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

cv2.rapid.drawSearchLines

See the lines RAPID is looking along — and why it found nothing

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
cv2.rapid.drawSearchLines
  • img
  • locations
  • nparray
◄color(0, 0, 0, 0)►

When edge-based model tracking fails, there are only a few things it can be doing wrong, and "where are the search lines actually looking?" is the first question to answer. This node draws those lines onto the frame. If the lines are floating in the background, your pose is off or your intrinsics are wrong. If they're crossing the object's edge at a shallow angle, the gradient search is going to be unreliable. If they're not where you expected at all, your model's scale or axis convention is the problem.

What it takes

  • img - the canvas to draw on. This should be the same image the search ran on, at the same resolution. In the pack's own RAPID playground workflow the frame comes straight through the chain, and each debug stage draws on the previous stage's result, so the visualisation accumulates: wireframe, then search lines, then correspondences.
  • locations - the pixel coordinates of the samples taken along each search line, i.e. the locations output of rapid.extractLineBundle. That's the whole point of the pairing: extractLineBundle produces the sampled intensities and where they came from, and this node renders the second half.
  • color - a cv2 Scalar written as a string literal, in OpenCV's BGR order: "(0, 255, 0)" is green, "(0, 0, 255)" is red, "(255, 0, 0)" is blue. A bare number broadcasts across components, so "255" means white. Pick something that isn't in the image you're debugging - over a natural scene, a saturated colour works better than white or black.

Output

One nparray. As with the other raw wrappers that aren't type-preserving, the output doesn't echo the input's type, so a preview node shows you nothing until you convert with CV Array → Image. It's the same conversion the whole debug trio needs (drawCorrespondencies, drawSearchLines, drawWireframe), so if you're building a debug lane, put one array-to-image node per draw node and keep the lane separate from your production path.

Where it fits in a RAPID round

The sequence, as the raw module exposes it:

  1. rapid.extractControlPoints - sample control points along the projected silhouette; you get ctl2d (pixels) and ctl3d (object space).
  2. rapid.extractLineBundle - collect image intensities along each control point's normal; you get the intensity bundle and the sample locations.
  3. This node - draw those locations to see where the search is looking.
  4. rapid.findCorrespondencies / rapid.convertCorrespondencies - turn the samples into matched image points and a validity mask.
  5. Solve for the pose - via rapid.rapid, or the curated CV Rapid Track (Sequence), which runs the whole loop over a batch with a PnP step and warms each frame with the previous pose.

The pack's CV Rapid Pose Refine subgraph packages steps 1–5 as one node with a note worth repeating: it refines a pose, it does not find one. The incoming rotation and translation must already be close, and the projected silhouette must be near the real edges, or the search locks onto the wrong gradient - which is precisely the failure this node visualises.

Install

Part of ComfyUI CV by 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 afterwards. Python ≥ 3.12, recent V3-API ComfyUI. No model downloads.

Common issues

Blank preview. The output is an NPARRAY - convert it with CV Array → Image.

The lines are drawn, but in the wrong place. Resolution mismatch between the frame you tracked and the frame you're drawing on. Don't resize between the solve and the debug pass.

The lines look right but the match is still wrong. Then the search is finding gradients it shouldn't: too long (len, the half-length of each search line, is too big and it reaches background clutter) or the pose is good but the silhouette isn't where the real edge is. Shorten len, and check the normals - RAPID needs the model's silhouette, and a cloud with inconsistent normals gives you search directions pointing into the object instead of along its outline.

Node absent from the menu. cv2.rapid ships in the contrib OpenCV build only. If a non-contrib wheel has clobbered the contrib one, the submodule disappears without warning: tools/repair_opencv_contrib.py --check, then --apply.

Categoryimage/CV/low-level/rapid

Inputs (3)

NameTypeDefaultDescription
imgNPARRAY,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.
locationsNPARRAY,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.
colorSTRING(0, 0, 0, 0) - - - cv2 Scalar as a literal, e.g. "(0, 255, 0)" (BGR) or "(0, 255, 0, 64)" (BGRA). A bare number broadcasts to every component, so "255" means (255, 255, 255, 255). Components past the target's channel count are ignored by OpenCV.

Outputs (1)

NameTypeDescription
nparrayNPARRAY—