Nodes/ComfyUI CV/cv2.solvePnPRansac
ComfyUI Node

cv2.solvePnPRansac

Pose Estimation That Survives Your Bad Matches

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.solvePnPRansac
  • objectPoints
  • imagePoints
  • cameraMatrix
  • distCoeffs
  • retval
  • rvec
  • tvec
  • inliers
◄useExtrinsicGuessfalse►
◄iterationsCount100►
◄reprojectionError8.0000►
◄confidence0.9900►
◄flagsSOLVEPNP_ITERATIVE►

Plain cv2.solvePnP trusts every correspondence you give it, which is a bad bet the moment those correspondences come from a feature matcher. One wrong match and the least-squares fit bends toward it. solvePnPRansac is the same pose problem, solved with a RANSAC loop instead: sample minimal subsets, keep the pose that explains the most points, then fit the inliers. It's slower, it's tolerant, and it tells you which points it believed.

This raw wrapper lives in ComfyUI CV (bmad4ever/comfyui_cv), and the pack's curated CV Solve PnP (Pose) node wraps the same two solvers behind one estimation dropdown if you'd rather not think about it. Use the raw node when you want the RANSAC parameters laid bare - that's the whole appeal here, because those parameters are what decide whether this fails or works on your data.

Inputs

The three required ones are identical to solvePnP: objectPoints (Nx3), imagePoints (Nx2, same order) and cameraMatrix (3×3 K, e.g. from CV Camera Matrix). Then the optional tail, which is where the tuning lives:

  • distCoeffs - lens distortion; leave unconnected for a zero-distortion pinhole.
  • useExtrinsicGuess (default false) - a starting rvec/tvec guess. On this node rvec/tvec are outputs, so there's nothing to seed it with; leave it off.
  • iterationsCount (default 100) - RANSAC iterations. More iterations buy robustness on noisy data at the cost of time.
  • reprojectionError (default 8.0) - the inlier threshold, in pixels: the maximum allowed distance between an observed point and where the pose projects the corresponding object point. This is the field to tune. Tighten it on clean data and you get a stiffer, better pose from fewer points; loosen it and you keep more inliers while letting worse matches back into the final fit.
  • confidence (default 0.99) - the probability the algorithm is asked to produce a useful result. It works with the iteration count to decide early termination.
  • flags (default SOLVEPNP_ITERATIVE) - the underlying solver, from the same set as solvePnP (EPNP, SQPNP, IPPE, IPPE_SQUARE, P3P, AP3P). Planar targets belong on IPPE.

Outputs

Four sockets, one more than solvePnP:

  • retval - boolean; false means RANSAC didn't find a usable pose. Branch on it.
  • rvec / tvec - the pose, exactly as the plain solver returns them.
  • inliers - the indices of the object/image points that were accepted. This is the underrated output: it's a quality report on your matching stage, and it's a filter. Keep the first three, drop the rest, and you can feed a clean subset back in for a final exact fit.

That inlier-driven second pass is the pattern worth copying: RANSAC to find which points are trustworthy, then the least-squares solve on just those to get the tightest pose. Within a graph you can index the arrays with CV Take By Index (a lookup-table indexing node, which is the pack's way of doing this without a loop).

Install

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 ComfyUI. Python ≥ 3.12 and a recent ComfyUI on the V3 node API. Pure geometry - no model files.

Where people get burned

The threshold is in pixels, and pixels are not portable. 8.0 is fine at 640×480 and meaningless at 4K. Scale it with your resolution and the noise in your detections, or you'll spend an afternoon deciding that RANSAC "doesn't work."

Too few inliers. RANSAC needs a decent fraction of good points to sample a clean minimal set. If your matcher is mostly wrong, pose estimation is the wrong stage to fix it - filter the matches first (ratio test, CV Match Features), or you'll be tuning iterationsCount forever.

Ignoring inliers. It's the most useful output on the node and it's easy to leave dangling. Wire it into an Inspect CV Data node the first time you run a new pipeline; the count tells you immediately whether you have a quality problem upstream.

Correspondence order again. Same as solvePnP: objectPoints[i] pairs with imagePoints[i]. A permutation still yields a confident, wrong pose.

The contrib-wheel trap. All four OpenCV distributions share one site-packages/cv2; installing a non-contrib wheel over the contrib build silently strips contrib-backed nodes out of the menu. tools/repair_opencv_contrib.py --check confirms it, --apply repairs it. Worth doing before you debug anything else.

Categoryimage/CV/low-level/cv2 S

Inputs (9)

NameTypeDefaultDescription
objectPointsNPARRAYArray of object points in the object coordinate space, Nx3 1-channel or 1xN/Nx1 3-channel, where N is the number of points. vector\ can be also passed here. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
imagePointsNPARRAYArray of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel, where N is the number of points. vector\ can be also passed here. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
cameraMatrixNPARRAYInput camera intrinsic matrix $\cameramatrix{A}$ . A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
distCoeffsoptNPARRAYInput vector of distortion coefficients $\distcoeffs$. If the vector is NULL/empty, the zero distortion coefficients are assumed. Optional - leave unconnected for the OpenCV default (None). A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
useExtrinsicGuessoptBOOLEANfalseParameter used for . If true (1), the function uses the provided rvec and tvec values as initial approximations of the rotation and translation vectors, respectively, and further optimizes them. Preset to the OpenCV default (False).
iterationsCountoptINT100-2147483648–2147483647Number of iterations. Preset to the OpenCV default (100).
reprojectionErroroptFLOAT8.0000-1e+38–1e+38Inlier threshold value used by the RANSAC procedure. The parameter value is the maximum allowed distance between the observed and computed point projections to consider it an inlier. Preset to the OpenCV default (8.0).
confidenceoptFLOAT0.9900-1e+38–1e+38The probability that the algorithm produces a useful result. Preset to the OpenCV default (0.99).
flagsoptCOMBOSOLVEPNP_ITERATIVEMethod for solving a PnP problem (see ). The function estimates an object pose given a set of object points, their corresponding image projections, as well as the camera intrinsic matrix and the distortion coefficients. This function finds such a pose that minimizes reprojection error, that is, the sum of squared distances between the observed projections imagePoints and the projected (using ) objectPoints. The use of RANSAC makes the function resistant to outliers.

Outputs (4)

NameTypeDescription
retvalBOOLEAN—
rvecNPARRAY—
tvecNPARRAY—
inliersNPARRAY—