cv2.sampsonDistance
The QA Number That Tells You Your Matches Are Rubbish
- pt1
- pt2
- F
- float
You ran CV Find Fundamental Matrix, it returned an F and a healthy inlier count, and now you're supposed to trust it. How do you actually check? You measure how well a point pair obeys the epipolar constraint - and the standard measure for that is the Sampson distance, because it's cheap, it's in something close to pixels, and it's what everyone else's robust pipelines minimize.
This is the raw cv2.sampsonDistance(pt1, pt2, F) wrapper from ComfyUI CV (bmad4ever/comfyui_cv), the pack that exposes ~470 OpenCV functions as nodes plus a few hundred hand-written ones. It is not an image-processing node. It's a measuring instrument, and it lives in the same graph as your matcher so you can read a number instead of guessing from a screenshot.
How it works
The exact geometric distance between a point and its epipolar line requires triangulating, projecting, and re-measuring - expensive and awkward per correspondence. The Sampson approximation gets you a first-order version of the same number: take the epipolar residual (how far off the constraint x₂ᵀ F x₁ = 0 the pair is) and normalize it by the local sensitivity of that constraint to moving the points. The result behaves like a distance instead of behaving like whatever units F happens to be scaled in, which is the whole point - a raw algebraic residual is scale-dependent and useless as a threshold, while Sampson distance sits in roughly pixel-like units you can reason about.
Inputs and output
Three inputs, all required, all NPARRAY only - none of these sockets accepts an IMAGE link, and trying to bridge an image in will not help:
pt1- first homogeneous 2D point. Homogeneous means three numbers:(x, y, 1).pt2- the corresponding homogeneous point in the second view.F- the 3×3 fundamental matrix.
And one output: float. That's the geometry. Wire it into a text preview to stare at it, or into a comparison so a threshold decides whether the pair gets used.
Two practical notes on the homogeneous part, since that's where people trip: your matcher emits Nx2 pixel coordinates, and cv2.convertPointsToHomogeneous is the node that appends the 1 and hands you Nx3. And F from cv2.findFundamentalMat (or the curated CV Find Fundamental Matrix) is already the right thing - 3×3, float, no conversion needed. Feed it an Nx2 array where a 3-vector belongs and you get an assert, not a sensible answer.
The honest caveat: one pair at a time
OpenCV's sampsonDistance computes the distance for a single correspondence per call. There is no batch version, and ComfyUI has no per-element loop node, so this is a single-pair instrument: perfect for sanity-checking F against a known-good correspondence, for chasing one suspicious match, or for validating that a calibration/stereo stage produces small residuals on the frame it was tuned for.
If your actual goal is "score all 200 matches and keep the good ones," you want the batch-shaped route instead: cv2.computeCorrespondEpilines turns the points in image 1 into the lines they should sit on in image 2, and you measure point-to-line distances over the whole set in one pass. Or just use the ratio test on the matcher and RANSAC inside the fundamental-matrix node - that's what they're for. This node is the ruler you hold against the result.
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"
Then restart ComfyUI. Python ≥ 3.12 and a recent V3-API ComfyUI are required. No models, no downloads - this is pure math on arrays you already have in the graph.
Where people get burned
The contrib wheel. opencv-python, opencv-python-headless and the contrib variants all share one site-packages/cv2. Installing a non-contrib wheel over a contrib one wipes the shared binary down to core only, and contrib-derived nodes disappear from the menu without an error. Run tools/repair_opencv_contrib.py --check if nodes go missing; --apply repairs it.
Version drift. The pack is curated against OpenCV 5.0.0.93 and says outright that other versions may behave differently. If a number looks off, check what's actually installed before rewriting your graph.
Reading it as a quality score. Sampson distance tells you about one pair. A small number on a hand-picked pair proves nothing about F; a large one on an outlier proves even less. Sample a few, or measure the set.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| pt1 | NPARRAY | first homogeneous 2d point A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| pt2 | NPARRAY | second homogeneous 2d point A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| F | NPARRAY | fundamental matrix A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| float | FLOAT | — |