Nodes/ComfyUI-QuasimondoNodes/Image to Optical Flow
ComfyUI Node

Image to Optical Flow

Turn an image's color channels into a motion field

By Quasimondo·Created 2 years ago·Updated about a year ago· 15
Image to Optical Flow
  • image
  • flow
xR
x_scale256.00
x_offset-128.00
yG
y_scale256.00
y_offset-128.00

Optical flow is normally computed from two video frames - this node does the opposite. Image to Optical Flow takes a single image and builds a flow field out of its color channels, letting you specify which channel is the X component, which is the Y, and how they're scaled and offset. It doesn't estimate motion; it treats channel values as motion vectors. That's the entire point: you get to hand-craft a flow field, or repurpose an image you already have, and feed it to any node that consumes OPTICAL_FLOW.

Think of it as a bridge. Want to make a warp node follow a pattern you've painted? Paint it as colors, feed it here, done.

How it works

The flow is built from two of the image's channels. By default the R channel becomes the X (horizontal) component and G becomes the Y (vertical) component - which is also the standard way flow fields are visualized, so the defaults produce something that reads like a real flow map. Each selected channel gets the same treatment:

flow_x = channel_R * x_scale + x_offset
flow_y = channel_G * y_scale + y_offset

The defaults are tuned for images whose channel values run 0–1: x_scale/y_scale 256 and x_offset/y_offset −128. That maps a mid-gray 0.5 to zero motion, darker values to negative displacement, brighter values to positive - the conventional flow encoding where 0.5 means "no movement." The output is a numpy 2-channel array labeled OPTICAL_FLOW, which only plugs into nodes that accept that type.

The channel pickers are the creative dial. Swap Y to the B channel and you can encode motion using any pair of channels you like - handy when your source image is itself an output of something that already packed data into channels.

The inputs that matter

  • image - the source. A batch is fine; the flow is built per image.
  • x / y - which channels become the X and Y components (R, G, or B each).
  • x_scale / x_offset, y_scale / y_offset - the mapping from channel value to displacement. Leave the defaults until you understand the encoding; then x_scale is how much one unit of channel value moves things, and x_offset is the "zero motion" point.

One output: flow (OPTICAL_FLOW).

Install

From the Quasimondo pack. ComfyUI Manager → search ComfyUI-QuasimondoNodes, or:

cd ComfyUI/custom_nodes
git clone https://github.com/Quasimondo/ComfyUI-QuasimondoNodes
cd ComfyUI-QuasimondoNodes
pip install -r requirements.txt

Pure torch/numpy - no models.

Where people get burned

The big one is type confusion. The output is OPTICAL_FLOW, a custom type that only plugs into nodes expecting optical flow - it will not accept a plain IMAGE input. If you try to feed the result into a generic warp node that wants an image, the sockets won't connect. Check that your downstream node actually takes OPTICAL_FLOW before building around this.

Second, the defaults assume a 0–1 channel range. If your image is already scaled 0–255 (some loaders hand you that), the defaults will produce enormous, clipped motion vectors. Match the scale to your data, or normalize first.

And remember what this node is not: it doesn't compute motion between frames, so it won't give you a "real" optical flow of a video. For real flow you want a model that compares frames - this is for authoring flow, which is rarer and underrated.

Categoryimage

Inputs (7)

NameTypeDefaultDescription
imageIMAGE
xCOMBOR3 options: R, G, B
x_scaleFLOAT256.00-10000–10000
x_offsetFLOAT-128.00-10000–10000
yCOMBOG3 options: R, G, B
y_scaleFLOAT256.00-10000–10000
y_offsetFLOAT-128.00-10000–10000

Outputs (1)

NameTypeDescription
flowOPTICAL_FLOW