cv2.ellipse (1/2)
Circles are just a special case, and half-axes will bite you
- source
- center
- axes
- result
OpenCV has two ellipse functions with the same name and completely different signatures, so this pack ships them as two nodes - (1/2) and (2/2). This is the arc one: centre, half-axes, rotation, start angle, end angle. You feed it numbers, it draws.
Which is exactly when you want it - when you are authoring the shape rather than reproducing geometry that a detector handed you. Highlight rings, gauge arcs, a hand-placed ellipse over a region, a decorative ring around a face. For geometry that came out of fitEllipse or minAreaRect, use (2/2) instead; it takes their output directly and skips the coordinate juggling below.
The inputs, in the order they'll trip you up
source is the canvas - IMAGE, MASK or NPARRAY - and the result output echoes the format, so batch behaviour comes along for free.
center is a CV_TUPLE, (x, y), default (0, 0), i.e. the top-left corner. Typeable, or wireable from CV Tuple and its split components.
axes is the trap: half of the ellipse's main axes, not the full width and height. A 40-pixel-wide ellipse is axes = (20, h). It's also a CV_TUPLE of (width, height) components. Half is the convention throughout this function, and the fact that (2/2) uses full sizes instead is the reason people get a doubled shape when they switch between the two nodes.
angle is the rotation in degrees. startAngle and endAngle are the arc's extremes in degrees - 0 to 360 draws a closed ellipse; 0 to 90 draws a quarter arc. The angles are measured in OpenCV's screen coordinate system, which means y points down, so "clockwise on screen" is the positive direction. Sketching a sector and getting a mirrored arc is this convention, not a bug.
color is a Scalar literal in BGR, defaulting to "(0, 0, 0, 0)" - black. A bare number broadcasts, so "255" is white.
Then the three you mostly won't touch. thickness defaults to 1, and the tooltip gives you the good bit: a negative thickness fills the shape, so -1 draws a filled ellipse or a filled sector. lineType defaults to LINE_AA (anti-aliased - set LINE_8 if you want hard pixel edges). shift is the number of fractional bits in the centre and axis coordinates, OpenCV's fixed-point trick for subpixel geometry; you can leave it at 0 unless you know you want it.
Getting clean results
Two habits make drawings like this look intentional:
- Draw thick, anti-aliased, on a copy. A
LINE_AAwhite ellipse at thickness 2 over a photograph reads as part of the image; thickness 1 atLINE_8reads as a debug overlay. Decide which one you want. - Nothing is destroyed upstream. OpenCV's drawing functions modify the image in place, and the pack passes every array across the call boundary as a private copy, so the IMAGE feeding this node is still the one your earlier nodes cached. If you want the drawing kept, save or preview the output of this node, not the input.
For anything with more than a couple of shapes, the pack's curated drawing nodes are less work: CV Draw Polygon handles polylines, CV Overlay Masks colours up region batches, and the drawing wrappers there take literals too. This raw node is the one to use when you want an exact signature - an arc with a specific start and end angle, which the curated helpers don't do.
Installing comfyui_cv
One of ~470 auto-generated raw cv2.* wrappers in bmad4ever/comfyui_cv: GPL-3.0, forked from Gerold Meisinger's opencv-comfyui, curated against OpenCV 5.0.0.93, with a hand-written node layer alongside. Manager: search ComfyUI CV. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
Restart after. Python ≥ 3.12 and a recent ComfyUI (V3 node API); dependency, opencv-contrib-python-headless~=5.0.0.93. Keep the contrib wheel - the four OpenCV distributions share one site-packages/cv2 and the last one installed wins, so a later plain opencv-python silently removes the contrib nodes. tools/repair_opencv_contrib.py --check / --apply is the fix.
Common issues
The ellipse is twice the size you asked for. Half-axes. Halve your numbers, or move to (2/2) with full sizes.
Nothing drawn. Black default colour, or a centre outside the frame. Both look like "the node did nothing".
Filled when you wanted an outline (or vice versa). Sign of thickness. Positive is an outline, negative fills.
The arc is mirrored. Angles go the other way round because y increases downward. Negate, or swap start and end.
Inputs (10)
| 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. | |
| center | CV_TUPLE | 0,0 | Center of the ellipse. One value with 2 components (x, y) - it travels as a whole, so it cannot arrive half-connected. Wire it from 'CV Tuple' or type the components in place. |
| axes | CV_TUPLE | 0,0 | Half of the size of the ellipse main axes. One value with 2 components (w, h) - it travels as a whole, so it cannot arrive half-connected. Wire it from 'CV Tuple' or type the components in place. |
| angle | FLOAT | 0.0000-1e+38–1e+38 | Ellipse rotation angle in degrees. |
| startAngle | FLOAT | 0.0000-1e+38–1e+38 | Starting angle of the elliptic arc in degrees. |
| endAngle | FLOAT | 0.0000-1e+38–1e+38 | Ending angle of the elliptic arc in degrees. |
| 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 |
| shiftopt | INT | 0-2147483648–2147483647 | Number of fractional bits in the coordinates of the center and values of axes. Preset to the OpenCV default (0). |
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. |