Video Frame Consistency
The fix for flicker, color drift, and softness in long clips
- image
- ref_image
- image
Long video generation has a dirty secret: the model doesn't generate your whole clip at once. It slides a fixed-size context window (81 frames, say) across the timeline, generating each window conditioned on the previous one. That works, but each window is a fresh roll of the dice - so your finished video ends up with three classic artifacts: color that shifts between sections, flicker at the seams, and progressive softness in the later windows. Video Frame Consistency is the post-processing pass that scrubs all three out.
What it does
You feed it your frame batch and it runs a stack of independent, individually-togglable corrections. This is not one magic setting - it's five techniques you switch on and off to taste:
- Section Normalise - aligns the color mean and standard deviation of each context window to the first window. This is the big one for "the whole second half went blue-green."
- Histogram Match - matches each frame's per-channel histograms to a reference frame, so brightness and color distribution stay locked.
hist_strengthblends it (0 = nothing, 1 = full match, default 0.6) - full match can flatten a video, so the blend is there to let you back off. - Luminance Normalise - corrects brightness drift in the LAB L-channel only. Because it leaves hue and chroma alone, it fixes "gets darker over time" without washing out color.
- Temporal Smooth - blends each frame with its neighbors using Gaussian weights. The anti-flicker button.
temporal_radiuscontrols how many frames on each side participate. - Sharpen Recover - applies a progressively stronger unsharp mask to later frames, since windows generated further along the timeline tend to lose sharpness.
sharpen_basesets the starting strength andsharpen_rampadds a little per frame.
The inputs that matter
image is the frame batch. window_size (default 81) tells Section Normalise how big the generation windows were - set it to match your pipeline (81 for WAN 5s @ 16fps), because the node groups frames into sections based on it. reference_frame picks which frame is the color/quality target (default 0 = first frame). And there's a ref_image optional input: connect your original input image and every technique uses that as the target instead of a frame from the batch, which is the right call for image-to-video - you want the output to match your source, not just the first generated frame.
Output is image, a list of corrected frames - wire it into Save Video. It's designed for WAN and CogVideo pipelines specifically, but the techniques are model-agnostic; any sliding-window generator can benefit.
The honest take
This node is a band-aid applied after generation, and it's a good one - but if your pipeline has huge cross-window drift, the real fix is upstream (longer context, better conditioning, proper first-frame continuity). For the common case of "81-frame windows, mild drift, a little flicker," this makes a genuinely unwatchable clip watchable in one pass. Start with Section Normalise and Histogram Match on, sharpen off; add sharpen only if later windows are visibly soft, and use hist_strength around 0.5–0.7 rather than 1.0.
Install it
Ships in ComfyUI_Eclipse. ComfyUI Manager → search "Eclipse" → Install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/r-vage/ComfyUI_Eclipse
Standard deps (opencv-python, pilgram, PyYAML, aiohttp; portable installs may need pip install -r custom_nodes/ComfyUI_Eclipse/requirements.txt). It's under Eclipse → Video.
Gotchas
If window_size doesn't match your actual generation windows, Section Normalise will group frames wrongly and can introduce seams instead of removing them. When in doubt, set window_size to the frames-per-context your sampler actually used. And don't run temporal smoothing with a large radius on fast-moving footage - you'll get motion ghosting; that's the classic "why is everything smeared" moment. Small radius, small effect, verify on a test clip.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Batch of video frames (N, H, W, 3). | |
| window_size | INT | 811–512 | Frames per context window used during generation (e.g. 81 for WAN 5 s @ 16 fps). Used by Section Normalise. |
| reference_frame | INT | 00–4096 | Index of the frame used as the colour/quality reference (0 = first frame). Used by Histogram Match and Luminance Normalise when no ref_image is connected. |
| section_normalise | BOOLEAN | true | Align the colour mean and std-dev of each window to the first window. Corrects large cross-section shifts. |
| hist_match | BOOLEAN | true | Match per-channel histograms of every frame to the reference frame. |
| hist_strength | FLOAT | 0.600–1 | Blend factor: 0 = no change, 1 = full histogram match. |
| luminance_normalise | BOOLEAN | true | Correct brightness drift in LAB L-channel only, preserving hue and chroma. |
| temporal_smooth | BOOLEAN | false | Reduce per-frame flicker by blending each frame with its neighbours using Gaussian weights. |
| temporal_radius | INT | 11–8 | Number of neighbour frames on each side to include in the temporal blend. |
| sharpen_recover | BOOLEAN | false | Apply progressively stronger unsharp mask to later frames to recover sharpness lost across generation windows. |
| sharpen_base | FLOAT | 0.300–2 | Base unsharp-mask strength applied from frame 0. |
| sharpen_ramp | FLOAT | 0.0030–0.05 | Additional sharpening strength added per frame index (0.003 ≈ +0.24 over 81 frames). |
| ref_imageopt | IMAGE | Optional reference image (e.g. the original input image). When connected, all methods use this as the colour/sharpness target instead of a frame from the batch. Frame 0 is also corrected. When disconnected, reference_frame selects the batch frame to use. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |