Nodes/ComfyUI-GiftHelperSuite/Gift Adaptive Matting | 自适应视频抠像
ComfyUI Node

Gift Adaptive Matting | 自适应视频抠像

MatAnyone2 With a Referee Watching Every Few Frames

By lingziwyh·Created 5 months ago·Updated a day ago· 7
Gift Adaptive Matting | 自适应视频抠像
  • images
  • check_masks
  • alpha
  • correction_report
check_indices
disagreement_threshold0.025
focus_ratio0.60
n_warmup10
max_internal_size1024
auto_downloadtrue

If you've wired MatAnyone into ComfyUI by hand you know the problem: it's excellent on hair and soft edges, and only ever as good as the mask you hand it on the first frame. Get that one mask slightly wrong and memory propagation carries the mistake through the clip. The community said as much within a week of release: it "works way better on their huggingface demo, so it's just clearly masking on the first frame problem to solve."

GiftAdaptiveMatting runs MatAnyone2 over a shot and hands it to a referee: sparse segmentation masks taken from frames inside the shot. Where the propagated mask and the fresh one disagree, it throws away the accumulated state and restarts from the fresh mask.

What it's solving

A matting model predicts fractional alpha and carries memory: stable, but it drifts, and it can only be as right as its guidance. The pack's chain runs split → check frames → segmenter (InSPyReNet or RMBG-2.0) → matte each shot, using those masks as periodic anchors. This node is the last link.

How it works

The node pulls MatAnyone2's own inference code out of the ComfyUI-MatAnyone pack - it doesn't ship a second copy - then, per shot:

  • Seeds the tracker with the check mask at frame 0 and warms it up by repeating that frame n_warmup times, so memory doesn't start from one cold frame.
  • Steps forward frame by frame, with max_mem_frames=5, long-term memory off, and max_internal_size capping the model's working resolution.
  • At every check index, scores disagreement between the propagated alpha and the fresh mask: both are area-downsampled to 192x256, only confidently opposite pixels count (a soft edge isn't an error), the mismatch map gets dilated a little, and the total is divided by the union area - so the score doesn't scale with subject size.
  • If that clears disagreement_threshold, it re-initializes from the fresh mask and runs a second tracker backwards over the frames since the previous check, blending the revised masks with a smoothstep that holds the left anchor steady. That's the reverse backfill, and it's why a correction doesn't land as a visible pop.

focus_ratio is the setting people misread: it restricts the disagreement check to the top of the frame. It does not crop your mask. At 1.0 the whole frame is watched.

Inputs and outputs

images is the frames of one shot, from GiftAutoShotSplit's shots output - not the whole video. check_masks is a batch of full-resolution masks, one per entry in check_indices, the JSON string from GiftMaskCheckFrames. Wire that string, don't retype it: the node checks that it starts at 0, increases, and stays inside the shot.

Then disagreement_threshold (0.025), focus_ratio (0.6), n_warmup (10) and max_internal_size (1024) - the author's tested defaults. Lower the threshold and you'll catch more drift and pay more, because every reset costs a warmup plus that backward pass. More correction is not the same as a better-looking matte.

Outputs are alpha - one mask per frame, ready for the compositing node's mask input in the shipped example - and correction_report, a JSON string with each check frame's disagreement score, whether it reset, reset_count, and elapsed time. Read it: it's the cheap way to know whether your threshold is doing anything.

Install

Manager, search ComfyUI-GiftHelperSuite, or:

cd ComfyUI/custom_nodes
git clone https://github.com/lingziwyh/ComfyUI-GiftHelperSuite.git

The pack ships no requirements.txt, and its own nodes need nothing beyond the PyTorch you already have. This node isn't self-contained, though: it needs ComfyUI-MatAnyone (2.1.4+, with MatAnyone2), ComfyUI-RMBG for the check masks, VideoHelperSuite to read the video, and KJNodes for MaskListToMaskBatch - all in the same Python that launches ComfyUI.

matanyone2.pth downloads on first execution from the official v1.0.0 release into ComfyUI/models/GiftHelperSuite/matanyone2.pth, SHA-256 pinned and published atomically, and it reuses an existing copy under models/MatAnyone2/, models/matanyone2/ or the MatAnyone plugin's checkpoint/. Off per node with auto_download, or globally with GIFT_HELPER_AUTO_DOWNLOAD=0.

Common issues

"requires FuouM/ComfyUI-MatAnyone with MatAnyone2 support." You have a MatAnyone wrapper, just not one that exposes the MatAnyone2 backend. Update it - the node fails loudly on purpose, since there's no sensible fallback.

"Model integrity check failed … The file was NOT overwritten." A stale or truncated matanyone2.pth, often from an older wrapper. The pack refuses to clobber it - move it aside and rerun.

"One full-resolution check mask is required for each check index." Your segmenter returned masks at a different resolution than the video, or the mask batch and index list drifted apart. Keep the segmenter at native size and let the masks pass through untouched.

It still flickers on the hard stuff. Transparent spheres, particles, complex architecture and subjects entering frame can be missed: the check-frame segmenter decides who counts as foreground, and MatAnyone2 won't invent a subject it never saw.

CategoryGiftHelperSuite/Video Matting

Inputs (8)

NameTypeDefaultDescription
imagesIMAGE
check_masksMASK
check_indicesSTRING
disagreement_thresholdFLOAT0.0250.001–1
focus_ratioFLOAT0.600.1–1
n_warmupINT101–30
max_internal_sizeINT1024256–4096
auto_downloadoptBOOLEANtrue

Outputs (2)

NameTypeDescription
alphaMASK
correction_reportSTRING