cv2.ximgproc.guidedFilter
The mask-feathering tool you already have, with the real parameters
- guide
- src
- result
Guided filtering is the one classical operation in this corner of the toolbox that keeps earning its keep: it smooths a source image while following the edges of a second image. The KB's post-processing doc is right that it's "the tool for feathering a mask along real edges", and that spacepxl's Guided Filter Image is what most people have installed. What this node adds is the full parameter set: the window radius, the regularization, the fast-filter subsampling factor, and an output depth. If you've been tuning a single mysterious "strength" slider, this is the un-shortened version.
How it works
For each pixel, the filter fits a local linear model a·guide + b in a window, then averages those fits. Where the guide is flat, the model degenerates to a local average (smoothing); where the guide has an edge, a and b track it, so the source's edge comes through. Because it's a linear fit rather than a weighted average, you don't get the halo/gradient-reversal artefact that bites bilateral filters - the author's note in the pack's own example workflow calls that out as its advantage.
Two modes, one node:
- Self-guided (
guide=src): edge-preserving smoothing. Structure/detail separation, skin softening, sensor noise removal without smearing the edges of the face. - Joint (
guide= a sharp image,src= a soft one): structure transfer. Feather a rough mask along the real edges of the photo; sharpen up a noisy or low-res depth/disparity map using the colour image; clean up a matte. The tooltip spells out exactly this: "pass a sharp image to transfer its structure onto a soft src (matte/depth refinement)".
Inputs that matter
- guide - the edge source. Up to 3 channels; extra channels ignored. Must match
src's size. It's a match-type socket, so theresultoutput echoes it: an IMAGE or MASK in, the same type back, and you can preview it directly. - src - what gets filtered. Any channel count.
- radius (default 0) - the window radius in pixels. The pack's example workflow uses 8 for self-guided smoothing, 5 for disparity refinement. Bigger means stronger smoothing.
- eps - the trap, and the reason this article exists.
epsis a variance in squared units of your data's own scale, not a 0–1 strength. On ordinary 0–255 uint8 input, anything up to about 1.0 is an exact no-op: the useful range is roughly 100–600, and the pack's example uses 400 (about a 20-level tolerance). On float 0–1 data, divide by 255² - the equivalent strength lands around 1e-3. - scale (1.0) - the fast guided filter. Below 1, the filter subsamples internally (
0.5shrinks the image 2×) for a big speed-up with almost no visible degradation. This is the underrated knob: half-res filtering on a 4K frame looks fine and runs far quicker. - dDepth - output depth;
same as inputis right unless you have a reason.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
Restart ComfyUI, or install ComfyUI CV from ComfyUI Manager. Python ≥3.12, a recent ComfyUI on the V3 node API, opencv-contrib-python-headless~=5.0.0.93 - no models, no downloads. It's a contrib function, so a non-contrib opencv-python install hiding in site-packages/cv2 will make the node disappear; tools/repair_opencv_contrib.py --check diagnoses that, --apply repairs it.
Common issues
"Nothing happened." eps ≤ 1 on 0–255 data. Nothing else.
It smooths over holes. Like its neighbours in this module, the filter has no notion of an invalid pixel: feed a disparity or depth map and the −1 "unknown" markers get averaged in as measurements. Smooth the valid regions and composite around the holes, or use one of the pack's curated disparity nodes that know about validity.
Over-smoothing across a real edge. The guide's edge has to be visible in the guide. If your guide is already blurred, the filter follows the blur.
Per resolution, not per workflow. radius and eps are both in absolute terms; a setting tuned on a 512px preview will visibly under-smooth a 4K render. Scale radius with the frame, and re-tune eps per data type rather than copying a number between a photo pass and a mask pass.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| guide | COMFY_MATCHTYPE_V3 | guided image (or array of images) with up to 3 channels, if it have more then 3 channels then only first 3 channels will be used. The image output(s) echo this input's format. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| src | NPARRAY,IMAGE,MASK | filtering image with any numbers of channels. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| radius | INT | 0-2147483648–2147483647 | radius of Guided Filter. |
| eps | FLOAT | 0.0000-1e+38–1e+38 | regularization term of Guided Filter. ${eps}^2$ is similar to the sigma in the color space into bilateralFilter. |
| dDepthopt | COMBO | same as input | optional depth of the output image. |
| scaleopt | FLOAT | 1.0000-1e+38–1e+38 | subsample factor of Fast Guided Filter, use a scale less than 1 to speeds up computation with almost no visible degradation. (e.g. scale==0.5 shrinks the image by 2x inside the filter) Preset to the OpenCV default (1.0). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| result | COMFY_MATCHTYPE_V3 | Echoes the 'guide' input's format: an IMAGE link comes back as IMAGE, MASK as MASK, NPARRAY stays NPARRAY. |