Extensions/ComfyUI-FlowDenoise
ComfyUI Extension

ComfyUI-FlowDenoise

Professional motion-compensated temporal video denoising for ComfyUI ? AIMZ GFX Division

By AIMZ-GFX·Created 5 months ago·Updated about a month ago· 44
AIMZ-GFX/ComfyUI-FlowDenoise
Nodes4
On cloudLocal install
CategoryFlowDenoise
Stars44
Updatedabout a month ago
Readme
<img width="4000" height="1080" alt="Image" src="https://github.com/user-attachments/assets/b9dc18c0-a08d-4cb6-8ea5-e0e713e26949" />

Developed by AIMZ GFX Division

ComfyUI-FlowDenoise

Professional motion-compensated temporal video denoising for ComfyUI.

FlowDenoise leverages state-of-the-art optical flow estimation (MEMFOF / RAFT) to align neighboring frames, then separates and removes chroma and luma noise with independent per-channel control. Purpose-built for suppressing AI-generated video artifacts including color flicker, chroma spikes, and temporal noise patterns.

Demo Video

<video src="https://github.com/user-attachments/assets/6fc3cc87-5e5c-425c-9bc6-c4711ef8b53b](https://github.com/user-attachments/assets/6fc3cc87-5e5c-425c-9bc6-c4711ef8b53b" autoplay loop muted playsinline></video>

Full Demo Video https://www.youtube.com/watch?v=Z1o1tuOBPQ0

Features

  • Optical flow alignment via MEMFOF (state-of-the-art 2025) or RAFT models
  • Batched inference pipeline with GPU sliding-window buffer for high-VRAM GPUs (RTX 30/40/50 series)
  • Long-clip friendly — vectorized scene detection + optional weight-map output (off by default) keeps CPU RAM flat on multi-thousand-frame HD sources
  • Chroma / Luma separation with independent denoising strength per channel
  • Multiple color spaces: YCbCr, HSV, LAB
  • Noise visualization: heatmap, signed (red/blue), and grayscale preview modes
  • Scene-aware processing: automatic scene change detection prevents cross-scene blending artifacts
  • Source color tag preservationMatchSourceColorTags helper node fixes the classic VHS_VideoCombine color-shift on untagged AI-generated sources

Installation

Via ComfyUI-Manager (Recommended)

Search for ComfyUI-FlowDenoise in ComfyUI-Manager and install.

Manual Installation

cd ComfyUI/custom_nodes
git clone https://github.com/AIMZ-GFX/ComfyUI-FlowDenoise.git

Dependencies

The memfof package is not on PyPI and must be installed from GitHub:

pip install git+https://github.com/msu-video-group/memfof.git

ComfyUI Portable users must use the embedded Python:

python_embeded\python.exe -m pip install git+https://github.com/msu-video-group/memfof.git

If installed via ComfyUI-Manager, requirements.txt and install.py will handle this automatically.

The MEMFOF optical flow model (egorchistov/optical-flow-MEMFOF-Tartan-T-TSKH) is automatically downloaded from HuggingFace on first use.

RAFT models (raft_small, raft_large) are provided via torchvision and require no additional installation.

Nodes

Temporal Flow Average

Motion-compensated temporal averaging using optical flow.

Aligns neighboring frames to the current frame using dense optical flow estimation, then computes a weighted average to produce a clean temporal reference. Frames further in time receive lower weight via exponential decay. Scene boundaries are automatically detected to prevent cross-cut blending.

| Parameter | Default | Description | |-----------|---------|-------------| | window_size | 2 | Number of frames to average on each side (total window = 2n+1) | | weight_decay | 0.8 | Exponential decay for temporal weights (lower = more aggressive averaging) | | flow_model | memfof | Optical flow model: memfof, raft_small, raft_large | | flow_iterations | 8 | Number of flow refinement iterations | | color_threshold | 0.04 | Per-pixel color difference threshold for outlier rejection | | scene_threshold | 0.06 | Scene change detection threshold (mean frame difference) | | batch_size | 1 | MEMFOF batch size (higher = faster but more VRAM) | | precision | bf16 | bf16 (RTX 30/40/50, ~1.5–2× faster) or fp32 (strict reproducibility) | | flow_scale | 1.0 | Flow at reduced resolution for speed. 0.5 = ~3× faster; warping stays at full res | | output_weight_map (optional) | false | Return the confidence weight map as the second output. Off by default — enabling it allocates a full-size (B×H×W×3) tensor at end of run; skip unless a downstream node consumes it |

Outputs:

  • clean -- Temporally averaged (denoised) frames
  • weight_map -- Per-pixel confidence weights (or a 1×1×1×3 placeholder when output_weight_map is off)

Extract Noise (Chroma/Luma)

Extracts and visualizes the noise difference between original and clean frames, separated into chroma and luma components. Useful for diagnostics and tuning denoising parameters.

| Parameter | Default | Description | |-----------|---------|-------------| | noise_amplify | 5.0 | Amplification factor for noise visualization | | color_space | YCbCr | Color space for chroma/luma separation: YCbCr, HSV, LAB | | noise_preview | heatmap | Visualization mode: heatmap (turbo colormap), signed (red=positive, blue=negative), gray (classic grayscale) |

Outputs:

  • noise_total -- Combined noise visualization (all channels)
  • noise_chroma -- Chroma noise only
  • noise_luma -- Luminance noise only

Selective Denoise

Selectively blends original and clean frames with independent chroma/luma control in the chosen color space. This is where the final denoising balance is set.

| Parameter | Default | Description | |-----------|---------|-------------| | chroma_strength | 0.8 | Chroma denoising strength (0=keep original, 1=fully clean) | | luma_strength | 0.3 | Luma denoising strength (0=keep original, 1=fully clean) | | color_space | YCbCr | Color space for separation: YCbCr, HSV, LAB | | clamp_output | true | Clamp output values to [0, 1] |


