Nodes/ComfyUI CV/CV Contour To Points
ComfyUI Node

CV Contour To Points

Get a contour out of Contour Land and into cv2's geometry functions

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
CV Contour To Points
  • contours
  • points
  • count
  • found
◄index0►
◄dtypeint32 (native contour)►

What this is for

CV Find Contours hands you contours as its own socket type - a set, sorted by area, largest first. That's a comfortable world with contour-aware nodes in it, and it's also a cul-de-sac: the raw OpenCV geometry on a contour wants a plain array of points. Do you want cv2.convexHull, cv2.convexityDefects, cv2.intersectConvexConvex, cv2.pointPolygonTest, cv2.fitEllipse, cv2.contourArea on one contour? Then something has to do the type conversion.

That's this node. It's a bridge, one of the honest little plumbing nodes: it moves data between the pack's socket types and touches no pixels. The inverse bridge, if you're going back, is CV Points To Contour.

How it works

Pick which contour of the set you want with index - Find Contours sorts by area largest first, so index 0 is the biggest, which is very often exactly the one you meant. Then choose the element dtype and the points come out reshaped to (N, 1, 2), the layout every cv2 geometry function and every draw node in the pack expects.

The dtype dropdown is small and load-bearing:

  • int32 (native contour) - keep this for cv2.convexityDefects, which requires the original integer contour and will not accept a float-converted copy. This is the exact kind of requirement that eats an afternoon.
  • float32 - for subpixel geometry, e.g. cv2.intersectConvexConvex where you actually want the fractional overlap area.

An index past the end of the set isn't an error: you get found = false and an empty (0, 1, 2) array of the right dtype. So a workflow where a detection found three contours on one frame and none on the next doesn't halt - found is a live boolean you can gate on, and count tells you what you got.

Inputs and outputs

  • contours - from CV Find Contours.
  • index (default 0) - which contour, as above.
  • dtype - int32 (native contour) or float32.

Outputs: points ((N, 1, 2), the shape the raw wrappers and point-set nodes want), count (number of points), and found (false when the index is out of range).

Typical chain: find contours → pick the largest → convert to points → cv2_convexHull for the hull → cv2_convexityDefects (int32, remember) for the finger-gap defects, or cv2_pointPolygonTest to ask whether some other point of interest is inside it. Or skip the raw wrappers entirely and feed the points into the pack's own point nodes.

Install

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

Or search ComfyUI CV in ComfyUI Manager (publisher bmad4ever). Since the pack pins opencv-contrib-python-headless~=5.0.0.93 in its requirements, installing through Manager or pip install -r requirements.txt handles the only dependency. Needs Python ≥ 3.12 and a current V3-node-API ComfyUI. No models.

Common issues

  • convexityDefects throws. Your dtype is float32. It wants the original int32 contour, and it wants the hull to have come from that same contour.
  • found is false. The set has fewer contours than index + 1 - usually because an upstream threshold produced nothing on this frame. Nothing is broken; branch on the boolean.
  • Shape complaints from a raw wrapper. Points come out as (N, 1, 2), not (N, 2). That's the layout cv2 wants and most of the pack's nodes expect, but a hand-written expression or a MathExpression will need the axis dropped with CV Reshape Array.
  • The node is there but the cv2 function you want isn't. The registry is generated from the installed build, and it only covers top-level functions - class APIs (create* factories, detectors) aren't reachable unless a curated node bridges them. Check the raw wrapper exists before you build a graph around it.
Categoryimage/CV/contours

Inputs (3)

NameTypeDefaultDescription
contoursCV_CONTOURSFrom 'CV Find Contours'.
indexINT00–100000Which contour of the set to convert (Find Contours sorts by area, largest first - 0 = biggest).
dtypeCOMBOint32 (native contour)Element type. Keep int32 for cv2.convexityDefects (it requires the ORIGINAL integer contour); float32 for subpixel geometry (cv2.intersectConvexConvex).

Outputs (3)

NameTypeDescription
pointsNPARRAY(N,1,2) point array - the layout every cv2 geometry function and draw node expects.
countINT—
foundBOOLEAN—