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

cv2.ellipse (1/2)

Circles are just a special case, and half-axes will bite you

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
cv2.ellipse (1/2)
  • source
  • center
  • axes
  • result
◄angle0.0000►
◄startAngle0.0000►
◄endAngle0.0000►
◄color(0, 0, 0, 0)►
◄thickness1►
◄lineTypeLINE_AA►
◄shift0►

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_AA white ellipse at thickness 2 over a photograph reads as part of the image; thickness 1 at LINE_8 reads 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.

Categoryimage/CV/low-level/cv2 E

Inputs (10)

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.
centerCV_TUPLE0,0Center 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.
axesCV_TUPLE0,0Half 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.
angleFLOAT0.0000-1e+38–1e+38Ellipse rotation angle in degrees.
startAngleFLOAT0.0000-1e+38–1e+38Starting angle of the elliptic arc in degrees.
endAngleFLOAT0.0000-1e+38–1e+38Ending angle of the elliptic arc in degrees.
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
shiftoptINT0-2147483648–2147483647Number of fractional bits in the coordinates of the center and values of axes. Preset to the OpenCV default (0).

Outputs (1)

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