Nodes/ComfyUI CV/CV Paste Through Warp
ComfyUI Node

CV Paste Through Warp

Put THIS picture THERE — correspondence-driven warping and compositing

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
CV Paste Through Warp
  • image
  • points_from
  • points_to
  • background
  • content_mask
  • background_paintable
  • image
  • mask
  • residual
  • found
◄modelthin plate spline►
◄regularization0►

This is the generic "paste a picture onto a surface" node. Give it a set of correspondences - point here should be point there - pick the model the geometry deserves, and it warps the image and composites it onto a background. Posters on walls, a design onto a shirt, a logo onto a curved can, a texture onto a 3D-ish surface. It's the node you reach for when a rectangle isn't the right shape.

The nice thing is where the correspondences can come from: CV Annotate Correspondences, which lets you drag pairs by hand with the background displayed next to the image, so you're authoring both halves visually; CV Match Features, if you want it automatic; a detector; or a grid. The fit doesn't care.

Pick the model the geometry deserves

model is the important choice, and the pack's tooltips are unusually honest about it:

  • thin plate spline - bends the image so every from point lands exactly on its to point. 3+ pairs, non-rigid: faces, cloth, anything a matrix cannot express. This is the one with no closed-form alternative.
  • homography - the 8-degree-of-freedom planar perspective map, 4+ pairs. Straight lines stay straight: posters, screens, documents. CV Quad Warp in fill mode is this node's 4-corner special case.
  • affine - 6-dof (3+ pairs), parallel lines stay parallel.
  • similarity - 4-dof (2+ pairs), rotation + uniform scale + translation, angles preserved.
  • translation - a pure shift (1+ pair).

regularization is the spline's knob (ignored by the others). At 0 the spline interpolates the control points exactly and follows noisy correspondences faithfully. Raise it and you trade exactness for a gentler warp - this is the knob that fixes a folded or rippling result. And be warned, it's image-scale dependent: cv2 adds it to the diagonal of a kernel whose other entries are in pixels squared, so on a few-hundred-pixel image 100 buys you about a tenth of a pixel of give and 1e4 is the first value you can actually see. Scale it with the square of the image size.

The masks, and the compositing detail

  • background (optional) - the image to paste into; points_to lives in its coordinates and the output is its size. Unconnected, the image warps within its own canvas over black, which is the plain warp.
  • content_mask (optional) - which part of image is real content. White is pasted, black isn't, and the mask travels through the same warp so the edge stays exact. A different-sized mask gets resized, not rejected.
  • background_paintable (optional) - where on the background the paste is allowed to land. This is how something in the background occludes the pasted image, and it's the mask that turns "sticker on top" into "poster behind the lamppost".

The composite is premultiplied, which matters more than it sounds: masking-then-blending on antialiased edges grows a dark outline, and premultiplied compositing doesn't. If you've ever wondered why your pasted logo has a grey halo, that's why.

Outputs: image (the composite, background-sized, in the input's format), mask (where the warped content actually landed after both mask gates - the alpha the composite used), residual (Nx2 of where points_from actually landed minus where it should have), and found. Watching residual tells you whether you picked the right model - if affine leaves a big residual, the surface really is curved and you want the spline.

Install

Manager → ComfyUI CV, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
cd comfyui_cv && pip install "opencv-contrib-python-headless~=5.0.0.93"

Restart. Python ≥ 3.12, V3 node API. The interactive correspondence editor (CV Annotate Correspondences) is a frontend widget shipped in the pack's web/ directory - a stale browser cache is the usual reason widgets don't render after an update.

Common issues

  • The warp folds over itself - too much freedom for bad correspondences, or the spline at regularization 0 chasing noise. Raise regularization (remember it's in squared pixels) or switch to affine/similarity.
  • found is false and nothing happened - count your pairs against the model's minimum. 4 for homography, 3 for affine, 2 for similarity.
  • Paste lands under something it should be over, or vice versa - that's background_paintable, inverted from what you'd expect.
  • Edges look cut out with a hard polygon - content_mask is doing its job too aggressively; soften it upstream.
  • Non-deterministic positions in a sequence - correspondences are data; if an upstream detector jitters frame to frame, so does the paste. Hand-authored pairs from CV Annotate Correspondences are stable.

The pack's own disclaimers apply - heavy LLM-assisted development, not production-verified, no update promises - so eyeball the composite before you run it over 300 frames.

Categoryimage/CV/features

Inputs (8)

NameTypeDefaultDescription
imageCOMFY_MATCHTYPE_V3The picture to bend and paste. The output comes back in THIS input's format. 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.
points_fromNPARRAYNx2 control points in 'image' PIXEL coordinates - where each point currently is.
points_toNPARRAYNx2 target positions in 'background' PIXEL coordinates, row-aligned with points_from - where the same-numbered point must land. 'CV Annotate Correspondences' with a background connected outputs exactly this pair.
modelCOMBOthin plate splineWhich map is fitted through the correspondences. 'thin plate spline' BENDS the image so every 'from' point lands exactly on its 'to' point (3+ pairs, non-rigid - faces, cloth, anything a matrix cannot express). 'homography' is the 8-dof planar perspective map (4+ pairs; straight lines stay straight - posters, screens, documents). 'affine' is 6-dof (3+ pairs: rotation, scale, shear, translation, parallel lines stay parallel), 'similarity' 4-dof (2+ pairs: rotation, uniform scale, translation, shape preserved), 'translation' a pure shift (1+ pair). Fewer pairs than the model needs is not an error - nothing is warped and 'found' comes out false.
regularizationFLOAT00–1000000Smoothing of the SPLINE (ignored by the other models). 0 interpolates the control points EXACTLY and follows noisy correspondences faithfully; raising it trades exactness for a gentler, more rigid warp - the knob to turn when the result folds or ripples. IMAGE-SCALE DEPENDENT: cv2 adds this to the diagonal of a kernel matrix whose other entries are d^2*log(d^2) in PIXELS SQUARED, so useful values are large - on a few-hundred-pixel image 100 buys 0.1 px of give and ~1e4 is the first setting you can see. Scale it with the SQUARE of the image size.
backgroundoptNPARRAY,IMAGEThe image pasted INTO: points_to lives in its coordinates and the output is its size. Left unconnected, the image is warped within its own canvas over black, which is the plain warp. 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.
content_maskoptNPARRAY,MASKWhich part of 'image' is real content: white is pasted, black is not, and the mask travels through the same warp so the edge stays exact. Unconnected means all of it. A mask of a different size is resized, never rejected. 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.
background_paintableoptNPARRAY,MASKWhere on 'background' the paste is allowed to land - white is paintable. This is how something in the background occludes the pasted image. Unconnected means everywhere. 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 (4)

NameTypeDescription
imageCOMFY_MATCHTYPE_V3The composite, background-sized, in the 'image' input's format. The background untouched when found=false.
maskMASKWhere the warped content actually landed, after both mask gates - the alpha the composite used. All zeros when found=false.
residualNPARRAYNx2 where 'points_from' actually landed minus where it should have. ~0 for the spline at regularization 0; for the rigid models it is the honest least-squares error, i.e. how badly the model fits. Empty when found=false.
foundBOOLEANFalse when there are fewer correspondences than the model needs, or when the fit is degenerate.