CV Optical Flow (DIS)
DIS is the dense-flow node you should reach for first
- frame_a
- frame_b
- init_flow
- flow
- magnitude
- angle
If you only install one optical-flow node from this pack, install this one. Dense Inverse Search is the modern replacement for Farneback: it matches small patches coarse-to-fine, propagates the winners to their neighbors, then runs a variational refinement pass over the result. In practice that means noticeably sharper motion boundaries and it's faster than Farneback at comparable quality. The old thing got beaten on both axes at once, which is rare enough to be worth knowing.
It's also a cv2 class (DISOpticalFlow), so no raw wrapper in the pack can reach it - the generated cv2_* nodes only cover top-level functions, and factories like this one are exactly what the hand-written nodes exist for.
How it works, and the three knobs that matter
Frames go in as frame_a and frame_b (polymorphic: IMAGE or MASK directly, frame 0 of a batch, or an NPARRAY). Both are converted to grayscale, and frame_b is resized to frame_a if the sizes differ. The flow runs from a to b, so order matters.
preset picks the speed/quality starting point - ultrafast through medium - and it sets the finest scale, patch size and stride, and the iteration counts all at once. The other parameters default to -1, and -1 is a real value: it means "leave whatever the preset chose". That's the design, and it's a good one, because it means you can't accidentally write a garbage parameter into an otherwise-fine preset. Override only what you've measured a need for:
refinement_iterations-0switches the variational refinement off entirely, giving you the rawer, blockier patch flow. That's how you tell whether the refinement is helping or hallucinating smoothness.init_flow- the previous frame pair's flow, passed in to warm-start a video sequence. This is the single biggest quality win for video: large motions converge far better when the solver starts near the answer. The node copies the array, so an upstream cached output is never modified.finest_scale-0computes the full resolution (sharpest, slowest), higher levels blur and speed up.
Advanced: patch_size, patch_stride, spatial_propagation (seed each patch from its already-solved neighbour - almost always worth it), and mean_normalization (normalize patch means, making the match robust to brightness changes).
Outputs
flow (HxWx2 float32, the (dx, dy) per pixel), magnitude (HxW float32, motion in pixels), and angle (HxW float32, direction in radians - exactly what CV Flow To Color takes by default). Same trio every flow node in this pack emits, so you can swap algorithms without rewiring.
Install
Manager → search 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 afterwards. Python ≥ 3.12 and a V3-API ComfyUI. DIS itself is in the core cv2 (not contrib), so even a plain wheel would expose it - but the pack as a whole wants the contrib wheel, and the pinned version is the one the behavior is curated against.
Common issues
- Flow looks blocky and stepped - you probably zeroed
refinement_iterations, or you're onultrafast. Check the preset before blaming the algorithm. - Big motions come out as garbage - that's the classic dense-flow failure, and the fix is
init_flow, not more iterations. - You set a parameter and nothing changed - if you left it at
-1that's intended; also note several of these only take effect when the preset didn't already pin them. - cv2 import errors on a Windows portable build - the mixed-OpenCV-wheel problem other ComfyUI users report, where one pack's
opencv-pythoninstall breaks every cv2-based node at once.tools/repair_opencv_contrib.py --checkin the pack will tell you whether contrib survived.
One honest caveat: this pack's README says it was built with heavy LLM assistance, isn't production-ready, and gets updates whenever the author feels like it. The curated nodes are useful; don't treat them as maintained infrastructure.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| frame_a | NPARRAY,IMAGE | First frame (earlier in time); 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_b | NPARRAY,IMAGE | Second 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. | |
| preset | COMBO | medium (most accurate) | Speed/quality preset; it presets finest_scale, patch size/stride and the iteration counts. 'ultrafast' is real-time-video fast, 'medium' is the best quality. |
| finest_scale | INT | -1-1–6 | Finest pyramid level actually computed. -1 keeps the preset's value. 0 = full resolution (sharpest and slowest); raising it blurs and speeds up. |
| gradient_iterations | INT | -1-1–100 | Gradient-descent iterations per patch. -1 keeps the preset's value; more = more accurate, slower. |
| refinement_iterations | INT | -1-1–100 | Variational refinement iterations run after the patch search. -1 keeps the preset's value; 0 turns the refinement off entirely (rawer, blockier flow). |
| init_flowopt | NPARRAY | Optional HxWx2 flow to start from - pass the previous frame pair's flow when processing a video. It is copied, never written to, so the upstream node's cached array is safe. | |
| patch_sizeopt | INT | -1-1–64 | Side of the matched patch in pixels. -1 keeps the preset's value (8 is the usual). |
| patch_strideopt | INT | -1-1–32 | Spacing between patches. -1 keeps the preset's value; smaller = denser and slower. |
| spatial_propagationopt | BOOLEAN | true | Seed each patch from its already-solved neighbour. Almost always worth it - the main reason DIS beats a plain patch search. |
| mean_normalizationopt | BOOLEAN | true | Normalise patch means before matching, which makes the match robust to brightness changes between frames. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| flow | NPARRAY | HxWx2 float32 (dx, dy) displacement per pixel. |
| magnitude | NPARRAY | HxW float32 motion magnitude in pixels. |
| angle | NPARRAY | HxW float32 motion direction in RADIANS - feed 'CV Flow To Color' in its default radians mode. |