cv2.connectedComponentsWithAlgorithm
The same blobs, faster — if you can name the algorithm
- image
- int
- nparray
What it is, honestly
cv2.connectedComponentsWithAlgorithm labels the blobs in a binary mask exactly like cv2.connectedComponents - same labels, same numbering, same output shapes - but lets you pick the labelling algorithm instead of taking OpenCV's default. That's the entire difference. It's not a better node; it's the version you reach for when you have a reason to care which union-find implementation runs.
Things that give you a reason: a per-frame blob pass over a long clip where labelling time shows up in the total; a pathological image (one enormous component, or a mask of millions of tiny specks) where algorithm choice actually moves the needle; or just curiosity about why the choices exist. If you're labelling a single 1024px mask, use the plain node and don't think about it again.
It's a raw wrapper from ComfyUI CV (bmad4ever/comfyui_cv), category image/CV/low-level/cv2 C.
How it works
Like its sibling: every non-zero pixel is foreground, connected runs get merged into a label map, background is label 0. The choice here is the merge strategy - the classic two-pass union-find approach, versus newer scan-array-based variants and a couple of named algorithms out of the YACCLAB benchmark lineage (Bolelli's, Spaghetti, SAUF). They are exact labelling algorithms: same result, different speed characteristics on different image shapes. The one you'd want is a micro-benchmark question, not a correctness question.
The other half of the mechanism is the same gotcha as everywhere in this family: the input has to be a binary mask. Non-zero means foreground, so a greyscale photo becomes one component. Threshold first.
Inputs and outputs that matter
Note the shape of this node versus the plain one - this is where beginners lose time:
- image - required, 8-bit single-channel mask.
- connectivity - required INT, and it has no preset here: it reads 0. This is the difference from
cv2.connectedComponents, where connectivity is an optional input preset to 8. cv2 wants exactly4or8; a 0 is not a synonym for "the default", and you should expect an OpenCV assertion rather than a helpful message if you leave it. Type8(or4) before anything else. - ltype - required COMBO, default
CV_32S. OnlyCV_32SandCV_16Uare supported by OpenCV here. - ccltype - required COMBO, default
CCL_DEFAULT, withCCL_WU,CCL_GRANA,CCL_BOLELLI,CCL_SAUF,CCL_BBDT,CCL_SPAGHETTIalongside it.CCL_DEFAULTlets OpenCV pick, which is what you want unless you're benchmarking.
Outputs:
- int - the label count, background included, so N blobs report N+1.
- nparray - the label map, as data (not an image echo). Look at it with Preview CV Array (heatmap) and split it with CV Labels to Masks (full size).
For an applied job rather than a benchmarking one, the curated nodes are the shortcut: CV Connected Components (Split Mask), CV Keep Largest Component, CV Components Touching Border, CV Fill Holes, CV Select Component At Point. They exist precisely so you don't assemble the raw plumbing yourself.
Installing the pack
Manager → search ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
Restart. Requirements: Python ≥ 3.12 and a V3 node API ComfyUI. Dependency: opencv-contrib-python-headless~=5.0.0.93.
Worth knowing: the pack's registry is generated against whatever OpenCV build you have installed, and it can list functions your build doesn't actually implement. There's precedent in the README - one pinned entry always raised (-213) needs to be compiled with EIGEN. So a node existing in the menu is not proof that the function behind it works on your wheel.
Where people get burned
- connectivity = 0. The single most likely first failure in this node, and it's silent in the node itself. Set 4 or 8.
- Assuming the algorithm names change the output. They don't. If your labels are wrong, the algorithm is not the reason - check the threshold.
- Benchmarking on one image. The differences between these algorithms depend on blob size distribution and density. A single test image tells you nothing generalisable.
- The pack's record, since obscure nodes are where it matters. The README declares LLM-assisted development, a known case of test-driven overfitting (they name the Hu-moments bug), no planned updates, and "not recommended in production" without your own review. There's no Reddit corpus for the pack - a corpus search comes back empty - so an odd result here has no existing answer waiting for it. Start by verifying against a hand-checkable mask: three blobs drawn on a black canvas should give
int = 4.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | NPARRAY,IMAGE,MASK | - - - 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. | |
| connectivity | INT | 0-2147483648–2147483647 | - - - |
| ltype | COMBO | CV_32S | - - - |
| ccltype | COMBO | CCL_DEFAULT | - - - |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| int | INT | — |
| nparray | NPARRAY | — |