OpenCV findEssentialMat_0
Recover camera motion between two views, the hard way
- points1
- points2
- cameraMatrix
- mask
- nparray_0
- nparray_1
This is the pack's most uncompromising "this is a computer-vision library, not a ComfyUI image pack" node, and it's worth knowing it for that reason. findEssentialMat_0 wraps cv2.findEssentialMat, the function that takes matching points between two camera views and computes the essential matrix - the 3×3 object encoding the camera's rotation and translation between the two shots. It's the mathematical heart of structure-from-motion, visual odometry, and camera pose estimation: the input is point correspondences, the output is "how did the camera move."
It is also absolutely not a filter. The inputs are not images you want to look at, and the outputs are not images at all. This node is for the rare ComfyUI workflow that does real photogrammetry math - the kind of thing people normally do in plain Python with a stack of feature matches.
The inputs that matter
points1,points2(NPARRAY) - matched point coordinates from the two views, as N×2 (or N×1×2) arrays of (x, y). Every row inpoints1corresponds to the same physical point as that row inpoints2; garbage matching means garbage geometry. Typically these come from a feature matcher (SIFT/ORB style), which this pack doesn't wrap - you'd source them from another tool.cameraMatrix(NPARRAY) - the 3×3 intrinsic matrix of the camera (focal lengths and principal point). Without correct intrinsics, the essential matrix is meaningless. This is why it's called the essential matrix and not the fundamental one: the fundamental matrix works with uncalibrated cameras, the essential matrix assumes you know the calibration.method(INT) - the robust estimation method: 8 = RANSAC, 4 = LMEDS. RANSAC is the sensible default for noisy correspondences.prob(FLOAT) - RANSAC confidence, 0.999 is the usual default.threshold(FLOAT) - RANSAC's reprojection error threshold (pixels). Too tight rejects good matches; too loose accepts junk.maxIters(INT) - RANSAC iteration cap; higher = more thorough, slower.mask(NPARRAY, optional) - an out-parameter for inlier/outlier flags. Leave unplugged.
Two outputs: nparray_0 is the 3×3 essential matrix; nparray_1 is the inlier mask (0/1 flags per match). Neither is an image - the README's "not every nparray is an image" warning applies in full force here. Don't route these to Nparrays2Image; you'll get nonsense or an error.
Installing it
One of ~600 nodes in geroldmeisinger/opencv-comfyui. ComfyUI Manager → search opencv-comfyui, or:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
then restart. Needs opencv-contrib-python, numpy, torch. If startup fails with Cannot import name 'guidedFilter' from 'cv2.ximgproc', conflicting OpenCV installs - consolidate to one.
The honest take
Ninety-nine percent of ComfyUI users will never have a reason to run this node, and that's fine. It exists because the pack wraps everything top-level in OpenCV - the README even warns that "not every function is useful within ComfyUI without further processing." If your workflow is doing camera pose, 3D reconstruction, or depth-from-motion, this is the correct and only way to get an essential matrix inside ComfyUI. If you're not, let it be a monument to how thorough auto-generation can be. It's also a great example of why the pack's nparray-in/nparray-out design exists: OpenCV geometry functions have no sane Comfy IMAGE representation, and this node doesn't pretend otherwise.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| points1 | NPARRAY | — | |
| points2 | NPARRAY | — | |
| cameraMatrix | NPARRAY | — | |
| method | INT | — | |
| prob | FLOAT | — | |
| threshold | FLOAT | — | |
| maxIters | INT | — | |
| maskopt | NPARRAY | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| nparray_0 | NPARRAY | — |
| nparray_1 | NPARRAY | — |