Nodes/opencv-comfyui/OpenCV estimateAffine2D_0
ComfyUI Node

OpenCV estimateAffine2D_0

The node that finds the transform between two sets of matching points

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV estimateAffine2D_0
  • from_
  • to
  • inliers
  • nparray_0
  • nparray_1
method
ransacReprojThreshold
maxIters
confidence
refineIters

Imagine you've matched two sets of points - say, keypoints on frame 1 and the same keypoints on frame 2 of a video. You know they line up, but how? What rotation, scale, shear, and translation turn one set into the other? That's the question estimateAffine2D answers: it takes two point sets and hands back a 2×3 affine transform matrix that best maps one onto the other, plus a mask saying which points it trusted.

This node is the OpenCV cv2.estimateAffine2D wrapper from opencv-comfyui (geroldmeisinger/opencv-comfyui), the auto-generated "every cv2 function as a node" pack. It's the mathematical core of image alignment - image stitching, frame registration, motion estimation, stabilizing a wobbling shot. In ComfyUI you'll mostly reach for it when you're building a registration pipeline, because the transform it produces is the thing you'd feed into a warpAffine node (which this pack also ships) to actually move the image.

How it works

The function computes the best-fit affine transform (rotation + scale + shear + translation - 6 degrees of freedom) from corresponding point pairs. The method parameter decides how it handles the "best" part:

  • 0 - plain least squares: fits all points, falls apart if there are outliers.
  • 8 - RANSAC (the default in OpenCV): randomly samples subsets, finds the fit most points agree on, and rejects outliers. This is what you want with real-world keypoint matches, which always contain garbage.
  • 4 - LMEDS: least-median-of-squares, another robust estimator.
  • 16 - RHO, RANSAC's newer, usually faster cousin.

RANSAC's robustness is the whole point - a handful of wrong keypoint matches can skew least squares badly, and RANSAC just ignores them.

Inputs and outputs

  • from_ (NPARRAY) - source points, one per row, N×2.
  • to (NPARRAY) - matching destination points, N×2, same count.
  • method (INT) - the enum above; leave at RANSAC (8) unless you know better.
  • ransacReprojThreshold (FLOAT) - how far a point may sit from the predicted transform and still count as an inlier. Default ~3.0; raise it for noisy point clouds.
  • maxIters (INT), confidence (FLOAT), refineIters (INT) - RANSAC tuning knobs. The defaults (2000 iterations, 0.99 confidence, 10 refine iterations) work; you almost never need to touch them.
  • inliers (NPARRAY, optional) - an out-parameter. Leave it unconnected.
  • Outputs: nparray_0 - the 2×3 transform matrix; nparray_1 - the inlier/outlier mask (1 = trusted, 0 = rejected).

Wiring it up

The honest advice: this is a math node with awkward wiring. Your point arrays have to be built as nparrays (from feature detectors or manual coordinate lists), the pack only takes batch_size-1 images through Image2Nparray, and the outputs aren't displayable images - nparray_1 is a 1-D mask array. The realistic flow is: compute matches somewhere, feed both point sets here, take nparray_0 into a warpAffine_0 node to apply the transform to the actual frame. If that sounds like a lot of plumbing, it is. For most people this pack's _0/_1 overload twins are interchangeable - and so are the two estimateAffine2D nodes here, which ship byte-identical.

Install

ComfyUI Manager (search "opencv-comfyui") or git clone https://github.com/geroldmeisinger/opencv-comfyui into ComfyUI/custom_nodes, then restart. Needs opencv-contrib-python (plus numpy, torch in requirements); no model downloads. Author's warning applies: "Expect dragons!" - raw enums, literal-string composites, auto-generated ugliness.

Categoryimage/OpenCV

Inputs (8)

NameTypeDefaultDescription
from_NPARRAY
toNPARRAY
methodINT
ransacReprojThresholdFLOAT
maxItersINT
confidenceFLOAT
refineItersINT
inliersoptNPARRAY

Outputs (2)

NameTypeDescription
nparray_0NPARRAY
nparray_1NPARRAY