Color Match LAB
Hold your palette across 200 frames
- image
- reference
- image
Every Deforum-style feedback loop eventually turns to neon. Run low-denoise img2img for 20–30 frames and the palette starts walking - reds pool, greens drop, and by frame 150 you're staring at acid. It's been a known failure mode of iterative img2img since basically day one (the classic thread title is literally "img2img applied iteratively eventually turns purple?"), and the community-standard fix has always been the same: histogram-match each frame against a stable reference. That's exactly what Color Match LAB does, cleanly, in pure torch.
How it works
It's a per-frame histogram color match: instead of matching just the mean and standard deviation like a lazy matcher would, it remaps the full per-channel distribution of the current frame to the reference's. That holds the whole palette, not just the average - which is the difference between "colors stay in the right neighborhood" and "the scene keeps its actual look."
It runs in LAB by default, and the LAB space is the smart choice here: luminance and chroma are separated, so you can match color while keeping the frame's own detail and brightness. HSV and RGB are the alternatives - HSV is harsher, RGB matches brightness too. The math is a clean-room reimplementation of Deforum's own maintain_colors, and the node is stateless: no hidden accumulation, no surprise state to reset.
Inputs that matter
image- the frame to recolor (your current loop frame).reference- the palette source. Feed it the frame-0 init image and you get a locked palette for the whole animation.color_space-LAB(default),HSV, orRGB.strength- 0 to 1, how hard to pull toward the reference. Schedulable, which is the trick: ramp it in (say 0 → 0.7 over the first frames) instead of slamming it on before the scene has formed.preserve_luminance- keep the frame's own brightness and match color only. On by default in spirit; flip it if you want the reference's brightness to win.
Output is a single image, straight back into the loop's latent/VAE path.
The honest caveats
It's a color stabilizer, not an injector. Matching to a fixed reference holds a palette but cannot create new prompt colors - if the scene is supposed to shift from golden hour to night, this node fights you, and you want the sibling Rolling Color Match node instead. And a dark or dull reference will pin you to a dark, dull loop: matching can't enrich a bad palette, so bootstrap with a rich image and the whole animation inherits its colors. The other trap is over-reliance - preserve_luminance only saves brightness on the color axis; if your loop is darkening because denoise/luminance is degrading, this node won't stop that, and that's a different fix.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Statistical-Impossibility/comfyui-Stat-Imp-nodes
Pure torch, zero extra Python dependencies, no model downloads. The node appears under Stat-Imp / Deforum / Color after a restart and hard-refresh. To use it in a real loop you'll also want the pack's fork of the Deforum harness (https://github.com/Statistical-Impossibility/deforum-comfy-nodes) - the shipped example workflow depends on it, and it's how the frame-0 reference gets threaded into the loop in the first place.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| reference | IMAGE | — | |
| color_space | COMBO | 3 options: LAB, HSV, RGB | |
| strength | FLOAT | 1.000–1 | — |
| preserve_luminance | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |