Color Correction | akatz-loops
Adaptive color correction that won't nuke already-vivid images
- image
- IMAGE
ColorCorrection | akatz-loops is a post-processing node that tries to fix washed-out images without wrecking the ones that are already fine. It measures how saturated an image actually is, boosts color only when it's below a threshold, and can optionally nudge the white balance - the "adaptive" in the name is the load-bearing word. It's deterministic, cheap, and needs no model, which puts it squarely in the "do it in pixels, not in another diffusion pass" category the KB's post-processing essay keeps telling you to reach for.
Inputs and outputs
- image (IMAGE) - the input, processed per batch image.
- saturation_threshold (FLOAT, default 0.4) - the measured-saturation line below which correction kicks in. Above it, the image passes through untouched.
- max_saturation_factor (FLOAT, default 1.3) - the ceiling on how much the boost can multiply saturation, so a barely-washed image can't get nuked into neon.
- enable_white_balance (BOOLEAN, default false) - opt-in white balance pass.
- white_balance_scale_min / white_balance_scale_max (FLOAT, defaults 0.97 / 1.03) - the clamp range for how far each channel's average can be pulled toward the mean intensity.
- output - a single IMAGE.
Under the hood it measures mean saturation in HLS space, applies the boost as saturation × min(threshold / measured, max_factor), and does the white balance by scaling each channel's average toward the overall mean, clamped to the scale range. Sensible, conservative defaults - most of the time you can leave everything but image alone.
When you'd use it
Where it shines is batch consistency: run a batch of generated frames through it and the flat, desaturated ones get pulled up while the already-colorful ones aren't touched, so you don't get the "every frame looks the same after the correction" problem a blunt saturation slider causes. It's a natural fit at the end of a loop's body or before a preview. And it pairs with the pack's sharpening and the standalone adaptive sharpener if you want the whole "make it pop" pass in one place.
Installing it
Part of the Akatz-Loop-Nodes pack (repo ComfyUI-Execution-Inversion), which is the pack that pulls in the opencv-python dependency this node uses:
cd ComfyUI/custom_nodes
git clone https://github.com/akatz-ai/ComfyUI-Execution-Inversion
# restart ComfyUI
Or ComfyUI Manager → "Akatz-Loop-Nodes". No model files; opencv-python is the only pip dependency.
Gotchas
The white balance is off by default and the two scale widgets are clamps, not intensities - the default 0.97/1.03 range is deliberately tight, so if you flip white balance on and see nothing happen, that's the range being conservative, not a bug. Also note it works in HLS, so hue stays put while only saturation moves; if an image reads "dull" because of contrast rather than saturation, this node won't fix it - that's a different tool.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| saturation_threshold | FLOAT | 0.400–1 | — |
| max_saturation_factor | FLOAT | 1.31–2 | — |
| enable_white_balance | BOOLEAN | false | — |
| white_balance_scale_minopt | FLOAT | 0.970.8–1 | — |
| white_balance_scale_maxopt | FLOAT | 1.031–1.2 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |