OpenCV connectedComponents_0
Count the blobs in your mask (OpenCV connectedComponents_0)
- image
- labels
- int
- nparray
Every mask eventually asks the question: how many actual objects are in here? You've thresholded a denoised image and you have a sea of white pixels - but is that one connected blob, or forty little speckles that happen to touch? connectedComponents_0 answers it. It's the OpenCV function cv2.connectedComponents, wrapped for ComfyUI, and it labels every connected region of your mask with its own ID. The classic mask-cleanup tool.
What it does
Feed it a binary, 8-bit single-channel image (white = foreground). It walks the image and assigns an integer label to every group of nonzero pixels that touch each other - same label for pixels in the same blob, a fresh label for the next blob. Label 0 is always the background. The two things it gives you:
- A count - how many connected components exist (including the background label, so a mask with one blob reports
2). - A label map - the same-sized image where every pixel holds its component's ID.
That's segmentation's most primitive form, and it's genuinely useful: counting objects in a mask, deciding whether a mask is "one thing or many," and - combined with the stats variant - filtering junk by size.
The inputs and outputs
- image (NPARRAY) - the binary mask. Needs to be 8-bit single-channel (
CV_8UC1). Convert a Comfy image withImage2Nparray, thencvtColorwithcode=6(BGR2GRAY) - the README's(-215:Assertion failed) img.type() == CV_8UC1is exactly what you get if you skip that. - connectivity (INT) -
4(pixels touch only at edges) or8(corners count too).8is the usual default and tends to match human intuition about "connected." - ltype (INT) - the label array's dtype:
4(CV_32S) or2(CV_16U). Use4unless you're memory-starved;2caps you at 65535 labels. - labels (NPARRAY, optional) - out-parameter; the README says skip the out-params and it's right.
- Outputs:
int(label count) andnparray(the label map).
Wiring it into a workflow
This is the node to reach for after masking-detection-detailing machinery gives you a rough mask - the "you can get that mask in SO many ways" crowd lands here when they want the mask to mean something. Count blobs and branch on the int, or pipe the label map onward. One honest caveat: label values aren't 0–255 pixel intensities, so shoving the label map straight into Nparrays2Image gives you a noisy-looking mess. It's data, not a picture - render it by normalizing, or just use the count. For per-blob sizes (so you can drop the speckles), step up to connectedComponentsWithStats_0; this node gives you the count, that one gives you the sizes too.
Install
Same pack as every OpenCV node here: ComfyUI Manager (search "opencv-comfyui") or
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
Requires opencv-python-contrib (requirements.txt: opencv-contrib-python, numpy, torch). Watch the guidedFilter import conflict if you have competing OpenCV installs, and remember Image2Nparray only handles batch size 1 - split with ImageFromBatch (length=1) if you get the batch-size error. Grayscale input, sane connectivity, and this node turns your noisy mask into a number you can actually branch on.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | NPARRAY | — | |
| connectivity | INT | — | |
| ltype | INT | — | |
| labelsopt | NPARRAY | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| int | INT | — |
| nparray | NPARRAY | — |