Nodes/ComfyUI CV/cv2.rotatedRectangleIntersection
ComfyUI Node

cv2.rotatedRectangleIntersection

Did Those Two Tilted Boxes Actually Overlap?

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.rotatedRectangleIntersection
  • rect1
  • rect2
  • int
  • nparray

Axis-aligned rectangles lie about anything tilted. A car, a pen, a rotated piece of paper, a face at 30° - wrap them in a straight BoundingBox and the box claims most of the empty background too. That's why OpenCV has RotatedRect: a centre, a width/height, and an angle. And the moment you have two of those, you want to know whether they overlap - which is what this node answers.

It's the raw wrapper of cv2.rotatedRectangleIntersection(rect1, rect2), one of the ~470 auto-generated cv2.* nodes in ComfyUI CV (bmad4ever/comfyui_cv). Nothing here runs a model: this is the deterministic geometry half of a ComfyUI graph, the same family of operations OpenCV has had for thirty years, sitting next to your samplers rather than inside them.

What you get back

Two outputs, and the interesting one isn't the obvious one:

  • int - a status code. OpenCV's RectanglesIntersectTypes: 0 = no intersection, 1 = partial, 2 = one rectangle fully contains the other. Branch on it if you only care whether they collide.
  • nparray - the actual intersection polygon, as a point array. This is the one you want, because you can measure it.

The classic move is nparray → cv2.contourArea for an overlap area, then divide by each rect's area for a rotated IoU. Or nparray → CV Points To Contour → CV Draw Contours to see the overlap drawn on the frame. If you'd rather build the rest of that math yourself, the pack's CV Polygon IoU (convex) subgraph does the polygon version (intersectConvexConvex) as a reference.

Inputs: two rotated rects, either wired or typed

Both rect1 and rect2 are required, and both use the pack's CV_ROTATED_RECT socket, which has a string widget as the type fallback. That gives you two ways in:

Wire it. The same socket is emitted by cv2.minAreaRect (tight box around a point set), cv2.fitEllipse (an oriented ellipse, same struct), cv2.CamShift (a tracker's rotating window), and consumed by cv2.boxPoints and the cv2.ellipse variant. So a real chain is: contour → points → cv2.minAreaRect → here. Two boxes, one comparison.

Type it. ((cx, cy), (w, h), angle) in degrees - the nested spelling cv2 itself returns. The flat (cx, cy, w, h, angle) is accepted too, because that's what a splitter or a saved workflow tends to hand over. Leave a field blank and the node raises with the expected format instead of a cryptic parse error, which is more helpful than it sounds.

Install

Manager → search ComfyUI CV → install, or:

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

The pack needs Python ≥ 3.12 and a recent ComfyUI built on the V3 node API. If you'd rather not run the pip line, Manager handles the dependency - but read the gotcha below first, because the OpenCV wheel is where this pack breaks.

Where people get burned

The contrib/non-contrib wheel trap. All four OpenCV distributions share one site-packages/cv2. Install plain opencv-python over opencv-contrib-python, or over the headless contrib wheel this pack pins, and the shared binary gets overwritten with a core-only build. Nodes that come from contrib submodules silently vanish from the menu - no error, they're just gone. That's what tools/repair_opencv_contrib.py --check is for; --apply fixes it. The pinned version is 5.0.0.93 for a reason: the pack is curated against it, and other versions may behave differently.

"No intersection" is not "not touching." The separating-axis test is exact, so grazing or edge-adjacent boxes come back 0 with no polygon. If you're doing collision work, decide up front whether touching counts.

Different rects, different angles. A box from minAreaRect and an ellipse from fitEllipse are the same struct but not the same estimate, and minAreaRect's angle convention has bitten everybody at least once. Don't compare raw angles across sources; compare areas and overlap instead.

Boxes are data, not images. Neither input takes an IMAGE link - you need the rect struct. Also worth knowing: the pack is explicitly a personal, AI-assisted project (the README says so, at length, including that it recommends an independent code review before any production use). For an overlap test between two rectangles, that's a small surface area to trust. It's still a real tool, just not an audited one.

Categoryimage/CV/low-level/cv2 R

Inputs (2)

NameTypeDefaultDescription
rect1CV_ROTATED_RECT,STRING - - - A rotated rectangle: ((center_x, center_y), (width, height), angle in degrees). Wire it from cv2.fitEllipse / cv2.minAreaRect / cv2.CamShift, or type the literal (the flat (cx, cy, w, h, angle) spelling is accepted too).
rect2CV_ROTATED_RECT,STRING - - - A rotated rectangle: ((center_x, center_y), (width, height), angle in degrees). Wire it from cv2.fitEllipse / cv2.minAreaRect / cv2.CamShift, or type the literal (the flat (cx, cy, w, h, angle) spelling is accepted too).

Outputs (2)

NameTypeDescription
intINT—
nparrayNPARRAY—