cv2.ximgproc.findEllipses
Detect circles that aren't quite circles
- image
- nparray
cv2.findEllipses sits in a strange spot in OpenCV: it's one of the few ximgproc functions that is genuinely a detector rather than a filter, it takes a plain photo (grey or colour - no preprocessing required), and it hands back a small table of ellipses it believes are in the frame. Plates, coins, wheels, buttons, the rim of a cup seen at an angle, a knob on a machine: anything where a HoughCircles run would fail because the shape is squashed. That's the niche.
It's also the detector with the worst documentation-to-parameter ratio in the pack, so let's be concrete about what the three thresholds actually reject.
How it works
The algorithm works on arcs, not on whole outlines - it collects edge-supported curve segments, groups arcs that are consistent with a single ellipse, and then scores the resulting hypothesis by how much of its perimeter is actually backed by edges. That's why you don't threshold first, and why it copes with partial occlusion better than a Hough-style vote accumulator.
The node's output is a single NPARRAY. The parameter documentation (lifted from OpenCV) says each row is "x, y, a, b, radius, score" - that's six values described as "five float", an upstream typo that's been there for years. The pack's own tooltip reads it as center, axes, angle, score. Practical consequence: if your result has six columns, the last one is the score, and the pack's CV Draw Ellipses node wants exactly (cx, cy, semi_axis_a, semi_axis_b, angle_deg) - so slice the extra column off with CV Slice Array before drawing. Check the shape with Inspect CV Data first; it takes three seconds and saves a confusing preview.
Inputs
- image - the only required input. Grey or colour, straight from a Load Image or a crop. It accepts an IMAGE, MASK or NPARRAY, and takes frame 0 if you hand it a batch.
- scoreThreshold (0.7) - the minimum detection score. Lower it to 0.5 and you'll get more ellipses and more junk; this is the first knob you turn.
- reliabilityThreshold (0.5) - how much of the ellipse's arc must actually be supported by detected edges. Raise it when false positives cluster on textured backgrounds.
- centerDistanceThreshold (0.05) - how close two centers can be before the detections merge. On a grid of similar objects, raising this is how you collapse double detections of one real thing.
An empty result is normal, not an error. The pack's tooltip says so explicitly, which is more than OpenCV does.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
Restart ComfyUI, or grab ComfyUI CV from the Manager. Requires Python ≥3.12, a recent ComfyUI on the V3 node API, and opencv-contrib-python-headless~=5.0.0.93. findEllipses is a contrib function, so it only exists if your installed OpenCV is a contrib build - installing a plain opencv-python wheel over it silently removes these nodes from the menu. tools/repair_opencv_contrib.py --check reports that state.
Common issues
Nothing found on a clean photo of a circle. The detector is tuned for real-world ellipses with arcs of reasonable length; a small or heavily occluded shape can fall below reliabilityThreshold. Try 0.3 before you conclude it can't see the thing.
Duplicate ellipses on one object. Centers within centerDistanceThreshold (as a fraction of the image size, not pixels) merge - the default 0.05 is tight on a large frame.
It's not instant. There's no threshold pre-pass to cut the work down, so on a 4K frame expect seconds, not milliseconds. Crop to your region of interest first; the node is fed by exactly the frame you give it.
Treating it like a segmentation node. It returns parameters, not masks. Find the ellipse, then draw it (CV Draw Ellipses) or use the parameters downstream as geometry. For "give me the mask of the round thing", the pack's contour and component nodes (find contours, filter by shape, keep the largest component) are the right half of the toolbox - detectors produce numbers, not masks, and the pack is consistent about that split.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | NPARRAY,IMAGE,MASK | input image, could be gray or color. 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. | |
| scoreThresholdopt | FLOAT | 0.7000-1e+38–1e+38 | float, the threshold of ellipse score. Preset to the OpenCV default (0.7). |
| reliabilityThresholdopt | FLOAT | 0.5000-1e+38–1e+38 | float, the threshold of reliability. Preset to the OpenCV default (0.5). |
| centerDistanceThresholdopt | FLOAT | 0.0500-1e+38–1e+38 | float, the threshold of center distance. Preset to the OpenCV default (0.05). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |