ComfyUI Node

Clahe

Local contrast that pops without blowing out the image

By jkrauss82·Created 3 years ago·Updated a day ago· 9
Clahe
  • image
  • IMAGE
clip_limit1.0
grid_size_wh8

Your image came off the sampler looking flat. Midtones everywhere, no snap, like the model ran out of contrast budget. Before you re-roll the seed or throw an img2img pass at it, there's a deterministic, millisecond-scale fix for exactly this: CLAHE. It ships as a node in ULTools for ComfyUI, and for a two-knob filter it does a surprising share of the "make it pop" work people routinely burn a diffusion pass on.

CLAHE is Contrast Limited Adaptive Histogram Equalization, and the name is the whole recipe. Plain histogram equalization stretches an image's brightness distribution across the full range - a global contrast boost, but it flattens everything into that fake-HDR plastic look. The adaptive part splits the image into a grid of tiles and equalizes each tile against its own local histogram, which is what actually digs detail out of shadow and highlight regions. The contrast limited part is the guardrail: it caps how hard any one tile's histogram can stretch, so you get the local contrast without amplifying flat-area noise into grit. That cap is the difference between a CLAHE result and a mess.

Mechanically, this node keeps it clean. It converts the image to LAB color space, runs kornia's equalize_clahe on just the L (lightness) channel, leaves the a/b color channels untouched, and converts back. Contrast without color shift, which is exactly what you want for a final grade. One honest quirk: the code is pinned to torch CPU, with the GPU call sitting beside it commented out. That's fine for one output image - don't plan on CLAHE-ing a whole 4K batch per second.

The node is two knobs and that's all it is:

  • clip_limit - default 1.0. Higher values mean stronger local contrast, and along with it more visible noise. This is your "how much pop" dial.
  • grid_size_wh - default 8. The tile grid for the adaptive equalization. Smaller tiles = finer, more local detail; larger tiles drift toward a global effect.
  • image - any IMAGE socket, typically the VAE Decode output.

Output is a single IMAGE at the input size, so wire it into SaveImage, PreviewImage, or a sharpen pass right after. Two behaviors worth knowing: grid_size_wh=1 short-circuits and returns the image untouched, and on a genuine error the node prints UL TOOLS ERROR in the console and hands back the unprocessed image rather than crashing. Graceful - but if the node ever seems to do nothing, go read the log.

Install is shared across this pack:

cd ComfyUI/custom_nodes
git clone https://github.com/jkrauss82/ultools-comfyui
cd ultools-comfyui
pip install -r requirements.txt   # run inside ComfyUI's python env

Restart ComfyUI after. ComfyUI Manager users can try searching "ULTools" first; the manual clone always works. Here's the real trap: Clahe is one of three kornia-backed filters in the pack (with UnsharpMask and Histogram), and kornia itself is not in the pack's requirements.txt even though the code imports it at module load. If it's missing, the entire pack fails to register - not just this node. The fix is a single pip install kornia.

Where I'd actually reach for it: a big flat sky or wall that needs local depth, cleaning washed-out output into something dehazed-looking, and restoring the tonal snap that a heavy upscaler tends to flatten out. It's not magic. Past a clip_limit of roughly 3 you're mostly sharpening the noise, and if you see grain get crunchy that's the sign to back off. Start at the defaults, tick clip_limit up near 2, and judge on a preview - it's a cheap experiment, which is the whole point of reaching for it before a re-gen.

Categoryimage

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
clip_limitFLOAT1.00–9999
grid_size_whINT81–16384

Outputs (1)

NameTypeDescription
IMAGEIMAGE