OpenCV estimateAffinePartial2D_0
The 2D transform for rotation + scale + shift — no shear allowed
- from_
- to
- inliers
- nparray_0
- nparray_1
If you have two sets of matched 2D points and you're sure they're related by nothing more than rotation, uniform scaling, and translation - the way two photos of the same flat scene are, if the camera only zoomed, rotated, and panned - then estimateAffinePartial2D is the tighter, more stable way to fit that transform. It's the "partial" affine: 4 degrees of freedom instead of the full 6, which means no shear and no non-uniform scale. estimateAffine2D can fit those extra distortions; this node refuses to, and that refusal makes it more robust when the distortion really isn't there.
This is the cv2.estimateAffinePartial2D wrapper from opencv-comfyui (geroldmeisinger/opencv-comfyui), the auto-generated "every OpenCV function as a node" pack. Its twin estimateAffinePartial2D_1 is byte-identical; grab this one. The obvious real-world job: video frame stabilization and registration between consecutive frames of a camera that's mostly just moving and rotating.
How it works
Same machinery as estimateAffine2D: it solves for a 2×3 matrix mapping from_ points onto to points, using a robust estimator that ignores outliers. The difference is the constraint set - rotation + uniform scale + translation only. method still picks the estimator:
0- least squares (use only with clean, outlier-free matches).8- RANSAC (default): samples subsets, finds the fit most points agree on, rejects the rest.4- LMEDS;16- RHO (RANSAC's faster cousin).
With RANSAC as the default, a few bad keypoint matches don't drag the whole fit off.
Inputs and outputs
- from_ (NPARRAY) - source points, N×2.
- to (NPARRAY) - matching destination points, N×2.
- method (INT) - the estimator enum above; RANSAC (8) is the sane default.
- ransacReprojThreshold (FLOAT) - inlier tolerance, ~3.0 default. Raise it for noisy matches.
- maxIters (INT), confidence (FLOAT), refineIters (INT) - RANSAC tuning; the defaults (2000 iters, 0.99, 10 refine) are fine to leave alone.
- inliers (NPARRAY, optional) - out-parameter; leave unconnected.
- Outputs: nparray_0 - the 2×3 transform matrix; nparray_1 - the inlier/outlier mask.
Wiring it up
The realistic flow: gather matched points from your two views, feed both N×2 arrays in, and pipe nparray_0 into a warpAffine_0 node (this pack ships it) to actually move the frame. nparray_1 is a 1-D mask, not an image - don't feed it to Nparrays2Image or you'll get the pack's 'NoneType' object has no attribute 'shape' error. This is a math node: it's powerful, but you're doing the plumbing yourself.
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); no model downloads. Pack gotchas: batch_size-1 images only, Python-literal strings for composite params, and the author's "Expect dragons!" warning about the raw auto-generated interface.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| from_ | NPARRAY | — | |
| to | NPARRAY | — | |
| method | INT | — | |
| ransacReprojThreshold | FLOAT | — | |
| maxIters | INT | — | |
| confidence | FLOAT | — | |
| refineIters | INT | — | |
| inliersopt | NPARRAY | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| nparray_0 | NPARRAY | — |
| nparray_1 | NPARRAY | — |