AP Temporal Blend Images
Kill the flicker — blending your frame history so video stops shimmering
- image_1
- image_2
- image_3
- image_4
- image_5
- mask
- blended_images
- blend_mask
The #1 tell of an amateur AI video is flicker - the same subject, the same lighting, but the pixels dance between frames because each frame was sampled independently and the model couldn't keep its opinion straight. AP Temporal Blend Images is the stab at fixing that after the fact: it takes up to five frames of your history and blends them into one temporally-consistent frame, so any given pixel gets its value from a run of frames instead of one roll of the dice.
This is the companion to the loop nodes. The loop gives you access to the last 5 processed frames; this node gives you something useful to do with them. Wire processed_previous_image_1..5 from APLoopOpen into the blend's image_2..image_5 inputs, keep image_1 as your current frame, and out comes a steadier version.
The mechanism - pick your blend
Five blend_mode options, and they're not marketing fluff - each is a genuinely different statistical strategy:
weighted_mean- plain average weighted by recency. Fastest, the stable baseline. If motion or detail doesn't matter much, this is enough.similarity_weighted(default) - weights each history frame by how similar it is to the current frame. This is the one the README calls the "best default for flicker reduction": pixels that agree across frames get reinforced, pixels that disagree get suppressed.median- per-pixel median across frames. Brutal outlier suppression, which is what you want when a single frame has a sporadic artifact (a sparkle, a glitch).trimmed_mean- mean after dropping thetrim_ratio(default 0.2) most-extreme values. Softer than median, more robust than mean.robust_huber- Huber-weighted mean, adaptive; helps in unstable inpaint regions where you want to downweight large deviations without throwing them away entirely.
Two parameters shape all of them: recency_decay (default 0.35) controls how much more the recent frames count than old ones - higher = more forgetful; and similarity_sigma / robust_delta tune the respective modes' sensitivity. detail_preservation (0–1) blends a bit of the raw current frame back in so you don't wash out fine detail - the README's tip is to raise it when the blend gets too soft.
Mask-aware blending - the trick that prevents drift
The optional mask input is the important one. When connected, blending only happens inside the mask; outside it, output stays exactly at the current frame. That's how you stop the background from drifting into a blurry mush over a long sequence - you mask the region that's allowed to blend (the subject) and leave the static background frozen. The README's recommended temporal-inpaint setup is exactly this: loop one frame at a time, feed history frames in, blend_mode=similarity_weighted, recency_decay 0.25–0.45, mask-limited blending on.
Outputs: blended_images (the result) and blend_mask (which pixels actually got blended - a MASK, mostly useful for debugging or for feeding downstream nodes that want to know).
Installing it
Pack-wide install, same as the other nodes: ComfyUI Manager (search "AP_OpticalFlow"), or
cd ComfyUI/custom_nodes
git clone https://github.com/adampolczynski/ComfyUI_AP_OpticalFlow
python -m pip install -r custom_nodes/ComfyUI_AP_OpticalFlow/requirements.txt
then restart. torchvision>=0.15 is the only dependency.
The honest limits
Temporal blending is a compromise between stability and motion fidelity. Blend too much and motion trails, detail softens, and fast-moving subjects get ghost tails; blend too little and you're back to flicker. Start with similarity_weighted at the default decay and only reach for median when you can see specific sporadic artifacts. And remember this node blends whatever you feed it - if your input frames are badly misaligned (no flow warp), blending just averages misalignment into a double-exposure. Feed it flow-warped history, not raw frames.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image_1 | IMAGE | — | |
| blend_mode | COMBO | similarity_weighted | 5 options: weighted_mean, similarity_weighted, median, trimmed_mean, robust_huber |
| recency_decay | FLOAT | 0.350–4 | — |
| trim_ratio | FLOAT | 0.200–0.49 | — |
| similarity_sigma | FLOAT | 0.10000.0001–1 | — |
| robust_delta | FLOAT | 0.08000.0001–1 | — |
| detail_preservation | FLOAT | 0.200–1 | — |
| clamp_output | BOOLEAN | true | — |
| image_2opt | IMAGE | — | |
| image_3opt | IMAGE | — | |
| image_4opt | IMAGE | — | |
| image_5opt | IMAGE | — | |
| maskopt | MASK | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| blended_images | IMAGE | — |
| blend_mask | MASK | — |