OpenCV warpAffine_0
The node that rotates, shifts, and skews your images with a 2×3 matrix
- src
- M
- dst
- nparray
Every rotation, translation, scale, and shear you've ever done in an image editor is one warpAffine call under the hood. This node wraps that OpenCV workhorse, and it's one of the genuinely useful entries in this pack - the deterministic, millisecond, "just move the pixels" primitive that the KB would tell you to reach for before you burn a diffusion pass on it. Straighten a tilted generation, re-center a subject, cheaply augment a dataset, correct slight jitter between video frames - all of it is warpAffine territory.
How it works
An affine transform is the whole family of "parallel lines stay parallel" geometric operations, encoded as a single 2×3 matrix M. The first two columns mix rotation and scale/shear; the third column is the translation. Feed warpAffine an image plus that matrix and it remaps every pixel to its new location, filling the gaps however you tell it to. Because it's a matrix, you never hand-roll it - you build M with the pack's getRotationMatrix2D_0 node (takes center as a literal, angle, and scale), or with getAffineTransform_0 from point pairs. The hard part of affine warping isn't running it; it's producing the right M, and this pack covers both sides.
Inputs and outputs
The ones you actually set:
src- theNPARRAYimage (run it throughImage2Nparrayfirst if you're starting from a ComfyIMAGE).M- the 2×3 transform matrix as anNPARRAY, usually straight out ofgetRotationMatrix2D_0.dsize- output size as a literal string, e.g.(512, 512)or(1024, 768). The pack parses these withast.literal_eval, so the parentheses and comma matter.flags- interpolation.1is linear (the default good-enough),0is nearest-neighbor (your pixel-art friend),2is cubic,4Lanczos if you want the fancy.borderMode/borderValue- what fills the edges you just opened up.0is constant fill withborderValue(a literal like(0, 0, 0));1replicates the edge pixels. If you rotate and see black corners you don't want, switch to1.
There's an optional dst - the README's advice is to skip the out-params, so leave it unplugged. Output is a single nparray, which you push through Nparrays2Image to get back to a normal image.
Installing
Standard for the pack. ComfyUI Manager, search "opencv-comfyui", install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
requirements.txt handles opencv-contrib-python, numpy, torch.
Common issues
invalid syntax (<unknown>, line 0)- yourdsizeorborderValueliteral isn't valid Python. It must be(512, 512), not512, 512or[512, 512].- Black triangles at the edges after rotation - that's
borderModedefaulting to constant. SetborderModeto1to replicate edges, or setborderValueto match your background. Only images with batch_size==1 are supported!- the pack only handles single images; pull one frame out of a batch withImageFromBatchfirst.
One more honest note: this pack has no CUDA path (no Image2UMat node), so warpAffine_0 runs on CPU. For a single warp that's instant; for per-frame warping of a long video, factor in the cost.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY | — | |
| M | NPARRAY | — | |
| dsize | STRING | — | |
| flags | INT | — | |
| borderMode | INT | — | |
| borderValue | STRING | — | |
| dstopt | NPARRAY | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |