Nodes/opencv-comfyui/OpenCV connectedComponentsWithStats_0
ComfyUI Node

OpenCV connectedComponentsWithStats_0

Per-blob sizes, boxes, and centroids (connectedComponentsWithStats_0)

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV connectedComponentsWithStats_0
  • image
  • labels
  • stats
  • centroids
  • int
  • nparray_1
  • nparray_2
  • nparray_3
connectivity
ltype

This is the one I'd actually reach for out of the whole connected-components family. Counting blobs (connectedComponents_0) is nice, but the question you usually want answered is "how big is each blob?" - because the tiny speckles in your mask are noise and the big one is your subject, and "drop everything under 500 pixels" is a sentence every mask-cleanup pipeline wants to be able to say. connectedComponentsWithStats_0 is that sentence. It labels every connected region and hands you each one's bounding box, area, and centroid.

What it does

It's cv2.connectedComponentsWithStats: the same labeling as plain connectedComponents, plus a stats matrix and a centroids matrix. For a mask with N components you get:

  • labels - a label map, every pixel holding its component's ID (0 = background).
  • stats - an N×5 matrix; columns are left, top, width, height, area (in pixels). Row i describes component i.
  • centroids - an N×2 matrix of (x, y) centers for each component.

Want to remove speckles? Filter the stats rows by area, keep components over your threshold, rebuild a mask from the surviving labels. That's a three-node pattern in a normal Python pipeline - here it's all upstream of whatever node does the filtering, but the data this node gives you is exactly the raw material.

The inputs and outputs

  • image (NPARRAY) - 8-bit single-channel binary mask. Convert with Image2Nparray, then cvtColor code=6 (BGR2GRAY). Feed it BGR and you'll see the README's (-215:Assertion failed) img.type() == CV_8UC1 in person.
  • connectivity (INT) - 4 or 8. 8 for normal use.
  • ltype (INT) - 4 (CV_32S) or 2 (CV_16U). Use 4.
  • labels / stats / centroids (NPARRAY, optional) - out-parameters. Per the README, skip them.
  • Outputs: int (component count), nparray_1 (labels), nparray_2 (stats), nparray_3 (centroids).

Note the order - count, labels, stats, centroids. It matches the function's return, and it's easy to wire the wrong wire if you're not looking.

Where it fits

This is mask post-processing, full stop - the tail end of the "you can get that mask in SO many ways" story from the masking/detailing world. Once a detector or a threshold has given you a rough mask, connectedComponentsWithStats_0 is how you turn it into structured facts: how many objects, where they are, which ones are too small to matter. It's also one of the few genuinely practical nodes in this pack, because OpenCV's contour functions (findContours, drawContours) are not generated here - so for blob analysis in this pack, this node is your workhorse, not an also-ran.

Install and gotchas

Same pack, same install: ComfyUI Manager (search "opencv-comfyui") or

cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui

Requires opencv-python-contrib. Pack-wide traps: the guidedFilter OpenCV conflict, and Image2Nparray's batch-size-1 limit (split with ImageFromBatch, length=1). And a reminder that the label map is data, not pixels - previewing it through Nparrays2Image gives you visual noise. Use the int and the stats to make decisions, not the label map.

Categoryimage/OpenCV

Inputs (6)

NameTypeDefaultDescription
imageNPARRAY
connectivityINT
ltypeINT
labelsoptNPARRAY
statsoptNPARRAY
centroidsoptNPARRAY

Outputs (4)

NameTypeDescription
intINT
nparray_1NPARRAY
nparray_2NPARRAY
nparray_3NPARRAY