Nodes/ComfyUI_Circle_Detection/πŸ”¬ Ellipse Detection (Simple)
ComfyUI Node

πŸ”¬ Ellipse Detection (Simple)

For the Circles Hough Can't Catch β€” Ellipse Detection the Simple Way

By zentrocdotΒ·Created 2 years agoΒ·Updated 2 years agoΒ· 0
πŸ”¬ Ellipse Detection (Simple)
  • image
  • image_output
  • standard_mask
  • inverted_mask
β—„number_sections1β–Ί
β—„div0.50β–Ί
β—„eps0.01β–Ί
β—„contour_switchtrueβ–Ί
β—„color_tuple_ellipse(255, 0, 255)β–Ί
β—„thickness2β–Ί
β—„numberingtrueβ–Ί
β—„number_size1β–Ί
β—„exclude_circlesβ€”β–Ί

The Hough node in this pack is great at perfect circles and useless at everything else. The moment a wheel is viewed from an angle, or a porthole reads as a flattened oval, Hough comes back empty-handed - the author lists exactly this as a known open issue. This node is the companion that picks up the slack, and it works a completely different way: plain OpenCV contour analysis instead of the Hough transform. Same philosophy - pure math, no model weights, no GPU, deterministic results - but built to tolerate squashed circles.

How it works

The pipeline is short and readable: grayscale, then a median blur, then an Otsu binary threshold, then findContours walks the result. Each contour is simplified with approxPolyDP and screened by how close its area comes to the ellipse that would fit in its bounding box. Winners get drawn and filled into a mask. That "how close to a real ellipse" score is the heart of the node, and it's what makes the settings click.

The inputs that matter

  • div (default 0.5) - the acceptance threshold for that area ratio. A perfect ellipse scores close to 1.0, so a higher div means "only accept things that are basically perfect ellipses," and a lower one lets sloppier, more deformed shapes through. If an ellipse you want is being rejected, drag div down.
  • eps (default 0.01) - the approximation tolerance for approxPolyDP, as a fraction of the contour perimeter. Too small and contours stay jagged; too large and you lose the shape.
  • number_sections (default 1) - the minimum number of polygon sides a contour must approximate to before it's even considered. The default accepts everything, which is usually right.
  • contour_switch - draw the raw contour (on) or the angular polygon approximation (off). Leave it on for smooth ellipses; the polygon view is mainly a debugging aid.
  • exclude_circles (optional input) - same trick as the Hough node: run once, note the numbers drawn on the output, then pass a comma list like 1,4 to drop those on the next run. Deterministic math makes this reliable.

One thing worth knowing from the code: the masks here are solid-filled (via fillPoly), not just outlines. That's actually nicer for inpainting than the circle node's stroke-style masks - you get a clean filled region to set.

Outputs

  • image_output - the input with detected ellipses drawn in color_tuple_ellipse, numbered if you want.
  • standard_mask / inverted_mask - the two MASK tensors, filled white-on-black and its inverse. Wire either into a Set Mask node to target inpainting inside the shapes, or the inverse to target everything outside them.

That's it - three outputs, no colored preview mask, no terminal data string. Leaner than its sibling, which is fine for the job.

The one real gotcha

Because it leans on Otsu's threshold, the node works best when your ellipses are a clearly different brightness from the background. Otsu assumes a bimodal histogram - dark shapes on a light background, or the reverse. Give it a busy, low-contrast photo and the contour list fills with noise that the area-ratio filter has to chew through. This is a "detect shapes on a clean background" tool, not a magic semantic segmenter.

Installation

It ships in the same pack as the Hough node, so one install gets you both. No models, no extra dependencies - only cv2/PIL/torch that ComfyUI already has:

cd ComfyUI/custom_nodes
git clone https://github.com/zentrocdot/ComfyUI_Circle_Detection

or search "Circle Detection" in ComfyUI Manager, then restart. Nodes live under 🧬 Circle Detection Nodes. If nothing seems to match, check div and the contrast of your image before touching anything else - those two account for most "it found nothing" reports.

Category🧬 Circle Detection Nodes

Inputs (10)

NameTypeDefaultDescription
imageIMAGEβ€”
number_sectionsINT11–256β€”
divFLOAT0.500–10β€”
epsFLOAT0.010.01–10β€”
contour_switchBOOLEANtrueβ€”
color_tuple_ellipseSTRING(255, 0, 255)β€”
thicknessINT21–256β€”
numberingBOOLEANtrueβ€”
number_sizeINT11–256β€”
exclude_circlesoptSTRINGβ€”

Outputs (3)

NameTypeDescription
image_outputIMAGEβ€”
standard_maskMASKβ€”
inverted_maskMASKβ€”