CV Detect Blobs
The shape filters that threshold + findContours can't give you
- image
- keypoints
- points
- sizes
- responses
- count
CV Detect Blobs finds compact bright-or-dark spots - cells, dots, holes, bubbles, fiducials, poker chips - and filters them by shape.
That last part is the whole reason to use it. You can absolutely write "threshold, findContours, circle-fit" by hand, and then you'll spend an afternoon reimplementing area, circularity, convexity and inertia ratio filters. cv2.SimpleBlobDetector has all four built in, and they're what let you say "count the round things between 25 and 5000 pixels and ignore everything else" in one node.
It's a cv2 class rather than a function, so there's no raw wrapper - that's why it's hand-written. And note the honest limit: it produces no descriptors. If you need to match the blobs across frames, run CV Compute Descriptors on the keypoints it emits.
How it works
It thresholds the image at many levels between min_threshold and max_threshold in threshold_step increments and keeps the connected regions that stay stable across consecutive levels - that run of stability is min_repeatability (default 2, meaning a blob has to show up at the next threshold too). Then the shape filters cull what's left. That multi-threshold sweep is why it's robust to uneven lighting in a way a single cv2.threshold never is: a blob doesn't have to be brighter than one magic number, it has to survive a range.
The inputs that matter
Required:
image- an IMAGE, MASK or NPARRAY; grayscaled internally.blob_color- dark blobs on a light background or the reverse. Read the tooltip and believe it: this is the first thing to flip whencountis 0, and it's the mistake everyone makes once.min_area/max_areain pixels. Notemax_area = 0means no upper limit, not "no blobs".min_circularity,min_convexity,min_inertia- each 0–1, each disabled at 0, which is the default. Circularity of 1.0 is a perfect circle, ~0.79 a square. Convexity is area over hull area, so crescents score low. Inertia ratio is short axis over long axis, so a thin streak scores near 0.
Optional, and the ones you'll actually tune when the defaults find nothing:
min_threshold/max_threshold/threshold_step- the sweep. A smaller step is more thorough and slower.min_repeatability- how many consecutive thresholds a blob must survive.min_distance- blobs closer than this get merged.
Outputs: keypoints (for CV Draw Keypoints or CV Compute Descriptors), points (Nx2 centres, for k-means, polar conversion, anything point-based), sizes (keypoint diameter), responses (detector strength - threshold it if you want only the strong ones), and count. Zero is a valid result, not an error.
Install
From comfyui_cv (bmad4ever/comfyui_cv). In ComfyUI Manager search "ComfyUI CV", or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
# then restart ComfyUI
Dependency, pinned:
pip install "opencv-contrib-python-headless~=5.0.0.93"
Python ≥ 3.12 and a V3-API ComfyUI. This one lives in the base cv2 API rather than a contrib module, but the contrib wheel is still the required install - mixing in a plain opencv-python wheel clobbers all four distributions' shared site-packages/cv2 and takes the contrib nodes with it. tools/repair_opencv_contrib.py --check / --apply is the repair.
Common issues
- Count is 0 and it should not be. Flip
blob_colorfirst, then widen the threshold range, then dropmin_repeatabilityto 1. In that order - it's almost always polarity. - Thousands of one-pixel specks. Raise
min_areafrom its default 25, and raisethreshold_stepso the sweep is less jumpy. - It finds one blob where you see five.
min_distanceis merging them. - It finds blobs and also long smears. That's what
min_inertiais for. Set it to ~0.5 and watch the streaks disappear. - It's slow. The sweep is
(max - min) / stepfull-image threshold passes. On a 4K frame, narrow the range before you narrow the step.
If your targets are text-like rather than round - signs, letters, print at an angle - CV Detect MSER Regions is the better tool: MSER sweeps thresholds too but keeps stable regions regardless of shape, which is exactly what letters are.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| image | NPARRAY,IMAGE | Image to search (converted to grayscale internally). 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. | |
| blob_color | COMBO | dark blobs on a light background | Polarity of the blobs. Pick the wrong one and the detector returns nothing - this is the first thing to flip when count is 0. |
| min_area | FLOAT | 250–10000000 | Smallest blob area in PIXELS. 0 disables the lower bound. Raise it to ignore speckle noise. |
| max_area | FLOAT | 50000–10000000 | Largest blob area in pixels. 0 means NO upper limit (the area filter is then one-sided). |
| min_circularity | FLOAT | 0.000–1 | Minimum 4*pi*area / perimeter^2: 1.0 is a perfect circle, ~0.79 a square. 0 disables the filter. |
| min_convexity | FLOAT | 0.000–1 | Minimum area / convex-hull area: 1.0 is fully convex, lower values allow dents and crescents. 0 disables the filter. |
| min_inertia | FLOAT | 0.000–1 | Minimum inertia ratio (short axis / long axis): 1.0 is a circle, near 0 is a thin streak. 0 disables the filter - raise it to reject elongated smears. |
| min_thresholdopt | FLOAT | 500–255 | First grayscale threshold of the sweep. |
| max_thresholdopt | FLOAT | 2200–255 | Last grayscale threshold of the sweep. |
| threshold_stepopt | FLOAT | 101–128 | Step between successive thresholds; smaller is more thorough and slower. |
| min_repeatabilityopt | INT | 21–100 | A blob must appear at this many consecutive thresholds to be reported - the stability test. |
| min_distanceopt | FLOAT | 100–10000 | Blobs closer together than this (pixels) are merged into one. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| keypoints | CV_KEYPOINTS | cv2.KeyPoint list - draw with 'CV Draw Keypoints', or give them descriptors with 'CV Compute Descriptors' to feed 'CV Match Features'. |
| points | NPARRAY | Nx2 float32 (x, y) centres - the point-set form for 'OpenCV Draw Points', k-means, polar conversion, ... |
| sizes | NPARRAY | (N,) float32 keypoint diameter in pixels. |
| responses | NPARRAY | (N,) float32 detector strength per keypoint - threshold it to keep only the strong ones. |
| count | INT | How many were found; 0 is a valid result, not an error. |