Nodes/RyanOnTheInside/Optical Flow Mask Modulation βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
ComfyUI Node

Optical Flow Mask Modulation βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜

A mask that follows motion, without hand-rotoscoping every frame

By ryanontheinsideΒ·Created 2 years agoΒ·Updated 5 months agoΒ· 852
Optical Flow Mask Modulation βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
  • masks
  • images
  • MASK
β—„strength1.00β–Ί
β—„invertfalseβ–Ί
β—„subtract_original0.00β–Ί
β—„grow_with_blur0.0β–Ί
β—„flow_methodβ–Ύβ–Ί
β—„flow_threshold0.10β–Ί
β—„magnitude_threshold0.05β–Ί
β—„modulation_strength1.0β–Ί
β—„blur_radius5β–Ί
β—„trail_length5β–Ί
β—„decay_factor0.80β–Ί
β—„decay_styleβ–Ύβ–Ί
β—„max_thickness20β–Ί

This one's a different shape from the Flex family, despite living conceptually next to it: it doesn't take a FEATURE input at all. Instead, it computes its own motion signal directly from your frame sequence using optical flow - the classic computer-vision technique for tracking how pixels move between consecutive frames - and uses that to modulate a mask you feed in. Give it a video and a base mask, and it can grow, reveal, or leave a decaying trail behind whatever's actually moving in the shot.

How it works

Pick a flow_method: Farneback (dense, a solid general-purpose default), LucasKanade or PyramidalLK (sparse point-tracking, better for large clean motions), or DIS (dense inverse search). The node computes flow between frames, filters it through flow_threshold and magnitude_threshold so small or noisy motion gets ignored, then turns the surviving flow magnitude into a modulation signal for your input masks. modulation_strength and blur_radius shape how strong and how smooth that signal is; subtract_original and invert control how it combines with your base mask.

The trail system is the more distinctive part: trail_length (1-20 frames) keeps a memory of recent motion, decay_factor controls how fast that memory fades, and decay_style decides whether the trail fades in opacity (fade) or shrinks in width (thickness, capped by max_thickness). That's what gets you a comet-tail effect behind a moving subject rather than just a mask that flickers on and off with the motion.

Inputs and outputs that matter

  • masks and images - the base mask and the frame sequence flow is computed from.
  • flow_method, flow_threshold, magnitude_threshold - how motion gets detected and filtered.
  • modulation_strength, blur_radius, strength - how hard and how smooth the effect lands.
  • trail_length, decay_factor, decay_style, max_thickness - the motion-trail behavior.
  • invert, subtract_original, grow_with_blur - how it composites with your input mask.

Output is a single MASK.

Where you'd use it

Auto-generating a mask that follows a moving subject - a dancer, a hand, a moving vehicle - without rotoscoping every frame by hand, then feeding that mask into a masked inpaint or composite step. The trail options are worth exploring separately for a stylized motion-streak look even outside a strict "follow the subject" use case.

Installing it

ComfyUI Manager: search RyanOnTheInside, install, restart. Manual:

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

Flow computation is OpenCV work (opencv-python is in this pack's requirements.txt) and it's CPU-bound - it can get slow on long or high-resolution clips, especially with the denser algorithms across many frames.

Where people get burned

With this many knobs, start simple: Farneback at modulation_strength = 1 before touching the decay/thickness controls. If the output mask comes back blank, flow_threshold or magnitude_threshold is almost always the culprit - they're probably set too high for your footage's actual motion scale, so turn them down first rather than assuming the node is broken. And this assumes a continuous shot: a hard cut or scene change between frames registers as a huge, spurious burst of "flow" since the algorithm has no idea it's not real motion - don't feed it a montage and expect a sane result at the cut points.

CategoryRyanOnTheInside/OpticalFlow

Inputs (15)

NameTypeDefaultDescription
masksMASKInput mask or sequence of masks to be processed (MASK type)
strengthFLOAT1.000–1Overall strength of the mask effect (0.0 to 1.0)
invertBOOLEANfalseWhen enabled, inverts the mask output (black becomes white and vice versa)
subtract_originalFLOAT0.000–1Amount of the original mask to subtract from the result (0.0 to 1.0)
grow_with_blurFLOAT0.00–10Amount of Gaussian blur to apply for mask growth (0.0 to 10.0)
imagesIMAGESequence of images to calculate optical flow from (IMAGE type)
flow_methodCOMBOAlgorithm used to calculate optical flow ('Farneback', 'LucasKanade', 'PyramidalLK')
flow_thresholdFLOAT0.100–1Minimum flow magnitude to consider (0.0 to 1.0)
magnitude_thresholdFLOAT0.050–1Relative threshold for flow magnitude as fraction of maximum (0.0 to 1.0)
modulation_strengthFLOAT1.00–5Intensity of the modulation effect (0.0 to 5.0)
blur_radiusINT50–20Amount of smoothing applied to the flow magnitude (0 to 20 pixels)
trail_lengthINT51–20Number of frames to maintain in the trail effect (1 to 20)
decay_factorFLOAT0.800.1–1Rate at which trail intensity decreases (0.1 to 1.0)
decay_styleCOMBOMethod of trail decay ('fade' or 'thickness')
max_thicknessINT201–50Maximum thickness of trails when using thickness decay (1 to 50 pixels)

Outputs (1)

NameTypeDescription
MASKMASKβ€”