Optical Flow Direction Mask β‘π ‘π π £π
Mask only the pixels moving a specific way
- masks
- images
- MASK
Most motion-masking tools give you "moving vs. not moving." This one is fussier, in a useful way - it masks only the pixels moving in a specific direction. Point it at footage of a crowd and isolate just the people walking left, or point it at a spinning object and mask only what's rotating clockwise. Under the hood it's the same optical-flow analysis behind MotionFeatureNode and OpticalFlowParticleSystem elsewhere in this pack, just aimed at producing a mask instead of a number or a particle trail.
How it works
flow_method picks the algorithm - Farneback (dense, the safe general default), LucasKanade/PyramidalLK (sparse point tracking, faster but can miss motion in flat, low-texture regions), or DIS (a modern dense method tuned for speed). flow_threshold and magnitude_threshold filter out weak or noisy motion before it's considered at all.
direction is the whole point of this node, and it's more than left/right: horizontal and vertical cover straight-line motion, but radial_in/radial_out catch things moving toward or away from the frame center (a zoom, or something approaching/receding), and clockwise/counterclockwise catch rotational motion around the center. angle_threshold (default 45Β°) is the tolerance - how far a pixel's motion angle can deviate from your target direction and still count. blur_radius softens the resulting mask edges so you don't get a jagged, pixel-exact cutout.
This node requires an existing masks input too - not optional - combined with the shared strength/invert/subtract_original/grow_with_blur controls you'll see across this pack's mask-processing nodes. If you just want the raw direction analysis over the whole frame with nothing subtracted, feed it a plain white mask.
The inputs and outputs that matter
images(required,IMAGE) - the sequence to compute flow from.masks(required,MASK) - the base mask this refines; use an all-white mask to consider the whole frame.direction- horizontal / vertical / radial_in / radial_out / clockwise / counterclockwise.angle_threshold(default 45Β°) - how strict the direction match is.blur_radius(default 3) - edge softening.strength,invert,subtract_original,grow_with_blur- the pack's standard mask post-processing set.
Output is a single MASK.
How to install it
ComfyUI Manager: search "RyanOnTheInside", install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/ryanontheinside/ComfyUI_RyanOnTheInside
cd ComfyUI_RyanOnTheInside
pip install -r requirements.txt
then restart. Optical flow runs on OpenCV, pinned in requirements.txt - no model download, but if your pack install didn't complete cleanly, this is one of the nodes most likely to fail at load rather than at runtime.
Common issues & troubleshooting
Mask comes back empty even though there's obvious motion in the right direction. Loosen angle_threshold first - 45Β° sounds generous, but real-world motion (a walking gait, a hand gesture) rarely moves in a perfectly straight line, and a strict threshold can reject most of it. Also double-check flow_threshold/magnitude_threshold aren't filtering the motion out before direction is even evaluated.
Rotational directions (clockwise/counterclockwise) never trigger. Those depend on motion actually curving around the frame center - if your subject is off to one side rather than centered, or the rotation is around a point far from frame-center, this direction analysis won't line up with what you're picturing. It's evaluating rotation relative to the image center, not relative to your subject.
Result looks jagged at the edges. Raise blur_radius - the raw direction match is a per-pixel binary decision, and without smoothing it can look harsh, especially on noisy footage.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| masks | MASK | Input mask or sequence of masks to be processed (MASK type) | |
| strength | FLOAT | 1.000β1 | Overall strength of the mask effect (0.0 to 1.0) |
| invert | BOOLEAN | false | When enabled, reverses the mask output |
| subtract_original | FLOAT | 0.000β1 | Amount of the original mask to subtract from the result (0.0 to 1.0) |
| grow_with_blur | FLOAT | 0.00β10 | Amount of Gaussian blur to apply for mask growth (0.0 to 10.0) |
| images | IMAGE | Sequence of images to calculate optical flow from (IMAGE type) | |
| flow_method | COMBO | Algorithm used to calculate optical flow ('Farneback', 'LucasKanade', 'PyramidalLK') | |
| flow_threshold | FLOAT | 0.100β1 | Minimum flow magnitude to consider (0.0 to 1.0) |
| magnitude_threshold | FLOAT | 0.050β1 | Relative threshold for flow magnitude as fraction of maximum (0.0 to 1.0) |
| direction | COMBO | Direction of motion to detect ('horizontal', 'vertical', 'radial_in', 'radial_out', 'clockwise', 'counterclockwise') | |
| angle_threshold | FLOAT | 450β180 | Maximum angle deviation from target direction (0.0 to 180.0 degrees) |
| blur_radius | INT | 30β20 | Amount of smoothing applied to the mask (0 to 20 pixels) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | β |