OpenCV bilateralFilter_0
Smooth skin and noise without smearing the edges
- src
- dst
- nparray
Here's the one filter people routinely reach for and get wrong: a Gaussian blur smooths everything, edges included, which is why it turns a face into a soft blur when you just wanted to kill the noise. bilateralFilter_0 is the edge-preserving alternative. It smooths flat regions - skin, skies, gradients - while keeping boundaries crisp, which is exactly the behavior you want for skin smoothing or denoising something you're not trying to melt. The KB's post-processing doc puts it bluntly: reaching for Gaussian where you needed bilateral is how you lose the edges you were trying to keep.
This node wraps cv2.bilateralFilter inside opencv-comfyui, the auto-generated pack of OpenCV functions. Unlike some of this pack's entries, this one is clean: one image in, one image out, no string literals.
How it works
A bilateral filter is a blur where each pixel's neighbors are weighted twice: once by spatial distance (close pixels matter more, like a Gaussian) and once by color difference (pixels with very different colors don't bleed in). The second weight is what saves the edges - a filter kernel never crosses a sharp color boundary, so a strong edge stays a strong edge while smooth areas average out.
The inputs:
- src - the image as an
NPARRAY. - d - the diameter of the pixel neighborhood. This is the knob people fight with. Odd numbers, typically 5–15.
0is allowed and means "compute it from sigmaSpace." Smalld= subtle, fast; larged= strong, slow. - sigmaColor - how different two colors can be and still count as "the same region." Higher = more smoothing across color boundaries. Start around 50–80 for an 8-bit image.
- sigmaSpace - how far the blur can reach spatially. Higher = larger effective radius.
- borderType - how edges of the image are handled (an OpenCV int constant;
4isBORDER_DEFAULT, which is fine). - dst (optional) - the out-parameter. Leave unwired.
- Output: one nparray, the filtered image.
Tuning it
The classic beginner trap is cranking d way up and wondering why it's slow - bilateral filtering is computationally heavy compared to a plain Gaussian, and the cost grows fast with d. The usual recipe is to keep d modest (7–11 for portraits) and adjust sigmaColor to control how much smoothing crosses into detail. If it looks like a painting, your sigmaColor is too high. If it looks like nothing happened, too low.
Where it fits
ComfyUI has plenty of blur nodes, but few that preserve edges, and the difference shows in skin-smoothing passes and denoising before upscale. If you're on the "soften the skin without plastic look" hunt, this is the deterministic primitive for it - milliseconds, no model, and nothing to re-roll. Wire Image2Nparray in, Nparrays2Image out, and remember the pack runs in BGR.
Install
ComfyUI Manager → search opencv-comfyui, or:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
pip install opencv-python-contrib
Restart ComfyUI. No model files. The pack's one known install trap is a conflicting OpenCV build (Cannot import name 'guidedFilter' from 'cv2.ximgproc') - a clean reinstall in the right environment fixes it. bilateralFilter_1 is this node's identical overload twin; use whichever you clicked.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY | — | |
| d | INT | — | |
| sigmaColor | FLOAT | — | |
| sigmaSpace | FLOAT | — | |
| borderType | INT | — | |
| dstopt | NPARRAY | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |