Chroma Clean (Badman)
Despill and clean an AI matte against a known backdrop
- image
- alpha_mask
- image
- mask
- chroma_mask
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, default28) - LAB distance cutoff: closer than this tobg_colorcounts as backdrop.chroma_feather(0.1–60, default12) - width of the soft ramp above the threshold; higher is a softer, more gradual edge.despill_strength(0–1, default1) - 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 where1means foreground, so leaveinvert_input_maskoff for those; aLoadImagenode's alpha channel is the opposite convention,1means background, so turn it on for that case.invert_output_maskcontrols the convention of what you get back - off gives you1= foreground as usual, on flips it to1= 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.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| alpha_mask | MASK | — | |
| bg_color | STRING | #00FE00 | Hex of the backdrop color to remove (e.g. #00FE00 greenscreen, #0047AB bluescreen). |
| chroma_threshold | FLOAT | 28.00–120 | LAB distance: pixels closer than this to bg_color are treated as backdrop. |
| chroma_feather | FLOAT | 12.00.1–60 | Width of the soft ramp above threshold. Higher = softer edge. |
| despill_strength | FLOAT | 1.000–1 | 0 = off. 1 = clamp dominant bg channel to max of the other two. |
| invert_input_mask | BOOLEAN | false | BiRefNet/RMBG use 1=foreground (leave OFF). LoadImage alpha uses 1=background (turn ON). |
| invert_output_mask | BOOLEAN | false | Output as 1=foreground (OFF) or 1=background (ON, for chaining into Color Match). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| chroma_mask | MASK | — |