Nodes/ComfyUI CV/cv2.ellipse (2/2)
ComfyUI Node

cv2.ellipse (2/2)

The fitEllipse shortcut nobody notices

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
cv2.ellipse (2/2)
  • source
  • box
  • result
◄color(0, 0, 0, 0)►
◄thickness1►
◄lineTypeLINE_AA►

This is the second cv2.ellipse overload, and it's the one that makes the first one feel like homework. Instead of a centre, two half-axes, an angle and a pair of arc angles, it takes a single rotated rectangle and draws the ellipse inscribed in it. fitEllipse, minAreaRect and CamShift all return exactly that structure in OpenCV - so this node lets you wire a detector's output straight into the draw call with no unpacking, no half-versus-full axis confusion, and no risk of transposing the angle.

That's the whole reason to prefer it: fewer numbers on the wire means fewer numbers to get wrong.

How the input arrives

box accepts two things, and the tooltip lists them both:

  • A CV_ROTATED_RECT link - the socket type cv2.fitEllipse, cv2.minAreaRect and cv2.CamShift emit in this pack. Wire it directly. This is the good path.
  • A literal you type: ((cx, cy), (w, h), angle_in_degrees) - centre tuple, size tuple, rotation. The flat spelling (cx, cy, w, h, angle) is accepted too, which is a mercy when you're copying numbers out of a debug print.

Note the sizes here are full width and height, not half-axes as in (1/2). Same shape, opposite convention, and switching between the two nodes without noticing is the standard way to get an ellipse that's wrong by a factor of two. Since RotatedRect is what fitEllipse hands you and fitEllipse works in full sizes, this node is the one that matches the data you already have.

The rest is familiar: source (IMAGE, MASK or NPARRAY, echoed back as result), color as a BGR Scalar literal defaulting to invisible black, thickness defaulting to 1 with negative values filling the shape, and lineType defaulting to anti-aliased LINE_AA.

What you don't get is arc angles. This overload always draws a closed, complete ellipse - if you want a partial arc, that's (1/2).

The workflow it's built for

Detection to annotation in three nodes: contours or keypoints → cv2.fitEllipse → this node. That's the standard "show me the shape the detector found" overlay, and it's how you check whether a segmentation mask, a contour or a blob is shaped the way you assume. The same chain with minAreaRect gives you the minimum-area bounding box of the same points - as a RotatedRect - so the two fit results are interchangeable as inputs here, which is handy when you're deciding which one describes your object better.

For pose-adjacent work there's a neat consequence: a rotated rect is a pose in 2D. Once you have its centre and angle, you can drive a crop, a rotation or an inpainting region off it, and this node is the quick way to see the rectangle you're about to act on before you act on it.

Installing comfyui_cv

Part of bmad4ever/comfyui_cv - roughly 470 auto-generated raw cv2.* wrappers plus curated nodes, a GPL-3.0 fork of Gerold Meisinger's opencv-comfyui. Manager: search ComfyUI CV. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv

Restart afterwards. Python ≥ 3.12 and a recent ComfyUI on the V3 node API; the only dependency is opencv-contrib-python-headless~=5.0.0.93. Install the contrib build specifically - all four OpenCV distributions write into one site-packages/cv2 and the last one installed wins, so a plain opencv-python silently strips the contrib submodules and their nodes (tools/repair_opencv_contrib.py --check / --apply).

Common issues

The ellipse doesn't sit on the object. Your literal's angle convention is off - OpenCV measures RotatedRect angles in degrees with y pointing down, and the sign flips people around. Wire the RotatedRect in directly and the question disappears.

Ellipse twice the expected size. You typed the literal from (1/2) numbers, which are half-axes. This overload wants full sizes.

Nothing appears. Black default colour, or a box outside the frame. Also check source: drawing on a MASK gives you a single-channel result, which looks very different from drawing on an IMAGE.

You wanted a partial arc or a pie slice. Wrong node - cv2.ellipse (1/2) has startAngle and endAngle, and a negative thickness fills the sector.

A shape that jitters frame to frame. fitEllipse needs five or more points and is sensitive to contour noise; smooth the contour first, or fall back to minAreaRect, which is more stable and often the more honest annotation.

Categoryimage/CV/low-level/cv2 E

Inputs (5)

NameTypeDefaultDescription
sourceCOMFY_MATCHTYPE_V3 The image output(s) echo this input's format. 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.
boxCV_ROTATED_RECT,STRINGAlternative ellipse representation via RotatedRect. This means that the function draws an ellipse inscribed in the rotated rectangle. A rotated rectangle: ((center_x, center_y), (width, height), angle in degrees). Wire it from cv2.fitEllipse / cv2.minAreaRect / cv2.CamShift, or type the literal (the flat (cx, cy, w, h, angle) spelling is accepted too).
colorSTRING(0, 0, 0, 0)Ellipse color. cv2 Scalar as a literal, e.g. "(0, 255, 0)" (BGR) or "(0, 255, 0, 64)" (BGRA). A bare number broadcasts to every component, so "255" means (255, 255, 255, 255). Components past the target's channel count are ignored by OpenCV.
thicknessoptINT1-2147483648–2147483647Thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn. Preset to the OpenCV default (1).
lineTypeoptCOMBOLINE_AAType of the ellipse boundary. See #LineTypes

Outputs (1)

NameTypeDescription
resultCOMFY_MATCHTYPE_V3Echoes the 'source' input's format: an IMAGE link comes back as IMAGE, MASK as MASK, NPARRAY stays NPARRAY.