Nodes/ComfyUI CV/cv2.rapid.drawCorrespondencies
ComfyUI Node

cv2.rapid.drawCorrespondencies

The debug picture that tells you why your pose refinement failed

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.rapid.drawCorrespondencies
  • bundle
  • cols
  • nparray

Tracking a 3D model through a video is one of those things that either works beautifully or produces a pose that slides sideways for no visible reason. When it slides, you need to see which search lines locked onto which edges - and that's all this node is. It takes the correspondence bundle from a RAPID round and renders it over the frame so you can look at it.

What it draws, and why that matters

The pack's own guidance for the RAPID refinement is blunt about this: search lines and correspondences are the debug outputs - draw them when a refinement diverges. Concretely, you'll see the matched points and their correspondence to the model's control points, which tells you whether the search found the object's real edge or grabbed a background line, a shadow, or a texture inside the silhouette. That's a diagnosis no scalar output gives you. A bad found flag tells you something went wrong; this tells you what.

Inputs

Two, and both are data rather than pictures:

  • bundle - the correspondence bundle from the round you're debugging. In the pack's own RAPID playground workflow, this comes straight off the pose-refine subgraph's bundle output.
  • cols - the colours/columns bundle from the same stage (the subgraph's cols output). Together, these two are what cv2 needs to lay the correspondences out for display.

There's no colour, thickness or font widget here - this node doesn't take styling arguments, unlike the other two RAPID drawing nodes. What you get is what the algorithm produced.

Output

A single nparray, and this is the part that catches people: it is not type-preserving. The two inputs accept the pack's polymorphic image-ish socket, but the result comes back as an NPARRAY regardless, so nothing shows up in a preview node until you convert. Add CV Array → Image and you'll get an IMAGE plus an alpha socket to look at.

If your graph already has an image lane (the frame being tracked, for instance), the simplest debug pattern is: run the full pose-refine step, then draw the correspondences and save that image next to the source frame. Comparison of the two frames in the same contact sheet is how you find the frame where the tracking went wrong.

Where it fits

RAPID in this pack is a loop, and the drawing nodes are the three optional ends of it:

  • rapid.drawSearchLines - shows the search lines themselves (from the locations output of rapid.extractLineBundle), so you can see whether they're reaching the edge at all.
  • rapid.drawCorrespondencies - shows what the search matched, which is this node.
  • rapid.drawWireframe - shows the model's projected geometry, the sanity check on the pose itself.

For the whole pipeline as one node, use the curated CV Rapid Track (Sequence) - it tracks a known mesh through a batch of frames, sampling control points along the projected silhouette, searching for gradients, and refining with PnP, warm-started per frame. The drawing nodes are what you reach for while you're debugging it, not what you ship.

Install

From ComfyUI CV (bmad4ever). ComfyUI 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"

Restart. Python ≥ 3.12 and a current ComfyUI built on the V3 node API. No models or downloads.

Common issues

"Nothing to preview." The output is NPARRAY. Convert with CV Array → Image first - same trap as the other raw wrappers that don't echo their input type.

Node missing from the menu. cv2.rapid is contrib-only. A non-contrib opencv-python wheel installed over the contrib build silently empties those submodules and the pack skips the entries at startup. python tools/repair_opencv_contrib.py --check in the pack directory diagnoses it, --apply fixes it.

A drawing that's nearly empty. You're feeding it a bundle from a round where almost nothing matched - which is itself the answer. Cross-check with the mask output of rapid.convertCorrespondencies and the scores from the refine step.

It draws over the wrong frame. These nodes render relative to the sample coordinates they're given, so a mismatched resolution between the image you tracked and the image you're drawing on will scatter everything. Match the resolutions, and don't resize between the solve and the debug draw.

Categoryimage/CV/low-level/rapid

Inputs (2)

NameTypeDefaultDescription
bundleNPARRAY,IMAGE,MASK - - - Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
colsNPARRAY,IMAGE,MASK - - - Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.

Outputs (1)

NameTypeDescription
nparrayNPARRAY—