Nodes/ComfyUI CV/cv2.intersectConvexConvex
ComfyUI Node

cv2.intersectConvexConvex

How much do these two shapes actually overlap?

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.intersectConvexConvex
  • p1
  • p2
  • float
  • nparray
◄handleNestedtrue►

IoU - intersection over union - is the score everything in detection is graded with, and for boxes it's four comparisons. For arbitrary convex polygons it's this node: it computes the intersection area of two convex shapes and hands you both the number and the polygon where they meet.

It's a raw wrapper from bmad4ever/comfyui_cv, the pack that exposes OpenCV as ComfyUI nodes. The pack itself uses it for a CV Polygon IoU (convex) subgraph and ships a convex-geometry playground workflow, so you're on a well-trodden path rather than a corner of the API.

Inputs and outputs

  • p1 - the first polygon, as an NPARRAY of (N,1,2) or (N,2) float32 points. The author's tooltip names the sources: CV Points, or CV Contour To Points with dtype float32. It's typed NPARRAY-only on purpose - this is a point set, not a picture, so an IMAGE or MASK link is rejected.
  • p2 - the second polygon, same layout.
  • handleNested (optional, default True) - whether to handle the case where one polygon is entirely inside the other. With the default, a contained polygon still gives you its area as the intersection. Set it to False and nested pairs return 0, which is cv2's documented behaviour and a genuinely surprising result if you weren't expecting it.
  • Outputs: a float - the intersection area, where 0.0 means the shapes are disjoint - and an nparray, the intersection polygon's points.

Divide that area by the union (area(p1) + area(p2) − area(intersection)) and you have IoU. cv2_contourArea gives you the individual areas.

What you'd use it for

Mask-based geometry, mostly. Two masks become contours, contours become point arrays, and then you can ask whether the region a prompt painted overlaps the region a detector found. That's the same job as box IoU, but at the fidelity of the actual shape rather than its bounding rectangle - which matters when your regions are diagonal, thin or rotated.

Other honest uses: checking that an AR marker's quad still overlaps the expected target; validating a warped region against a reference; deduplicating overlapping regions before you paste or crop; and building a quick "how much of this object is inside that zone" metric for a tracking or counting workflow.

The area you get back is in pixels² of whatever coordinate space you fed it. If your two polygons come from differently-sized images, you're comparing apples to oranges until you rescale one - CV Scale BBoxes and the transform-points nodes are the plumbing for that.

The trap: "convex" is load-bearing

The function's contract is convex input. The pack's own tooltip is blunt about what happens otherwise: non-convex input gives undefined results. Not an error, not a fallback - undefined. A blob with a notch, a contour traced around a star, a hand-drawn mask with a concave edge: all of those can produce a number that looks plausible and is wrong.

The fix is cheap. Run the contour through cv2_convexHull (with returnPoints on, so you get points back rather than indices) and intersect the hulls, or guard with cv2_isContourConvex - the node next door - and branch on the bool it returns. If you're computing IoU for a grader or a decision, do the guard; a silently wrong overlap score is worse than an error.

Installing the pack

Manager → search comfyui_cv, or:

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

Python ≥ 3.12 and a ComfyUI recent enough for the V3 node API; the pack is curated against OpenCV 5.0.0.93. intersectConvexConvex is core OpenCV, so it's there as soon as the pack loads. No models to download.

Other things that bite

Point dtype. Float32 is what the tooltip asks for. Integer contours from some sources work, others don't; casting deliberately beats hoping.

Point layout. (N,1,2) or (N,2) - the two shapes cv2 accepts. A transposed array of the right size is not one of them.

Degenerate polygons. Fewer than three points, or collinear points, gives you an area of zero without complaint. If everything reads 0.0, check the inputs before you doubt the geometry.

Using it where a mesh or raster would do. For pixel-accurate overlap of messy masks, cv2_bitwise_and on the two masks followed by an area count is exact, and doesn't care about convexity at all. This node is the right tool when your shapes genuinely are convex, or when you need the intersection polygon itself.

The pack's README is upfront that it's a personal, LLM-assisted project not recommended for production without review. The maths here is OpenCV's; the tooltips - which are unusually careful on this node - are the author's.

Categoryimage/CV/low-level/cv2 I

Inputs (3)

NameTypeDefaultDescription
p1NPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
p2NPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
handleNestedoptBOOLEANtrue - - - Preset to the OpenCV default (True).

Outputs (2)

NameTypeDescription
floatFLOAT—
nparrayNPARRAY—