Nodes/ComfyUI CV/CV Optical Flow (Farneback)
ComfyUI Node

CV Optical Flow (Farneback)

Farneback flow, and why the raw cv2 wrapper for it is unusable

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
CV Optical Flow (Farneback)
  • frame_a
  • frame_b
  • flow
  • magnitude
  • angle
◄pyr_scale0.50►
◄levels3►
◄winsize15►
◄iterations3►
◄poly_n5►
◄poly_sigma1.2►
◄windowbox (faster)►

Farneback is the dense optical-flow algorithm every OpenCV tutorial teaches: fit a polynomial to a neighbourhood of each pixel and find the displacement that best matches the polynomial in the next frame. It's been the default for fifteen years and it's still fine. It is not the best option in this pack anymore - CV Optical Flow (DIS) beats it on both sharpness and speed - but if you're following a tutorial, comparing against published numbers, or you need the exact parameter set everyone else uses, this is the node.

The reason this node exists at all is a nice illustration of why "just wrap every cv2 function" doesn't get you a usable toolkit. The raw generated cv2_calcOpticalFlowFarneback wrapper in this pack is basically unusable: its flow argument is an in/out array, which means the generated node demands you supply the empty flow buffer you're asking it to compute, and none of the seven numeric parameters has a sensible default. This curated node passes flow=None for you and presets the parameters.

The parameters, in the order you'd actually care about

frame_a and frame_b go in as frames (IMAGE or MASK directly, frame 0 of a batch, or NPARRAY), both converted to grayscale, with frame_b resized to frame_a if they don't match. Order is time order.

Then it's the classic Farneback set:

  • winsize (default 15) - the averaging window. Bigger is more robust to noise and blurrier.
  • levels (default 3) - pyramid levels. 1 means no pyramid, which means small motion only.
  • poly_n (default 5, typically 5 or 7) and poly_sigma (default 1.2) - the polynomial expansion neighbourhood and its Gaussian sigma. These two travel together: ~1.1 for poly_n=5, ~1.5 for poly_n=7. Mismatching them is the most common silent quality loss.
  • iterations (default 3), pyr_scale (default 0.5), and window (box (faster) vs gaussian).

The two you'll actually touch are levels and winsize. If large motion vanishes, add pyramid levels. If the field is noisy, raise winsize.

Outputs

flow (HxWx2 float32 (dx, dy)), magnitude (pixels of motion, HxW float32), and angle (radians, HxW float32). The angle/magnitude pair feeds CV Flow To Color in its default radians mode; the flow field itself is what you'd hand to a remap or an extract-channel pair of cv2.extractChannel nodes if you want the raw dx and dy.

Because the pack standardizes those three outputs across every flow node, swapping Farneback for DIS or TV-L1 later is a two-click change.

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. Farneback itself is core OpenCV, but the pack declares the contrib headless wheel and is curated against 5.0.0.93.

Common issues

  • Flow is garbage on a big jump between frames - Farneback's pyramid only gets you so far. Add levels, or switch to DIS with init_flow, which is the actual fix for video.
  • You want OPTFLOW_USE_INITIAL_FLOW - that's a raw-wrapper flag, and this node doesn't expose a flags input; use CV Optical Flow Flags with the generated cv2_calcOpticalFlowFarneback node if you need it, and accept the in/out array pain.
  • Sizes not matching - frame_b is silently resized to frame_a. Silent resizing is convenient and occasionally misleading; check you fed the frames in the right order.
  • cv2 DLL errors on Windows - the mixed-wheel issue that hits every cv2-based pack in the install, not this node specifically. The pack's tools/repair_opencv_contrib.py --check diagnoses it.

The pack's README is upfront that this is a personal project with heavy LLM involvement and no production promises. For flow computation specifically, that's low-risk - the algorithm is OpenCV's, and the node is mostly a sane argument-passer.

Categoryimage/CV/features

Inputs (9)

NameTypeDefaultDescription
frame_aNPARRAY,IMAGEFirst frame (earlier in time); any colour space, converted to grayscale. 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.
frame_bNPARRAY,IMAGESecond frame; resized to frame_a if the sizes differ. 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.
pyr_scaleFLOAT0.500.1–0.9Pyramid scale between levels (<1); 0.5 halves the resolution at each level.
levelsINT31–10Number of pyramid levels (1 = no pyramid).
winsizeINT153–101Averaging window size; larger = more robust to noise but blurrier flow.
iterationsINT31–20Iterations at each pyramid level.
poly_nINT53–11Neighborhood size for the polynomial expansion (5 or 7 are typical).
poly_sigmaFLOAT1.20.3–3Gaussian sigma of the polynomial expansion (~1.1 for poly_n=5, ~1.5 for poly_n=7).
windowCOMBObox (faster)Averaging window type; gaussian is slower but yields smoother flow.

Outputs (3)

NameTypeDescription
flowNPARRAYHxWx2 float32 (dx, dy) displacement per pixel.
magnitudeNPARRAYHxW float32 motion magnitude in pixels.
angleNPARRAYHxW float32 motion direction in RADIANS - feed 'CV Flow To Color' in its default radians mode.