GrabCut Mask Refinement
Polish any rough mask until it snaps to the subject
- image
- mask
- image
- refined_mask
Sometimes you already have a mask - from RMBG, BiRefNet, a manual paint job - and it's close but wrong at the edges: bleeding into the background, eating into the subject, fuzzy around contours. GrabCut Mask Refinement exists for exactly that. You give it an IMAGE and a MASK, it uses the mask to define where the subject roughly is, then runs GrabCut to pull the boundary back onto the actual object edges using the color and contrast information in the source image. It's the classic GrabCut "refine a trimap" workflow, packaged as a node. This is the pack's honest use case for GrabCut: not segmenting from nothing, but fixing a mask that's 90% right.
Inputs that matter
grabcut_iterations(default 3) - how hard GrabCut works; more iterations, tighter convergenceedge_refinement(0-1) - boundary smoothing strengthedge_blur_amount(0-10) - Gaussian blur on the mask edge; 0 keeps it sharp, higher feathers itexpand_margin(default 10) - pixels to expand the mask boundary so GrabCut has room to workbbox_safety_marginandmin_bbox_size- keep the refinement region sensibleoutput_size(ORIGINAL or fixed presets;custom_width/custom_heightfor custom) andscaling_methodinvert_mask- swap foreground and background if your source mask is backwards
The README's edge_blur guidance is a decent starting point: 0.0 preserves sharp edges (pixel art), 0.5-1.5 feathers for natural photo edges, 2.0+ gives soft composite blending. With edge_blur_amount at 0 the blur path is skipped entirely, so there's no cost to leaving the knob where it is.
Two outputs: image and refined_mask. Feed refined_mask into whatever consumed the original - compositing, inpainting, a save node - and compare against the source mask to see what GrabCut actually fixed.
When it's worth it
The product-pipeline pattern, honestly: run a fast neural remover to get 90% of the mask, then snap the edges with this node. It's cheaper than re-running a heavier matting model, and it's the pack's answer when your cutout is almost there but not quite. Keep expectations calibrated - GrabCut works on color/contrast boundaries, so if the source image genuinely lacks an edge (subject and background are nearly the same tone), no amount of iteration finds one.
Install
It lives in the pack's GrabCut module, so the dependency rule from the auto node applies: ultralytics must be installed or the whole GrabCut group - this node included - won't load. Same pack install:
cd ComfyUI/custom_nodes
git clone https://github.com/Limbicnation/ComfyUI-TransparencyBackgroundRemover.git
cd ComfyUI-TransparencyBackgroundRemover
pip install -r requirements.txt
Or search "Transparency Background Remover" in ComfyUI Manager, restart, and it'll be under image/processing.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| grabcut_iterations | INT | 31–10 | Number of GrabCut refinement iterations |
| edge_refinement | FLOAT | 0.50–1 | Edge smoothing strength |
| edge_blur_amount | FLOAT | 0.00–10 | Amount of Gaussian blur to apply to mask edges (0=none, 10=maximum) |
| expand_margin | INT | 100–50 | Pixels to expand mask boundary for refinement |
| bbox_safety_margin | INT | 200–100 | Extra pixels beyond detected bounding box for safety |
| min_bbox_size | INT | 6432–256 | Minimum bounding box dimensions to prevent over-cropping |
| output_size | COMBO | ORIGINAL | Target output size for the refined image and mask |
| scaling_method | COMBO | NEAREST | Interpolation method for scaling |
| custom_widthopt | INT | 51264–4096 | Custom width (used when output_size is 'custom') |
| custom_heightopt | INT | 51264–4096 | Custom height (used when output_size is 'custom') |
| invert_maskopt | BOOLEAN | false | Invert the output mask (foreground becomes background and vice versa) |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| refined_mask | MASK | — |