Nodes/Castcut nodes/Castcut Mask Repair
ComfyUI Node

Castcut Mask Repair

Filling the holes your matte left behind

By doodersrage·Created 21 days ago·Updated 14 days ago· 2
Castcut Mask Repair
  • image
  • mask
  • source_mask
  • composite
  • mask
  • report_json
◄fill#ffffff►
◄regrow_edgesfalse►

Background removal is the most commoditized operation in this ecosystem and still the least settled - the models got good at finding the subject and nobody has solved hair, fur and semi-transparency. But there's a second, dumber failure that shows up constantly and gets blamed on the model: holes. The gap between an arm and the torso, the space under a bent knee, a dark patch that looked like background. BiRefNet punches a hole in the middle of your subject and you only notice on the white plate.

Castcut Mask Repair is a fix for exactly that. It reads the photo's own colours to figure out what the background actually was, then decides which "background" pixels are really background.

How the repair works

Feed it the photo and the matte. It runs two passes, and the split is the thing to understand:

  1. Enclosed holes get filled - always. It labels connected background regions and finds the ones that don't touch the image border: those are islands inside your subject. Then it checks their colour against the photo's actual backdrop. If a hole isn't backdrop-coloured, it was occluded subject - a gap between limbs, the shade under a chin - and it's set to solid. That runs regardless of any widget you set.
  2. Edge regrowth - only when you ask, and only when it can tell. The backdrop colour is estimated as the per-channel median of "sure background" pixels (very low alpha, connected to the border). If at least 80% of those pixels sit within a tight colour distance of that median, the node calls the backdrop plain - a studio white or a flat plate. Only then, and only with regrow_edges on, does it walk outward from the subject and restore person-coloured pixels that were wrongly cut. On a busy or gradient background it simply doesn't trust itself and does nothing.

A final 3-pixel cleanup pass firms up the rim where the repair created new solid area. Everything is deterministic numpy - no model, no VRAM, no second round trip through a segmentation network.

Inputs and outputs

  • image - the original photo, not the cutout.
  • mask - the matte. High value = subject. If yours is inverted you'll get a nonsense composite and no error, so check it.
  • fill - #rrggbb, default #ffffff. Three-digit shorthand works (#fff); anything else raises Castcut fill must be #rrggbb.
  • regrow_edges - off by default. Turn it on for studio-white plates and flat backdrops; leave it off for anything else.
  • source_mask (optional) - LoadImage's MASK, where 1 = transparent. That's the opposite polarity to mask, deliberately: wire it in when your input PNG already has real alpha and you want that transparency preserved rather than invented.

Outputs: composite (the photo's original pixels composited through the repaired mask onto fill, RGBA in, RGB out), mask (the repaired matte, if you want a second stage downstream instead of the composite), and report_json with filledHolePixels, regrownPixels, backdrop, plainBackdrop, subjectShare and looksIsolated. That last one is the honest self-check: if filledHolePixels is zero on an image you know had holes, the matte is the wrong polarity or the wrong size.

Masks that don't match the image dimensions get resized to fit (cv2 if it's there, nearest-sample if not), so a mismatched matte won't crash it - it'll just be mushier.

Installing it

Same pack as the rest of Castcut's nodes - Manager → search Castcut nodes, or comfy node install castcut-nodes, or drop the single file in and restart:

git clone https://github.com/doodersrage/castcut-nodes
cp castcut-nodes/castcut_nodes.py /path/to/ComfyUI/custom_nodes/
# restart ComfyUI

numpy and pillow, both already in ComfyUI. No model downloads, no BiRefNet requirement - it's pure post-processing on a matte you got from anywhere. Note the author's warning to install it one way only: a castcut_nodes.py file and a castcut folder sitting side by side both load, and you'll get duplicate node registration.

Where people get burned

  • The mask is inverted. Most background-removal nodes in ComfyUI emit subject-as-1, but plenty of custom ones don't. If the composite is a white silhouette on a photo-shaped hole, invert before blaming the repair.
  • Flat-background results only. regrow_edges doing nothing on a gradient or a real-world photo isn't a bug; the plain-backdrop check refused. Test on the studio plates where it applies.
  • This cannot fix what the model never saw. If the segmentation ate a chunk of hair, there is no alpha signal to recover - the holes pass only restores regions that were enclosed, and the regrow pass only restores pixels that are both person-coloured and touching the subject. For genuinely translucent material you need a matting checkpoint (BiRefNet-matting), not a repair pass. That's a model problem; this node is an output-hygiene problem.
CategoryCastcut

Inputs (5)

NameTypeDefaultDescription
imageIMAGE—
maskMASK—
fillSTRING#ffffff—
regrow_edgesBOOLEANfalse—
source_maskoptMASK—

Outputs (3)

NameTypeDescription
compositeIMAGE—
maskMASK—
report_jsonSTRING—