OpenCV grabCut_0
Interactive foreground cutout, before SAM existed
- img
- mask
- bgdModel
- fgdModel
- nparray_0
- nparray_1
- nparray_2
grabCut_0 is the pack's heavyweight: a real, working foreground-segmentation algorithm - graph cuts - that separates a subject from its background using color and contrast. No model weights, no API, no learned segmentation. Just a rectangle you provide and an optimization loop that decides which pixels are foreground. If you've ever wanted a mask of "the thing in this box," grabCut is the classical answer to exactly that question.
And then there's the catch: in the image-gen ecosystem, the ecosystem has moved on. Detailing pipelines reach for SAM or segmentation detectors, which is the "polygon mask, fewer seams" world described in the masking-detection-detailing docs. grabCut is the 2010s tool - model-free and interactive, but cranky and old-school. That makes this node an honest mixed bag: a faithful port of a genuinely clever algorithm, wrapped in a way that makes it near-unusable inside a pure ComfyUI graph.
How the algorithm works
GrabCut frames the image as a graph: pixels are nodes, edges encode color similarity between neighbors, and a min-cut partitions the graph so that "background-ish" pixels separate from "foreground-ish" pixels. It estimates color distributions (Gaussian mixtures) for both regions, then iterates: refine the distributions, re-cut, repeat for iterCount times. It's unsupervised in a useful way - it just needs a seed.
The inputs, and the problem
- img (
NPARRAY): your BGR image fromImage2Nparray. - rect (
STRING): the seed rectangle as a Python literal,(x, y, width, height), used whenmodeis0. This is the "put a box around the subject" step. - mode (
INT):0= GC_INIT_WITH_RECT (start from the box),1= GC_INIT_WITH_MASK (start from a mask you supply),2= GC_EVAL,3= GC_EVAL_FREEZE_MODEL (continue iterations on later runs). - iterCount (
INT): optimization iterations;5is the standard starting point, more for messy edges. - mask, bgdModel, fgdModel (all
NPARRAY): here's the trap. In OpenCV, these are out-parameters - the function mutates them in place and returns them. This pack exposes them as required inputs because the auto-generator couldn't tell out-params from inputs. To start, you needmask= a zeros array the same size as the image, andbgdModel/fgdModel= emptyfloat64arrays of shape(1, 65).
And here's the deeper problem: this pack has no node that creates a zeros or empty array. np.zeros isn't a cv2 function, so the generator never wrapped one. With this pack alone you cannot fabricate the seed arrays grabCut demands. You'd need an array-creation node from another pack (or custom code) to even run it - then the three outputs (segmented mask, plus the two models) feed back into subsequent GC_EVAL runs.
What the output mask means
The returned mask uses four values: 0 = definite background, 1 = definite foreground, 2 = probable background, 3 = probable foreground. To get a usable binary cutout, threshold it - keep mask == 1 for confident foreground, or mask >= 1 to include the "probable" halo. That array can then feed an inpaint or detailing pass, which is the only reason to fight through this node.
Install
Standard pack install:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
or ComfyUI Manager, search "opencv-comfyui", restart. Needs opencv-contrib-python; numpy/torch ship with ComfyUI. No models, no keys - which is genuinely grabCut's one advantage over SAM-style segmentation.
Honest verdict
If your goal is "cut out a subject," SAM nodes are faster, more accurate, and friendlier. GrabCut's strengths are that it needs no downloaded model and runs on anything. Its weakness here is that the pack's wrapping - out-params as required inputs with no array factory - turns a one-line Python function into an exercise in graph plumbing. Know that going in: this is the node in the pack where the author's "Expect dragons" warning is most deserved. If you have an array-creation node handy, it works; otherwise it's a trap you can admire from a distance.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| img | NPARRAY | — | |
| mask | NPARRAY | — | |
| rect | STRING | — | |
| bgdModel | NPARRAY | — | |
| fgdModel | NPARRAY | — | |
| iterCount | INT | — | |
| mode | INT | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| nparray_0 | NPARRAY | — |
| nparray_1 | NPARRAY | — |
| nparray_2 | NPARRAY | — |