Image to Optical Flow
Turn an image's color channels into a motion field
- image
- flow
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; thenx_scaleis how much one unit of channel value moves things, andx_offsetis 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.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| x | COMBO | R | 3 options: R, G, B |
| x_scale | FLOAT | 256.00-10000–10000 | — |
| x_offset | FLOAT | -128.00-10000–10000 | — |
| y | COMBO | G | 3 options: R, G, B |
| y_scale | FLOAT | 256.00-10000–10000 | — |
| y_offset | FLOAT | -128.00-10000–10000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| flow | OPTICAL_FLOW | — |