Color Correction + Sharpening | akatz-loops
One Stop for the Two Post-Process Passes You Keep Re-Adding
- image
- IMAGE
If you've ever chained a saturation boost into a sharpening node because every render comes out slightly washed-out and slightly soft, this node is that chain fused into one. ColorCorrectionAndSharpening takes an image, fixes the color if it's washed out, sharpens it if it's soft, and hands back one IMAGE - with booleans so you can turn either half off without rewiring. It's the pack's combined stop for the two most common "make the output look finished" passes.
The color half is the interesting bit and it's genuinely adaptive: the node measures the image's average saturation (in HLS space), and only if it's below a threshold does it do anything. A punchy render passes through untouched; a washed-out one gets its saturation boosted by a factor proportional to how far below the threshold it fell, capped at max_saturation_factor. That's a "correct only when needed" behavior, which is why the same node can sit in a batch loop producing consistent-looking output across wildly different inputs.
The inputs that matter
- image - IMAGE in, batch-friendly; every frame gets the same treatment.
- enable_color_correction (default
true) / enable_sharpening (defaulttrue) - the two on/off switches. Turn one off and the node behaves like just the other, which makes it a useful single slot that can do either job depending on how you set it. - saturation_threshold (default
0.4) - the "is this washed out?" line. Lower it and fewer images get corrected; raise it and correction kicks in more eagerly. - max_saturation_factor (default
1.3, up to 2) - the ceiling on how hard saturation gets boosted. 1.3 is mild; pushing toward 2 risks neon. - sharpening_intensity (default
0.7) and sharpening_radius (default1.1) - the unsharp-mask pair, same as the pack's standaloneAdaptiveSharpening.
The optional trio - enable_white_balance (default false), white_balance_scale_min/max (defaults 0.97/1.03) - is off until you want it. When enabled, the node scales each channel toward the mean intensity so a cold or warm cast gets pulled to neutral, clamped to those two bounds. It's a gentle auto-white-balance; leave it off for stylized looks where the "cast" is the point.
Where it fits
Post-processing, full stop - the "everything after the sampler" layer that should cost milliseconds, not diffusion passes. The real appeal here is batch/loop consistency: one node with one set of settings gives every frame the same treatment, and the threshold behavior means it won't over-correct frames that were already fine. If you're tuning, start with both toggles on and the defaults; you'll rarely need to touch more than saturation_threshold.
Install
Ships in Akatz-Loop-Nodes (akatz-ai). Via ComfyUI Manager, search "Akatz-Loop-Nodes"; or:
cd ComfyUI/custom_nodes
git clone https://github.com/akatz-ai/Akatz-Loop-Nodes
Restart ComfyUI. This node genuinely needs the pack's one dependency, opencv-python (the saturation/white-balance work is cv2), which Manager installs for you. No models to download.
Main thing to watch: with both toggles on, saturation_threshold and max_saturation_factor interact, so a "too colorful" result is usually the factor, and a "nothing changed" result is usually the threshold sitting above your image's saturation. Nudge the threshold down first.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| enable_color_correction | BOOLEAN | true | — |
| enable_sharpening | BOOLEAN | true | — |
| saturation_threshold | FLOAT | 0.400–1 | — |
| max_saturation_factor | FLOAT | 1.31–2 | — |
| sharpening_intensity | FLOAT | 0.70–2 | — |
| sharpening_radius | FLOAT | 1.10.1–3 | — |
| enable_white_balanceopt | 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 | — |