cv2.findFundamentalMat (1/2)
Cv2.findFundamentalMat (1/2)
- points1
- points2
- mask
- F
- mask
Two nodes in this pack are called cv2.findFundamentalMat. This one is the full-parameter overload - every argument required - and the sibling is the version with OpenCV's defaults preset. The reason to open this one is specific and narrow: you want FM_7POINT or FM_8POINT, or you need to pin the RANSAC parameters. Otherwise you want (2/2).
F is the uncalibrated counterpart of the essential matrix. It relates two views of a scene through epipolar geometry using image coordinates alone - no camera matrix needed - which is what makes it the tool for epipolar line drawing, uncalibrated stereo rectification, and sanity checks on a match set before you go anywhere near 3D.
Inputs
points1 and points2 are your correspondences from one matching pass (CV Match Features), floating point, equal length. NPARRAY-only sockets, as the pack's tooltips say outright - data arrays, not pictures.
method is the algorithm, and this is the parameter with real consequences. FM_7POINT needs exactly 7 points and is not robust; FM_8POINT uses all points and is only for outlier-free input; FM_RANSAC (the default) and FM_LMEDS are the robust ones and want 8 or more. For feature matches, which always contain outliers, RANSAC is the choice.
ransacReprojThreshold, confidence and maxIters all arrive with widget defaults of 0 - not because zero is a good idea, but because this overload declares them required, so the wrapper has nothing to preset them to. Copy cv2's own documented defaults in: threshold 1–3 pixels (it's the maximum distance from a point to its epipolar line to count as an inlier), confidence 0.99, maxIters 1000. In particular, some tools have a flag for zero that means "use the algorithm's internal best"; set them anyway and you'll understand your own results.
Then there's the optional mask input. It's the C++ in/out buffer and feeding it does nothing - the inlier mask is an output. Look at the outputs.
Outputs
F is the fundamental matrix, 3×3 in the normal case. Then the trap: FM_7POINT may return up to three solutions, which cv2 stacks into a single 9×3 matrix. If you fed FM_7POINT and then wire F into cv2_computeCorrespondEpilines or cv2_stereoRectifyUncalibrated, you're handing those functions three matrices when they want one, and the result is nonsense rather than an error. The curated CV Find Fundamental Matrix node sidesteps this - it takes the first 3×3 and reports found - which is a decent argument for using that instead of the raw wrapper.
mask is the Nx1 uint8 inlier mask: 1 for inliers, 0 for outliers. It's how you know whether F means anything. CV Draw Matches consumes it; CV Filter Points By Mask uses it to strip the outliers out of the point sets before you triangulate.
Downstream, F goes to CV Draw Epipolar Lines for the classic visual verification (the lines should run through the matched points in the other image), and to cv2_stereoRectifyUncalibrated for the Hartley rectification route to a stereo pair. Both shipped exercises - exercise_epipolar_geometry.json and exercise_stereo_rectification.json - walk exactly that path.
One geometry warning that isn't in the node description
Points from a single plane - a poster, a wall, a chessboard - are a degenerate configuration for F. The matrix comes back; it just doesn't mean what you want it to. Use views of a scene with actual depth, from a camera that translated rather than only rotated.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
ComfyUI Manager → search "ComfyUI CV" → install → restart. Python ≥ 3.12 and a V3-API ComfyUI are hard requirements.
Common issues
All-zero F, or cv2 raising. Fewer than 8 points for the robust methods, or fewer than exactly 7 for FM_7POINT. Count them (Inspect CV Data reports shapes) before blaming the estimator.
F built from almost no inliers. Raise the threshold slightly, or fix the matching upstream with a ratio test. A 300-match set with 10 inliers is a matching failure wearing a geometry costume.
Contrib nodes missing. A non-contrib OpenCV wheel installed over the contrib build empties the contrib submodules; all the wheels share one site-packages/cv2. Run tools/repair_opencv_contrib.py --check, then --apply.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| points1 | NPARRAY | Array of N points from the first image. The point coordinates should be floating-point (single or double precision). A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| points2 | NPARRAY | Array of the second image points of the same size and format as points1 . A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| method | COMBO | FM_RANSAC | Method for computing a fundamental matrix. - for a 7-point algorithm. $N = 7$ - for an 8-point algorithm. $N \ge 8$ - for the RANSAC algorithm. $N \ge 8$ - for the LMedS algorithm. $N \ge 8$ |
| ransacReprojThreshold | FLOAT | 0.0000-1e+38–1e+38 | Parameter used only for RANSAC. It is the maximum distance from a point to an epipolar line in pixels, beyond which the point is considered an outlier and is not used for computing the final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the point localization, image resolution, and the image noise. |
| confidence | FLOAT | 0.0000-1e+38–1e+38 | Parameter used for the RANSAC and LMedS methods only. It specifies a desirable level of confidence (probability) that the estimated matrix is correct. |
| maxIters | INT | 0-2147483648–2147483647 | The maximum number of robust method iterations. The epipolar geometry is described by the following equation: $$[p_2; 1]^T F [p_1; 1] = 0$$ where $F$ is a fundamental matrix, $p_1$ and $p_2$ are corresponding points in the first and the second images, respectively. The function calculates the fundamental matrix using one of four methods listed above and returns the found fundamental matrix. Normally just one matrix is found. But in case of the 7-point algorithm, the function may return up to 3 solutions ( $9 \times 3$ matrix that stores all 3 matrices sequentially). The calculated fundamental matrix may be passed further to #computeCorrespondEpilines that finds the epipolar lines corresponding to the specified points. It can also be passed to #stereoRectifyUncalibrated to compute the rectification transformation. : |
| maskopt | NPARRAY,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 (2)
| Name | Type | Description |
|---|---|---|
| F | NPARRAY | — |
| mask | NPARRAY | — |