Edge-Aware Skin Smoother
A skin smoother that won't turn eyes into smudges
- image
- mask
- image
The thing that ruins a portrait retouch is smoothing that kills the face's structure - lips become smudges, eyelashes vanish, the hairline melts. JHPixelProEdgeAwareSmoother is a bilateral filter: it smooths flat regions (cheeks, forehead) hard and leaves strong edges (eyes, lips, hair) mostly alone. It's the "beauty blur" node of the ComfyUI-JH-PixelPro pack, and it's the one I'd reach for over a plain Gaussian for skin every time, because it doesn't just look smoother - it looks untouched, which is the entire point of good skin work.
It's also smart about workflow: the optional mask input gates the smoothing to a region. Pipe in a refined face mask (the pack's JHPixelProEdgeAwareMaskRefiner upstream works great for this) and you smooth skin while the eyes and hair stay pixel-exact. Where mask = 0, the output equals the input exactly; where mask = 1, full smoothing; in between, blend.
The settings that matter
strength(default 0.4): how much smoothed result gets blended over the original. 0 = bypass, 1 = full smoothing. The README's pro dose is 0.3–0.5, and that's right - 0.4 is a natural, believable retouch.sigma_color(default 0.1): here's where people get burned. This is on the[0,1]image scale, not the 8-bit 10–50 range you'll find in OpenCV's docs. Start around 0.05–0.3. If you type 20 and wonder why your image turns to wax, this is why.sigma_space(default 6): spatial sigma in pixels, capped at 8.0 in v1.1. Want wider smoothing than that? Don't crank the knob - the node deliberately blocks it to protect your VRAM budget. Instead, downsample upstream with a Resize node, smooth, and upscale back.
device (auto/cpu/cuda) picks where the math runs. tile_mode is the OOM escape hatch: enable it for 4K+ images or any run with sigma_space > 4, and the node processes in 512×512 tiles and stitches. There's also a 2 GB memory guardrail that raises an early, readable RuntimeError telling you to turn on tile_mode or downsize - instead of a mid-render CUDA OOM crash, which is genuinely nice engineering.
Install
ComfyUI Manager → search ComfyUI-JH-PixelPro, or:
cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt
Restart ComfyUI; it's under ComfyUI-JH-PixelPro/filters. Needs ComfyUI ≥ 0.43.x, Python ≥ 3.10, and the pack's deps (kornia, mediapipe, opencv-python-headless, scipy).
One honest warning: on CPU this is slow above 1K - a 1024×1024 run is tens of seconds. The GPU path is the intended one, so if you're CPU-only, keep images small or expect to wait. And note the smoothing is bilateral, not frequency-separation - if you want to preserve texture on the smooth layer and keep pores separate, the pack's JHPixelProFrequencySeparation is the more surgical tool. For a quick, believable beauty pass that respects edges, this node is hard to beat.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| strength | FLOAT | 0.400–1 | Blend between smoothed and original. 0 = identity (bypass), 1 = full smoothing. Typical pro dose 0.3–0.5. |
| sigma_color | FLOAT | 0.100.01–0.5 | Intensity sigma on the [0, 1] image scale — not the 8-bit 10–50 range from OpenCV docs. Small values preserve edges; large values smooth across weak edges. |
| sigma_space | FLOAT | 6.01–8 | Spatial sigma in pixels. Range 1.0–8.0 (v1.1 cap). Kernel size auto-sized to 2*ceil(3*sigma_space)+1. Need wider? Downsample the image first with a Resize node upstream. |
| device | COMBO | auto | Compute device. 'auto' picks CUDA if available, else CPU. Explicit 'cuda' raises if CUDA unavailable. 'cpu' forces CPU (slow but deterministic). |
| tile_mode | BOOLEAN | false | Enable 512x512 tile processing to avoid OOM on large images. Required for 4K+ or sigma_space > 4 on most GPUs. Leave off for images ≤1K for max speed. |
| maskopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |