Nodes/ComfyUI CV/CV GrabCut
ComfyUI Node

CV GrabCut

Cut a subject out with a hint and no model download

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
CV GrabCut
  • image
  • points
  • mask
  • sure_foreground
  • sure_background
  • mask
  • labels
  • success
◄iterations5►

GrabCut has been in OpenCV since 2004 and it still does a job the neural segmenters can't: it runs instantly, needs no download, and produces a mask you understand completely. Give it a rough hint - a rectangle around the object, a squiggle inside it, or a scribble on what must stay - and it separates foreground from background using colour statistics instead of a network.

The honest framing first, because the KB has a whole document on this turf: if you want the best edges on hair, fur and glass, you want BiRefNet or InSPyReNet or SAM, and there's a three-model workflow at the top of that pile for a reason. GrabCut is the tool for one well-separated object against a distinguishable background, on CPU, with no 4 GB of weights and no Triton. It's also the one you reach for when you want a mask seeded from your own clicks rather than from a text prompt.

How it works

The mechanism is a graph cut over colour models. The node builds a label map and hands it to cv2.grabCut, which fits Gaussian mixtures for foreground and background from the seeds, then finds the pixel labelling that minimizes an energy balancing colour fit against boundary smoothness, iterating a few times (iterations, default 5 - that's plenty).

The hints are combinable, and each means something specific:

  • points - two or more points (Nx1x2 or Nx2) whose bounding rectangle contains the object. Everything outside that rectangle is marked sure background. This is the classic rect-initialisation and the fastest way to get a useful mask.
  • mask - non-zero pixels are marked probable foreground; the rest stays probable background unless points also marked a rectangle. The polygon output of CV Annotate Points plugs straight in.
  • sure_foreground / sure_background - scribbles that pin pixels. Non-zero foreground pixels are forced to stay foreground; non-zero background pixels are forced to stay background. This is where you fix the one region GrabCut keeps getting wrong, without repainting everything.

Note the semantics people misread: mask is probable foreground, not a hard constraint. If something in your mask keeps vanishing, that's why - move it to sure_foreground.

Outputs

  • mask - uint8 0/255, sure plus probable foreground. Ready for a cv2_bitwise_and cutout, a core mask node, or an inpainting workflow - the compose-and-inpaint path the KB describes for masks feeding a re-render.
  • labels - the raw 4-value GC map: 0 sure background, 1 sure foreground, 2 probable background, 3 probable foreground. View it with Preview CV Array in heatmap mode, and you can see exactly which pixels the algorithm was unsure about, which is a much better debugging signal than staring at the binary mask.
  • success - a boolean, and the failure contract.

No usable hints, or everything ends up as background, gives success = false with an empty mask instead of an exception. Branch on it. In a per-frame loop that's the difference between one bad frame and a dead queue.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"

Or find ComfyUI CV in ComfyUI Manager. Python ≥ 3.12 and a V3-API ComfyUI. The pack's workflows/21_grabcut.json is worth opening even if you never run it: it builds the same photo two ways - rectangle-from-points and polygon-as-probable-foreground - and previews the cutout, the mask and the label heatmap for each. Comparing those four previews teaches the seeding semantics faster than any write-up.

Common issues

The object bleeds into the background. Background colours that overlap the object's colours. Add sure_background scribbles on the offending region; that's a hard constraint the energy minimisation has to respect.

Anything with hair, fur or transparency comes out ragged. Expected, and the reason those neural models exist. GrabCut is a segmentation, not a matting, algorithm - it labels pixels rather than predicting fractional alpha. Use it for the solid-object case.

success = false on a photo where a rectangle clearly marks the thing. Check the points are in the right coordinate space and that the rectangle isn't effectively the whole frame - a rect that covers everything gives the label map nothing but probable foreground, and the node treats that as no usable hint.

It's slow on a big image. iterations is the dial, and 5 is already generous; the colour-model fitting is per-run, not per-iteration, so going to 3 barely changes the result. Downscaling, masking at a workable resolution and scaling the mask back up is the usual escape.

Categoryimage/CV/segmentation

Inputs (6)

NameTypeDefaultDescription
imageNPARRAY,IMAGEColor image (BGR uint8); grabCut needs 3 channels - grayscale is converted. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
iterationsINT51–50GrabCut refinement iterations; 5 is usually plenty.
pointsoptNPARRAY2+ points whose bounding rectangle contains the object (Nx1x2 or Nx2). Everything outside the rectangle becomes sure background.
maskoptNPARRAY,MASKMask; non-zero = probable FOREGROUND (the rest stays probable background unless 'points' also marks a rectangle). The polygon mask of 'CV Annotate Points' plugs in directly. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
sure_foregroundoptNPARRAY,MASKScribble mask; non-zero pixels are forced to stay foreground. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
sure_backgroundoptNPARRAY,MASKScribble mask; non-zero pixels are forced to stay background. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.

Outputs (3)

NameTypeDescription
maskNPARRAYuint8 0/255 foreground mask (sure + probable foreground).
labelsNPARRAYRaw GC label map: 0 sure BG, 1 sure FG, 2 probable BG, 3 probable FG - view with 'Preview CV Array' (heatmap).
successBOOLEAN—