Bilateral Filter
Denoise that doesn't turn your edges to mush
- images
- IMAGE
You know how a gaussian blur cleans up noise by smearing everything, edges and all? Bilateral filter is the version that refuses to smear. It's the node you reach for when a render comes out grainy or banded - AI noise, film grain, JPEG-ish compression - but the hair strands, eyelashes, and hard object edges are exactly what you're trying to keep. The name sounds scary; the job is simple: smooth the flat stuff, leave the boundaries alone.
How it works
Under the hood this is a one-liner wrapper around Kornia's bilateral_blur (with the L2 color distance, the Matlab-style convention, if you care). The idea: for every pixel, the filter averages its neighbors - but each neighbor only gets to vote if it's close in color as well as close in space. A pixel across an edge differs a lot in color, so it gets essentially zero weight, and the edge survives. A pixel in a flat region differs barely at all, so you get honest smoothing. That's the whole trick, and it's why this filter is the classic pre-upscale cleanup step.
One thing to know before you're surprised: the node runs on CPU. The pack moves the tensor off the GPU before filtering, so a single 1024² image is fine, but feeding it a big batch before an upscale will feel slower than you'd hope.
The inputs that matter
- images - a ComfyUI IMAGE tensor. Wire it after VAE decode (or between two upscale passes).
- kernel_size (1–20, default 3) - the neighborhood size. Keep it odd; 3 is a whisper, 5–7 is where you actually see smoothing.
- sigma_color (0–10, default 0.25) - how much color difference kills a neighbor's vote. Lower = more edge preservation, less noise removal. This is the "how careful is this filter" knob.
- sigma_space (0–10, default 1.25) - the spatial blur radius. Raise it to smooth a wider area.
The output is an IMAGE of the same shape, so it slots right back into whatever pipeline you had. Save it, or feed it into your upscaler chain - denoising before upscaling is where this node earns its keep, because it stops the upscaler from faithfully amplifying the grain.
Installing it
It's part of the tiny ImageProcessing pack by bvhari, which is just seven of these wrapper nodes plus Kornia. Install it like any custom node:
cd ComfyUI/custom_nodes
git clone https://github.com/bvhari/ComfyUI_ImageProcessing
# restart ComfyUI - it auto-installs requirements.txt (adds kornia; torch you already have)
Or skip the terminal: ComfyUI Manager → Custom Nodes Manager → search "ImageProcessing" → Install → restart. No model files, no API key, nothing to download beyond a small Python package. In the node menu it lives under the ImageProcessing category.
When it bites
The most common "bug" is nothing happening: the defaults (3×3, sigma_color 0.25) are genuinely subtle, so bump kernel_size to 5 or 7 first. If kornia failed to install on startup, you'll get an import error in the console - fix it with pip install kornia in your ComfyUI environment. And remember it only smooths: if your goal is edge sharpening, you want its sibling, the Unsharp Mask node, from the same pack.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| kernel_size | INT | 31–20 | — |
| sigma_color | FLOAT | 0.250–10 | — |
| sigma_space | FLOAT | 1.250–10 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |