Nodes/ComfyUI Timesaver Nodes/TS Matting (ViTMatte)
ComfyUI Node

TS Matting (ViTMatte)

From a sloppy SAM mask to real hair-level transparency

By AlexYez·Created 2 years ago·Updated about 21 hours ago· 12
TS Matting (ViTMatte)
  • image
  • mask
  • background_color
  • IMAGE
  • MASK
  • MASK_IMAGE
modelvitmatte-base-composition-1k
trimap_erode_px10
trimap_dilate_px20
max_resolution2048
auto_crop_by_masktrue
crop_padding_pct15
precisionauto
temporal_smoothmedian3
ema_alpha0.50
mask_blur0
mask_offset0
invert_outputfalse
backgroundAlpha

The name is a lie and that's a good thing - this node doesn't take a clean, hand-painted mask. You hand it a coarse one, the kind SAM3 Detect or SAM3 Video Track hands you (a hard binary blob, edges included), and it returns an actual photo-quality alpha matte with flyaway hair, fur, and semi-transparency preserved. That's the whole trick, and it's the difference between a cutout that looks fine in a preview and one that holds up over a coloured background.

Why matting instead of segmentation

A segmentation model labels each pixel foreground or background - structurally wrong for a veil, a wine glass, or a single hair. Matting predicts fractional alpha for every pixel. This node is built around Hugging Face's ViTMatte, which does exactly that job, and the brief is clear about where it fits: it's a drop-in upgrade for TS Remove Background when you already have a SAM3 mask and edges, hair or transparency actually matter.

The mechanism is easy to follow. ViTMatte wants a trimap - an image where you've marked "definitely foreground," "definitely background," and "unknown, please decide." This node builds that for you from your coarse mask: trimap_erode_px shrinks the mask to a confident foreground core, trimap_dilate_px expands an "unknown" band around it where the model does the real work. If your source mask is tight around hair or fur, bump trimap_dilate_px to 32+ so ViTMatte gets room to look. The model then predicts fractional alpha inside that band.

The inputs that actually matter

For a beginner, three things:

  • mask - your coarse mask. From SAM3 Detect, BiRefNet, a Mask Editor, anything. A single-frame mask is broadcast across the batch.
  • model - vitmatte-base-composition-1k is the default (~370 MB, best edge quality); small is ~96 MB and faster but lower detail.
  • trimap_dilate_px - the unknown band. Higher = more context for hair and fur.

The VRAM controls are worth knowing because ViTMatte uses global self-attention: on a 4K input that single attention matrix wants ~25 GB. max_resolution (default 2048) caps the long edge and upscales the alpha back afterwards; auto_crop_by_mask crops to the mask's bounding box first, which saves enormous amounts of VRAM and time when your subject is small in the frame. Leave both defaults on and you'll rarely think about them.

The output contract is the same as TS Remove Background: IMAGE (RGBA cutout, or composited on your chosen background colour), MASK (the refined alpha), and MASK_IMAGE (a grayscale preview). For video, temporal_smooth (median3 by default) kills the "boiling" edge flicker across frames.

Install

There's no special dependency - it's part of comfyui-timesaver, so ComfyUI Manager → search "Timesaver" → install, then restart. The ViTMatte weights auto-download into models/vitmatte/ on first use.

cd ComfyUI/custom_nodes
git clone https://github.com/AlexYez/comfyui-timesaver
cd comfyui-timesaver
python -m pip install -r requirements.txt

Where people get burned

  • "My cutout has hard edges again." You fed it a segmentation mask but expected matting output. If the model is small, try base - the edge quality is the advertised difference.
  • OOM on a big photo. That's max_resolution and auto_crop_by_mask doing the wrong job for you - set a lower cap or turn the crop on.
  • Boiling edges in video. That's what temporal_smooth exists for; if median3 isn't enough there's median5 or the causal ema_causal (no lag, but it can blur fast motion).

The honest expectation: this isn't magic for a genuinely semi-transparent subject like smoke - no matting model fully is. But for hair, fur, and glass edges from a SAM mask, it's the difference between a sloppy cut and a real one.

CategoryTS/Image/Cutout

Inputs (16)

NameTypeDefaultDescription
imageIMAGESource image batch [B, H, W, 3].
maskMASKCoarse binary or soft MASK [B, H, W] (e.g. from SAM3 Detect or SAM3 Video Track). A single-frame mask is broadcast across the image batch.
modelCOMBOvitmatte-base-composition-1kViTMatte variant. 'base' = ~370 MB (recommended for best edge quality), 'small' = ~96 MB (faster, lower detail). 'composition-1k' is the standard matting benchmark; 'distinctions-646' is more diverse.
trimap_erode_pxINT100–128Erosion radius for the confident foreground core. Higher = thinner certain-foreground, more soft edges (better for hair).
trimap_dilate_pxINT200–128Dilation radius for the unknown band beyond the mask. Higher = ViTMatte gets more context around the object (helps fly-away hair / fur). 20 is a good default; bump to 32+ if the source mask is tight around hair/fur.
max_resolutionoptINT20480–4096Long-edge cap (px) for ViTMatte inference. ViTMatte uses global self-attention in some ViT blocks; on 4K input that single attention matrix needs ~25 GB of VRAM. The frame is downscaled before inference and the resulting alpha is upscaled back to native size. 0 = use the native resolution (only safe for small images / lots of VRAM).
auto_crop_by_maskoptBOOLEANtrueCrop the frame to the mask's bounding box (plus padding) before running ViTMatte. Saves enormous amounts of VRAM and time when the object is small compared to the frame. Has no effect when the mask covers the whole frame.
crop_padding_pctoptINT150–100Padding around the mask bbox in percent of bbox size when ``auto_crop_by_mask`` is on. 15 = 15% context margin.
precisionoptCOMBOautoInference precision on CUDA. 'auto' picks bf16 on Ampere+ (more numerically robust, no fp16 inf/nan on extreme alpha) and fp16 elsewhere. Force 'fp32' for diagnostics. CPU always runs fp32.
temporal_smoothoptCOMBOmedian3Smooth alpha across frames to reduce 'boiling' edges in video. 'median3' (default) kills random 1-frame flicker with minimal overhead and is a no-op for single images. 'median5' for stronger flicker (2-frame lag at clip boundaries). 'ema_causal' is causal exponential averaging — no lag, but can blur fast motion. 'off' disables. Peak RAM grows by ~N*H*W*4 bytes during the pass.
ema_alphaoptFLOAT0.500–0.99Strength of the causal EMA when temporal_smooth = 'ema_causal'. Higher = more smoothing (lag for moving objects); lower = closer to raw per-frame alpha.
mask_bluroptINT00–64Final Gaussian blur on the alpha output (px).
mask_offsetoptINT0-20–20Shrink (-) / expand (+) the final alpha mask.
invert_outputoptBOOLEANfalseInvert the alpha output.
backgroundoptCOMBOAlphaOutput background mode.
background_coloroptCOLOR#ffffffSolid background colour when 'background' = 'Color'.

Outputs (3)

NameTypeDescription
IMAGEIMAGECutout image (RGBA or composited on the chosen background).
MASKMASKRefined alpha matte.
MASK_IMAGEIMAGEAlpha matte as a grayscale image for preview.