CLAHE Preprocess
Don't let specular highlights carve fake ridges into your 3D meshes
- image
- IMAGE
Geometry models are gullible. Show TRELLIS, InstantMesh, or any single-image-to-3D model a photo with a specular highlight - a glossy car hood, wet pavement, a window glint - and it reads the shine as a surface edge, carving a false ridge right into your mesh. Depth estimators and normal-map extractors fall for the same trick - they read brightness as structure, and lighting artifacts are bright gradients that lie.
CLAHE Preprocess is a one-node insurance policy against that. It sits in the cuzelac/ComfyUI-CLAHE-Preprocessor pack and exists for exactly one job: strip color and lighting interference out of an image before a geometry-focused model sees it, and hand back a clean 3-channel image with the local texture contrast cranked up. You'd reach for it whenever a depth map looks like it's hallucinating edges that aren't in the actual surface, or when your mesh gen keeps turning a photo's glare into bumps.
How it works
The node runs four steps in order, and the pipeline is the whole point:
- Weighted grayscale conversion. It blends the red, green, and blue channels into one gray image using weights you control. The defaults (15% R, 65% G, 20% B) lean hard on green, which usually carries the most structural detail, and starves red - the channel where "warm glow" artifacts live.
- Specular suppression. Pixels brighter than a configurable percentile get blended toward their Gaussian-blurred local average. Highlights get flattened without nuking the texture contrast around them.
- CLAHE (Contrast Limited Adaptive Histogram Equalization) - the star of the show. It boosts local contrast tile-by-tile instead of globally, so fine surface detail and subtle geometry cues pop without amplifying the broad highlights you just suppressed.
- Back to 3-channel RGB. Grayscale comes out, RGB goes in. That last step matters more than it looks: the author explicitly calls out that TRELLIS throws a
TypeErroron single-channel input, so the node forces a compatible 3-channel output.
That last point is the reason this isn't just "a grayscale node with extra steps." You get the benefits of a gray, de-lit image while keeping every downstream node that insists on color happy.
The inputs that matter
There are eight inputs but a beginner touches maybe three:
clip_limit(default 3.0, range 0.5–10) - CLAHE's contrast knob. Higher = punchier local contrast, but push it too far and you start amplifying noise into halos. Start at the default and only nudge up.tile_size(default 8) - how fine-grained the local contrast is. Smaller tiles react to finer detail, bigger tiles behave more like global equalization.specular_percentile(default 90) - the brightness threshold for highlight suppression. If glare survives, drop it toward 80; if your image gets washed out, raise it.
The three *_weight sliders are the "fine-tune per content" dials - the README's example is dropping red_weight further when a warm orange glow dominates. specular_blur (default 21) is the suppression blur kernel; the code quietly bumps even values up by one, so you can't break it with a bad number.
The single output is an IMAGE, and it wires straight into whatever geometry model you're feeding - TRELLIS or another mesh generator, a depth estimation node, or a normal-map extractor. It also handles batched image tensors, so a stack of frames can pass through in one go.
Install
ComfyUI Manager can find it if you search CLAHE, but the manual route is the same as always:
cd ComfyUI/custom_nodes
git clone https://github.com/cuzelac/ComfyUI-CLAHE-Preprocessor.git
pip install opencv-python # the only non-bundled dependency
Then restart ComfyUI. You'll find CLAHE Preprocess under image/preprocessing. requirements.txt pins opencv-python >= 4.8.0, and the README wants Python 3.10+.
Gotchas
The real one: this node is written against ComfyUI's newer V3 API (comfy_api.latest), the ComfyNode/ComfyExtension pattern. If it doesn't show up after install, it's usually because your ComfyUI is too old for that API - update ComfyUI first, don't blame the node.
Also be aware the included frontend JS auto-queues a run 500ms after you touch any parameter, so the preview updates live as you drag sliders. Lovely for tuning, but in a heavy workflow that's a lot of queued prompts - worth knowing before you fiddle with all eight widgets at once.
One honest caveat: this is a preprocessing node, not a general image beautifier. Feed it through a depth map or a mesh and judge it there. If you run it on a random image and think it looks washed out or gray - that's the point. The color is gone so the geometry can come through.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Input image to preprocess | |
| red_weight | FLOAT | 0.150–1 | Red channel contribution to grayscale. Low value suppresses warm glow artifacts. |
| green_weight | FLOAT | 0.650–1 | Green channel contribution to grayscale. High value preserves structural detail. |
| blue_weight | FLOAT | 0.200–1 | Blue channel contribution to grayscale. |
| specular_percentile | FLOAT | 90.050–100 | Brightness percentile threshold for specular suppression. |
| specular_blur | INT | 213–51 | Gaussian blur kernel size for specular suppression (must be odd). |
| clip_limit | FLOAT | 3.00.5–10 | CLAHE clip limit. Higher values increase local contrast. |
| tile_size | INT | 82–32 | CLAHE tile grid size (used for both dimensions). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |