Nodes/ComfyUI-JH-PixelPro/Color: CLAHE Local Contrast
ComfyUI Node

Color: CLAHE Local Contrast

Local Contrast That Doesn't Turn Skin Orange

By jetthuangai·Created 6 months ago·Updated a day ago· 6
Color: CLAHE Local Contrast
  • image
  • mask
  • image
◄clip_limit2.0►
◄grid_size8►
◄strength1.00►

CLAHE - Contrast Limited Adaptive Histogram Equalisation - is one of the oldest tricks in the imaging toolbox and one of the most reliably misunderstood. Run it on RGB and it shifts colour: each channel gets stretched independently, so a slightly warm shadow goes very warm. Run it on lightness only and it does the thing it's famous for in microscopy and medical imaging without wrecking hue.

Color: CLAHE Local Contrast (JHPixelProCLAHE) does the second one. It's the same algorithm OpenCV has shipped for years, converted to CIE LAB, applied to L* alone, and given a strength blend.

What it does

The image goes through a Kornia RGB→LAB conversion. L* (divided by 100) is the only channel that gets equalised, on a grid_size × grid_size tile grid with a clip limit on each tile's histogram. The original a* and b* come back untouched. Then the result is lerp(original, enhanced, strength × mask) and clamped.

That's why it's the tool to reach for when a region is too flat or too dark rather than "not punchy enough". Clarity - the ColorLab slider, the Camera Raw one - is a radius-based edge punch: it makes edges feel crisper. CLAHE redistributes brightness within each tile, so it can open up a muddy corner and flatten a big soft gradient that clarity wouldn't notice. Different tool, different job, frequently confused.

The knobs

Four of them, and the defaults are sane.

clip_limit (0.1–40, default 2.0) is how hard each tile may be stretched. Higher = more contrast and more visible noise. 1.5–3 is the working range for photographs; past about 6 the grain starts jumping out of the shadows.

grid_size (2–32, default 8) is tiles per axis. Few tiles give a broad, natural lift; many tiles give the crunchy, over-detailed "HDR from 2009" look. 4–6 reads as natural, 12–24 as gritty. Inverted from what people expect - smaller grid number equals broader effect.

strength (0–1) blends back toward the original. For portraits, 0.3–0.6. Skin rarely wants full local contrast.

mask (optional) limits where it applies, and is applied whole to the batch.

One image in, one image out. No mask output.

The mask is the pro move

Wire a skin mask into mask and invert your intent: apply CLAHE to clothing, hair, fabric, background texture - the things that benefit from local crunch - and keep faces out of it. Or the other way round: shadow luminosity mask in, so only the deep areas get lifted. That's the entire difference between "the AI filter look" and retouching, and it costs one additional node from the same pack (Luminosity Masking, Saturation Mask, or any segmenter you already run).

Install

cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt   # the Python that runs ComfyUI

ComfyUI Manager: search ComfyUI-JH-PixelPro → Install → restart. The node lives under Add Node → ComfyUI-JH-PixelPro → color. Requirements: kornia>=0.7, mediapipe>=0.10.33, opencv-python-headless>=4.8, scipy>=1.10; PyTorch from ComfyUI. Nothing extra to download, no model, no optional runtime.

Where it goes wrong

  • Grainy shadows are the classic CLAHE failure. Lower clip_limit before you lower strength - the clip limit is what amplifies noise, the blend just dilutes everything equally.
  • Small images come back unchanged. Under 80 px the node bails; and the grid shrinks automatically to keep every tile at least 80 px wide. Kornia biases very small tiles brighter (a flat image can drift up), so the 80 px floor is a guard rail, not an arbitrary limit.
  • It's quantised to 256 levels inside Kornia's histogram, so banding in an already-8-bit sky is possible at high strengths. Don't stack two CLAHE passes.
  • Flat colour areas stay flat, which is why solid backdrops don't get tinted - a nice side effect worth knowing if you're grading product shots.

Order of operations, since it matters: CLAHE for the local lift, then Smart Sharpen for edge crispness, then Tone Curve last for the global shape. Applying a curve before local contrast means you're redistributing brightness twice with the second pass reacting to the first.

The pack - JH (@jetthuangai), Apache-2.0, 64 nodes, release 1.10.0, bilingual docs - has essentially no footprint in the Reddit corpus; a search for the pack name turns up one unrelated Chrome extension. So there's no community consensus on settings to copy. My advice instead: run it at clip_limit 2.0 / grid_size 8 / strength 0.5 on five of your own photos, put the originals next to them, and look at the shadows specifically. That'll teach you more about CLAHE than any preset.

CategoryComfyUI-JH-PixelPro/color

Inputs (5)

NameTypeDefaultDescription
imageIMAGEInput image (B,H,W,3).
clip_limitFLOAT2.00.1–40Histogram clip limit. Higher = stronger local contrast.
grid_sizeINT82–32Tiles per axis. Smaller = broader, larger = finer detail.
strengthFLOAT1.000–1Blend between original (0) and CLAHE result (1).
maskoptMASKOptional mask limiting where the effect applies.

Outputs (1)

NameTypeDescription
imageIMAGE—