cv2.ellipse (2/2)
The fitEllipse shortcut nobody notices
- source
- box
- result
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_RECTlink - the socket typecv2.fitEllipse,cv2.minAreaRectandcv2.CamShiftemit 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.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| source | COMFY_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. | |
| box | CV_ROTATED_RECT,STRING | Alternative 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). | |
| color | STRING | (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. |
| thicknessopt | INT | 1-2147483648–2147483647 | Thickness 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). |
| lineTypeopt | COMBO | LINE_AA | Type of the ellipse boundary. See #LineTypes |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| result | COMFY_MATCHTYPE_V3 | Echoes the 'source' input's format: an IMAGE link comes back as IMAGE, MASK as MASK, NPARRAY stays NPARRAY. |