Match Source Color Tags

Post-processes a VHS_VideoCombine output to rewrite its color atoms (colr) and h264 VUI so downstream tools (Nuke / Premiere / DaVinci) apply the same color matrix they used on the original source. No re-encoding — ffmpeg -c copy remux with the h264_metadata bitstream filter.

Fixes the classic VHS symptom on untagged AI-generated content (Seedance, Kling, Dreamina, etc.): source has no color tags, but VHS_VideoCombine stamps bt709 into the output by default. Downstream tools read the output as bt709 and the source as bt601 (untagged heuristic), producing an artificial midtone shift — commonly reported as "denoise changed my colors" when the RGB numerics are actually unchanged.

| Parameter | Default | Description | |-----------|---------|-------------| | source_video_path | (empty) | Original source path — ffprobe reads its color tags for reference | | denoised_video_path | (empty) | VHS_VideoCombine output path — this file's tags get rewritten | | mode | match_source | match_source (mirror source tags; strip if source untagged), strip_all (unspecified everywhere — matches untagged sources), force_bt709 (stamp bt709/tv regardless) | | output_suffix | _colorfixed | Suffix appended to the fixed file. Empty = atomic in-place replace |

Outputs:

  • fixed_path -- Path to the tag-corrected file

Workflow

An example workflow is included in workflow_example.json. The standard pipeline:

LoadVideo -> Temporal Flow Average -> Extract Noise (preview)
                                   -> Selective Denoise -> Save Video
                                                        -> Match Source Color Tags (optional)
  1. Load Video -- Import your video with VHS_LoadVideo
  2. Temporal Flow Average -- Align and average neighboring frames to create a clean reference
  3. Extract Noise -- (Optional) Visualize what noise is being removed
  4. Selective Denoise -- Blend original and clean with independent chroma/luma control
  5. Save Video -- Export with VHS_VideoCombine
  6. Match Source Color Tags -- (Optional but recommended for untagged AI sources) Fix VHS-imposed color tags to match the original

Recommended Settings

AI-Generated Video (Seedance, Kling, etc.)

Chroma flicker and color spikes common in AI video generators:

Temporal Flow Average:
  window_size: 2-3
  weight_decay: 0.7
  flow_model: memfof
  batch_size: 8-16 (RTX 5090 32GB, 720p)

Selective Denoise:
  chroma_strength: 0.7-0.9
  luma_strength: 0.1-0.3
  color_space: YCbCr

Film Grain Removal

Subtle grain in live-action footage:

Temporal Flow Average:
  window_size: 3-5
  weight_decay: 0.6
  flow_model: memfof

Selective Denoise:
  chroma_strength: 0.5-0.7
  luma_strength: 0.3-0.5
  color_space: LAB

Chroma-Only Cleanup

Remove color noise while preserving all luminance detail:

Selective Denoise:
  chroma_strength: 0.9
  luma_strength: 0.0

How It Works

  1. Optical Flow Estimation: MEMFOF computes dense motion vectors between adjacent frames
  2. Frame Alignment: Neighboring frames are warped to match the current frame's viewpoint using the estimated flow
  3. Weighted Averaging: Aligned frames are averaged with exponential temporal decay and per-pixel outlier rejection
  4. Color Space Separation: The noise (original - clean) is decomposed into chroma and luma components
  5. Selective Blending: Original and clean frames are blended with independent control per component

This purely mathematical approach requires no training, works on any video content, and produces deterministic results.

Workflow Example

<img width="4077" height="3009" alt="Image" src="https://github.com/user-attachments/assets/8fe3f59e-2b68-459b-9074-ddc31c1b2f4a" />

License

MIT License. See LICENSE for details.

Note: This project depends on the MEMFOF optical flow model. Please verify the MEMFOF model license for your intended use case.

Acknowledgments


Changelog

v1.0.0 — Formal release

  • New node: Match Source Color Tags — post-processes VHS_VideoCombine output to fix its color atoms (colr) + h264 VUI so downstream tools (Nuke / Premiere) use the same color matrix as the original source. No re-encoding. Fixes the classic VHS bt709 shift on untagged AI-generated content.
  • Long-clip memory fixTemporal Flow Average no longer allocates the full-size weight map + 3-channel visualization by default. The old always-on behavior spiked CPU RAM by tens of gigabytes on multi-thousand-frame HD clips (8000 × 1080p ≈ +65 GB), tripping the DefaultCPUAllocator OOM. New optional output_weight_map input (default off) lets workflows that actually consume the weight map keep the old behavior.
  • Vectorized scene detection — replaced the per-frame .item() sync loop with a single batched MSE reduction. The old loop serialized the whole pre-processing pass against the CPU on long clips.
  • Better memory hygiene — intermediate tensors (output, frames) are freed as soon as the final BHWC result is materialized, so the peak-memory point during torch.cuda.empty_cache() at the end of the run is now the actual output tensor size instead of ~4× it.

Previous — Performance Update

  • Temporal Flow Average now runs significantly faster on modern GPUs (RTX 30/40/50 series).
    • Added precision option (bf16 / fp32, default bf16) — uses bfloat16 autocast for optical flow inference, ~1.5–2× faster with negligible quality difference.
    • Added flow_scale option (1.0 / 0.75 / 0.5, default 1.0) — computes optical flow at reduced resolution for additional speedup. Warping still uses full resolution. 0.5 is fastest (~3× extra), 0.75 is a balanced choice.
    • Combined defaults are backward-compatible; for maximum speed try precision=bf16 + flow_scale=0.5.

Developed by AIMZ GFX Division