Nodes/ComfyUI-BadmanNodes/Chroma Clean (Badman)
ComfyUI Node

Chroma Clean (Badman)

Despill and clean an AI matte against a known backdrop

By MariusKM·Created 2 years ago·Updated 3 months ago· 4
Chroma Clean (Badman)
  • image
  • alpha_mask
  • image
  • mask
  • chroma_mask
bg_color#00FE00
chroma_threshold28.0
chroma_feather12.0
despill_strength1.00
invert_input_maskfalse
invert_output_maskfalse

Background-removal models like BiRefNet and RMBG 2.0 are genuinely good these days - that's not really the debate anymore. What they're still not great at is the classic VFX greenscreen problem: a matte from a model gives you a foreground/background split, but it doesn't know or care that your backdrop was a specific known color, so it leaves color contamination behind. Backdrop light bounces onto the subject's edges (spill), and thin or semi-transparent bits of the subject let backdrop color leak through the alpha (fill-in). Chroma Clean is a real-VFX-technique node bolted onto an AI matte, purpose-built to fix exactly that.

What it's actually doing

Feed it your image, the alpha matte you already got from a segmentation model, and the hex color of the backdrop you shot or generated against - a greenscreen, a bluescreen, whatever known flat color was behind the subject. From there it does two distinct jobs. First, it refines the matte itself: anything close enough to bg_color in LAB color distance (within chroma_threshold) gets treated as backdrop and punched out of the alpha, with chroma_feather controlling how soft the ramp is above that threshold rather than a hard cutoff - this is the fix for the fill-in problem, where a segmentation model let a bit of backdrop color show through thin structures like hair or fabric edges. Second, it despills the RGB: despill_strength clamps the dominant backdrop channel (green, blue, whatever bg_color implies) down to the max of the other two channels, at a strength you control from 0 (off) to 1 (full clamp) - this is the fix for spill, the backdrop-colored fringe you get around edges even after the matte itself is clean.

You get three outputs back: the despilled image, the refined alpha, and the raw chroma-detection mask on its own - useful for tuning, since you can inspect exactly what the node decided counted as backdrop before trusting the final composite.

The inputs that matter

  • bg_color (string, default #00FE00) - hex of the backdrop you're removing. Green screen, blue screen, whatever you shot or generated against.
  • chroma_threshold (0–120, default 28) - LAB distance cutoff: closer than this to bg_color counts as backdrop.
  • chroma_feather (0.1–60, default 12) - width of the soft ramp above the threshold; higher is a softer, more gradual edge.
  • despill_strength (0–1, default 1) - how hard the dominant backdrop channel gets clamped.
  • invert_input_mask / invert_output_mask (booleans) - the two fields most likely to trip you up, and worth reading their own tooltips carefully. BiRefNet and RMBG output masks where 1 means foreground, so leave invert_input_mask off for those; a LoadImage node's alpha channel is the opposite convention, 1 means background, so turn it on for that case. invert_output_mask controls the convention of what you get back - off gives you 1 = foreground as usual, on flips it to 1 = background, which matters if you're chaining straight into this pack's Color Match node, since it expects masks in that inverted convention.

Installing it

ComfyUI Manager: search ComfyUI-BadmanNodes, install, restart. Manual: cd ComfyUI/custom_nodes && git clone https://github.com/MariusKM/ComfyUI-BadmanNodes. This node doesn't need the separate comfyui-rmbg pack - that's only a requirement for this pack's Tiled Background Removal node - Chroma Clean just needs a mask as input, and it doesn't care which model produced it.

Where people get burned

By far the most common mistake is skipping the mask-convention check above - running BiRefNet's output through with invert_input_mask on (or a LoadImage alpha through with it off) inverts your whole selection, and the result looks like total garbage in a way that's easy to misdiagnose as a bad chroma_threshold rather than a flipped boolean. Check that first. Second, this node assumes a genuinely flat, known backdrop color - it works on real chroma-key footage or on generated images where you deliberately put a flat color behind the subject; it's not a general-purpose spill remover for arbitrary photo backgrounds, since there's no single bg_color to key against there. And if your refined matte still shows a faint color fringe after a full despill pass, that's usually a chroma_threshold set too tight - widen it (and open chroma_feather alongside it) before assuming despill strength alone will fix an edge the matte itself didn't clean.

CategoryBadman/matte

Inputs (8)

NameTypeDefaultDescription
imageIMAGE
alpha_maskMASK
bg_colorSTRING#00FE00Hex of the backdrop color to remove (e.g. #00FE00 greenscreen, #0047AB bluescreen).
chroma_thresholdFLOAT28.00–120LAB distance: pixels closer than this to bg_color are treated as backdrop.
chroma_featherFLOAT12.00.1–60Width of the soft ramp above threshold. Higher = softer edge.
despill_strengthFLOAT1.000–10 = off. 1 = clamp dominant bg channel to max of the other two.
invert_input_maskBOOLEANfalseBiRefNet/RMBG use 1=foreground (leave OFF). LoadImage alpha uses 1=background (turn ON).
invert_output_maskBOOLEANfalseOutput as 1=foreground (OFF) or 1=background (ON, for chaining into Color Match).

Outputs (3)

NameTypeDescription
imageIMAGE
maskMASK
chroma_maskMASK