CV Contour To Points
Get a contour out of Contour Land and into cv2's geometry functions
- contours
- points
- count
- found
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 forcv2.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.intersectConvexConvexwhere 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- fromCV Find Contours.index(default 0) - which contour, as above.dtype-int32 (native contour)orfloat32.
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
convexityDefectsthrows. Yourdtypeis float32. It wants the original int32 contour, and it wants the hull to have come from that same contour.foundis false. The set has fewer contours thanindex + 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 aMathExpressionwill need the axis dropped withCV 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.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| contours | CV_CONTOURS | From 'CV Find Contours'. | |
| index | INT | 00–100000 | Which contour of the set to convert (Find Contours sorts by area, largest first - 0 = biggest). |
| dtype | COMBO | int32 (native contour) | Element type. Keep int32 for cv2.convexityDefects (it requires the ORIGINAL integer contour); float32 for subpixel geometry (cv2.intersectConvexConvex). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| points | NPARRAY | (N,1,2) point array - the layout every cv2 geometry function and draw node expects. |
| count | INT | — |
| found | BOOLEAN | — |