Apply optical flow
Warp your generated frame to match the source, before the sampler redraws it
- image
- flow
- IMAGE
This is the node that makes vid2vid consistency actually work. The trick it implements - the "warp the previous output forward, then let the sampler redraw it" pattern - has been the backbone of frame-consistent image animation since Deforum and EbSynth. The README lays it out plainly: you use it "to improve consistency between video frames in a vid2vid workflow, by applying the motion between the previous input frame and the current one to the previous output frame before using it as input to a sampler."
Plainly, in workflow terms: you have source video frame N and frame N+1. You generated frame N' (your styled version of N). Instead of starting the next img2img pass from N' - which still thinks the scene hasn't moved - you warp N' along the motion between N and N+1. Now the sampler starts from an image that already matches where the source video actually is, and the redraw only has to clean up your style, not invent the motion. Result: way less swimming, morphing, and flicker.
How it works
The code is lifted from Deforum (the README credits it, MIT license, same as this pack), so this is battle-tested stuff, not a one-off. Under the hood it does a cv2.remap: it takes your flow (a two-channel displacement map from Compute optical flow), adds a pixel grid so the offsets become absolute source coordinates, and samples your image through that map with bilinear interpolation.
One detail worth knowing: before warping, it pads your image by 25% on each side, warps the padded version, then center-crops it back. That's the standard trick for hiding the ugly edge-stretch that happens when flow points past the image boundary. You'll still get some softness on the edges, but not the raw smearing a naive warp would give you.
There's no strength or blend knob here - just image and flow. It's an all-or-nothing warp. If you want to mix the warped frame with the original, you'll need to do the blending yourself, which honestly fits ComfyUI's philosophy: this node does exactly one thing and does it well.
Inputs and outputs
image- the frame you want to move. In the vid2vid loop, that's your previously generated frame. It must be the same dimensions as the frames that produced the flow.flow- theOPTICAL_FLOWoutput from Compute optical flow, computed between the frame pair you care about.
The output is a single IMAGE of the same dimensions, warped along the motion field. Wire it wherever you'd feed the next frame's image: into a VAE encode ahead of your sampler, into an Efficient Loader's image slot, whatever your workflow uses. It slots into the same place the raw frame would go.
Direction matters
Flow is directional: Compute reads prev → current. So compute flow with prev = source frame N and current = source frame N+1, then apply it to the frame that sits where N was (your generated N'), and the output is positioned where N+1 is. Feed the pair backwards and you'll warp your output the wrong way - the motion compounds instead of cancelling. If things look jittery, check this first; it's the classic mistake.
Installing it
Same as the whole pack - ComfyUI Manager, search ComfyUI Optical Flow, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/seanlynch/comfyui-optical-flow
No requirements.txt, no models to download, no GPU needed for the warp. The pack leans on OpenCV and NumPy, which ComfyUI already ships.
Where it falls short
A warp can only rearrange pixels that exist. Occluded regions - bits of the scene that disappear between frames - can't be reconstructed, so you'll get smears or duplicated edges there. That's not a bug in the node; it's inherent to optical flow, and the community's answer is to pair the warp with a masked inpaint pass to fix the holes it leaves. If you're chasing near-flawless consistency, treat Apply as the motion backbone and let your sampler repair the seams. For the casual animator, it'll quietly save your renders from looking like a morphing mess - which is more than most nodes this small can claim.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| flow | OPTICAL_FLOW | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |