Nodes/ComfyUI CV/cv2.minEnclosingConvexPolygon
ComfyUI Node

cv2.minEnclosingConvexPolygon

Fit exactly k corners around your points (OpenCV 5 only)

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
cv2.minEnclosingConvexPolygon
  • points
  • float
  • nparray
◄k0►

Fitting a shape to points usually means making a choice: the tightest box (upright or rotated), the tightest circle, or the exact convex hull with as many corners as the data happens to have. cv2.minEnclosingConvexPolygon is the "I want exactly this many corners" option. Hand it a point set and a k, and it returns the minimum-area convex polygon with k vertices that contains every point.

Four corners over a quadrilateral-ish blob, five over a pentagon-ish one, three when you want the triangle case generalised. It's the tool for "the object is roughly a quad, but minAreaRect keeps orienting it wrong" - a quad fit from the actual points doesn't care about the box's angle convention at all, which is a real relief if you've ever fought that.

It's also a shape-descriptor primitive: fit a k-gon, compare its area against the convex hull's area, and the gap tells you how polygonal the object is. A clean rectangle gives you almost no gap at k=4; an amoeba gives you a lot. Cheap, deterministic, no detector required.

The sockets

points is NPARRAY-only - a data array, not an image. CV Find Contours → CV Contour To Points is the standard route; the pack's point nodes exist precisely to get you into that shape.

k is the vertex count, and it's the whole point of the node. Treat the widget default as a placeholder rather than a value: a k-gon with fewer than 3 corners isn't a polygon, so set it deliberately - 4 for a quad fit, 3 for the triangle, 5+ for rounder things. There are no other inputs, no tolerance, no iterations.

Two outputs. The FLOAT is the function's own return value for the enclosed polygon - its area, following the same convention as cv2.minEnclosingTriangle - which is what you want for the "how much slack did the fit need" comparison against the hull area. The NPARRAY is the polygon's vertices, k of them, ready to draw with the pack's point/annotation nodes or to hand to the geometric ones.

Version, and this matters

This is an OpenCV 5.0 addition, not something that's been around forever. The pack pins opencv-contrib-python-headless~=5.0.0.93 for a reason, and its node registry is generated from and checked against the installed build - so if your environment is on an older cv2, this node either doesn't appear or doesn't work. Before you file a bug, look at what you're actually running.

Installing the pack

ComfyUI CV (bmad4ever/comfyui_cv) - search "comfyui_cv" in ComfyUI Manager, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"

Restart ComfyUI. Python ≥ 3.12 and a ComfyUI with the V3 node API. Keep the pinned wheel - the README is explicit that behaviour is curated against 5.0.0.93 and that other versions may behave differently. CV Build Information will print your actual build banner, including whether the contrib modules are present.

Where people get burned

k left at the default. A meaningless vertex count doesn't produce a meaningful polygon. Set it.

Fewer points than k. You can't fit a hexagon to four points; expect a degenerate result or a cv2 error, not a graceful fallback.

Sanity-check the float once. If you're building anything on the returned area, compare it against cv2.contourArea of the hull for one known case. It should come out slightly smaller - that's the cost of forcing k corners - and knowing your numbers agree is worth the thirty seconds.

Contrib nodes vanishing after installing another vision pack. Pack-wide, and it looks exactly like "this node was never ported": all four opencv-* wheels share one site-packages/cv2, so a non-contrib wheel installed over the contrib one empties the contrib submodules and those nodes stop registering. python tools/repair_opencv_contrib.py --check, then --apply.

And the caveat the author puts on his own work, which applies most where the geometry is unfamiliar: the codebase was written with heavy LLM assistance, he flags test-driven overfitting as a real risk, and he advises against production use without reading the source. For a fallback path in a hobby graph, fine. For a measurement you're going to ship, verify it.

Categoryimage/CV/low-level/cv2 M

Inputs (2)

NameTypeDefaultDescription
pointsNPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
kINT0-2147483648–2147483647 - - -

Outputs (2)

NameTypeDescription
floatFLOAT—
nparrayNPARRAY—