Image Processing & Computational Photography
Bilateral Filter
An edge-preserving smoothing filter that averages each pixel with neighbors that are both nearby and similar in value, so noise and texture are removed while strong edges stay sharp.
intermediate
The bilateral filter smooths an image while keeping its strong edges sharp. Like a Gaussian filter, it replaces each pixel with a weighted average of its neighbors, but a neighbor’s weight depends on how similar its value is as well as on how close it is, so pixels across an edge receive almost no weight. Simple and controlled by two intuitive parameters, it became a standard tool for denoising, tone mapping, detail manipulation, and edge-aware upsampling.
The name comes from Tomasi and Manduchi (1998). As the survey by Paris, Kornprobst, Tumblin and Durand (2009) recounts, the same idea appeared earlier in the nonlinear Gaussian filters of Aurich and Weule (1995) and in the SUSAN framework of Smith and Brady (1997). This article describes the method as it is used today.
Problem
Linear smoothing assumes that nearby pixels can be averaged, which fails at edges. The goal is to average within regions of similar intensity, removing noise and fine texture, but not across the boundaries between them.
Inputs and Outputs
- Input: a grayscale or color image, a spatial standard deviation in pixels, and a range standard deviation in intensity units. A joint variant also takes a second guidance image that defines the edges.
- Output: a smoothed image of the same size. Decomposition applications also use the residual (input minus output), which holds the removed detail and noise.
Intuition
Consider a pixel just on the bright side of a step edge. A Gaussian filter averages it with dark neighbors too, and the edge softens. The bilateral filter asks each neighbor how far away it is and how different its value is. Bright neighbors pass both tests; dark ones fail the second and are effectively ignored. Each side of the edge is smoothed separately, and the step survives. In a flat region every neighbor passes, and the filter acts as an ordinary Gaussian blur: its effective kernel adapts to the image, a full disk in flat regions, a half-disk beside a straight edge.
Algorithm
For each pixel :
- For each neighbor within a window of radius about to , compute a spatial weight from the distance and a range weight from the difference .
- Multiply the two weights.
- Accumulate the weighted sum of neighbor values and the sum of the weights.
- Divide the weighted sum by the sum of weights.
All outputs are computed from the original input in a single, non-iterative pass, so the parameters have a direct meaning.
Mathematical Formulation
The bilateral filter of a grayscale image is
with the normalization
where and is the set of pixel positions. is the spatial (domain) kernel and the range kernel. Because the range weights depend on the image, differs from pixel to pixel, and dividing by it makes the weights at every pixel sum to one; a constant image is left unchanged.
Tomasi and Manduchi defined the filter with general closeness and similarity functions, with Gaussians as the main example. For color images they measured similarity as Euclidean distance in CIE-Lab, a color space in which such distances roughly track perceived differences. Filtering the color vector jointly averages only perceptually similar colors, whereas filtering red, green, and blue separately can create colors at edges that were not in the image.
Two limits show what each kernel contributes. As , the range weights become constant and the filter reduces to Gaussian smoothing. As , the spatial weights become constant and the filter becomes a pure range filter; Tomasi and Manduchi showed that this merely remaps gray levels according to the image histogram, without any spatial smoothing. Edge-preserving smoothing needs both.
Parameters
- Spatial . The neighborhood size, and so the scale of the features removed; it must scale with image resolution. Denoising typically uses small values, decomposing an image into a smooth base and a detail layer large ones.
- Range . The contrast of the edges preserved: differences much smaller than are averaged, much larger ones are not. It must scale with the intensity range ( versus ). For denoising it is set in proportion to the noise level; Paris et al. report a recommendation by Liu and colleagues of for a local noise standard deviation .
Because the weights multiply, no averaging occurs where either is near zero: increasing does not blur an edge whose contrast is well above .
Complexity
A brute-force implementation over a window of radius costs for pixels. The filter is neither a convolution nor separable, so neither the FFT nor row-and-column factoring applies directly. Tomasi and Manduchi precomputed the range weights in a lookup table, one entry per intensity difference; even so, Paris et al. report that a direct implementation can take minutes for a megapixel image with a large kernel.
Fast approximations exploit the observation that the filter becomes linear in a higher-dimensional space:
- Piecewise-linear approximation. Durand and Dorsey (2002) fixed a few intensity levels, computed for each a Gaussian convolution of the image weighted by the range kernel centered at that level, and interpolated between the two levels nearest each pixel’s value, on a downsampled image. This cut the time for a megapixel image to about a second.
- Bilateral grid. Paris and Durand (2006) showed that bilateral filtering a grayscale image is exactly a 3D Gaussian convolution over position and intensity of a homogeneous representation of the image, followed by sampling at each pixel’s own intensity (“slicing”) and a division. Because the convolved volume is band-limited, it can be computed on a coarse 3D grid, which they named the bilateral grid. Chen, Paris and Durand (2007) made the grid a primary data structure, ran it on graphics hardware in real time for high-definition video, and used it for other edge-aware operations such as local histogram equalization and edge-aware painting.
- Permutohedral lattice. Color bilateral filtering is a 5D problem (two positions, three colors), where regular grids grow expensive. Adams, Baek and Davis (2010) sampled the space on the permutohedral lattice, whose simplices make splatting and slicing cheap, and obtained a high-dimensional Gaussian filter whose cost is linear in the number of pixels and polynomial ( per pixel) in the dimension .
Implementation
The example filters a noisy vertical step edge (height 0.6) by brute force and compares it with a Gaussian filter of the same , at a low and a high noise level. It reports the noise remaining in a flat region, the jump between the two columns either side of the edge, and the overall error against the clean image.
import numpy as np
from scipy import ndimage
def bilateral(img, sigma_s, sigma_r, truncate=3.0):
"""Brute-force bilateral filter of a grayscale image (reflect padding)."""
r = int(np.ceil(truncate * sigma_s))
pad = np.pad(img, r, mode="reflect")
num = np.zeros_like(img)
den = np.zeros_like(img)
h, w = img.shape
for dy in range(-r, r + 1):
for dx in range(-r, r + 1):
spatial = np.exp(-(dx**2 + dy**2) / (2 * sigma_s**2))
neighbor = pad[r + dy:r + dy + h, r + dx:r + dx + w]
weight = spatial * np.exp(-(neighbor - img)**2 / (2 * sigma_r**2))
num += weight * neighbor
den += weight
return num / den
def report(name, out, clean):
flat = out[:, 8:24] # left region, away from the edge
contrast = out[:, 32].mean() - out[:, 31].mean() # jump across the edge
rmse = np.sqrt(np.mean((out - clean)**2))
print(f"{name:26s} flat-region std {flat.std():.4f} "
f"edge jump {contrast:.3f} RMSE {rmse:.4f}")
rng = np.random.default_rng(0)
clean = np.full((64, 64), 0.2)
clean[:, 32:] = 0.8 # vertical step edge of height 0.6
for sigma_n in [0.05, 0.3]:
noisy = clean + rng.normal(0, sigma_n, clean.shape)
print(f"noise sigma {sigma_n}:")
report("input", noisy, clean)
report("Gaussian, sigma 2", ndimage.gaussian_filter(noisy, 2, mode="reflect",
truncate=3.0), clean)
for sigma_r in [0.1, 0.3, 10.0]:
report(f"bilateral, sigma_r {sigma_r}", bilateral(noisy, 2, sigma_r), clean)
Output:
noise sigma 0.05:
input flat-region std 0.0502 edge jump 0.591 RMSE 0.0499
Gaussian, sigma 2 flat-region std 0.0080 edge jump 0.119 RMSE 0.0507
bilateral, sigma_r 0.1 flat-region std 0.0143 edge jump 0.595 RMSE 0.0141
bilateral, sigma_r 0.3 flat-region std 0.0083 edge jump 0.489 RMSE 0.0142
bilateral, sigma_r 10.0 flat-region std 0.0080 edge jump 0.120 RMSE 0.0507
noise sigma 0.3:
input flat-region std 0.3052 edge jump 0.614 RMSE 0.3012
Gaussian, sigma 2 flat-region std 0.0479 edge jump 0.120 RMSE 0.0693
bilateral, sigma_r 0.1 flat-region std 0.2866 edge jump 0.601 RMSE 0.2827
bilateral, sigma_r 0.3 flat-region std 0.1745 edge jump 0.481 RMSE 0.1749
bilateral, sigma_r 10.0 flat-region std 0.0473 edge jump 0.121 RMSE 0.0689
At low noise, the Gaussian filter reduces flat-region noise sixfold but shrinks the edge jump from 0.6 to 0.12, so its overall error is no better than the input’s. The bilateral filter with , twice the noise level, keeps the edge and cuts the error by more than a factor of three; it leaves more flat-region noise because the range kernel also down-weights strongly noisy neighbors. With it smooths flat regions as well as the Gaussian but softens the edge, and with it is the Gaussian. At high noise, half the edge height, no separates noise from edge: a narrow range kernel treats the noise as edges and barely smooths, and the plain Gaussian has the lowest error. The range kernel works only when edges are much stronger than the noise.
Properties and Behavior
- Nonlinear but shift-invariant. The weights depend on the image, so filtering a sum of images is not the sum of the filtered images. Shifting the image, or adding a constant to its intensities, shifts the output accordingly.
- Staircasing. The filter is best at step-like edges. It tends to break smooth gradients into piecewise-constant pieces, the staircase effect analyzed by Buades, Coll and Morel, and can sharpen soft edges into steps.
- Gradient reversal. When the residual detail layer is amplified, as in detail enhancement or tone mapping, the filter can produce reversed profiles next to edges. He, Sun and Tang (2013) trace this to edge pixels with few similar neighbors, whose weighted average becomes unstable.
- Impulse noise survives. An outlier differs from all its neighbors, so the range kernel gives them little weight and the outlier stays. Paris et al. describe computing the range weights from a median-filtered copy of the image to handle this case.
Limitations
The bilateral filter is a simple, flexible denoiser rather than a state-of-the-art one: it compares single pixel values, which are themselves noisy. Its brute-force cost grows with , and fast versions are approximations whose accuracy and memory depend on , , and the range dimension.
Variants
- Joint (cross) bilateral filter. Petschnigg and colleagues (2004) and Eisemann and Durand (2004) independently computed the range weights from a second image: a flash photograph supplies reliable edges for smoothing a noisy no-flash photograph of the same scene. Kopf and colleagues (2007) used it for joint bilateral upsampling: a high-resolution image guides the upsampling of a solution computed at low resolution.
- Guided filter. He, Sun and Tang (2010, 2013) proposed an alternative based on a local linear model of the output in terms of a guidance image. It preserves edges in a similar way, avoids gradient reversal, and has an exact algorithm whose cost is linear in the number of pixels, regardless of kernel size and intensity range.
- Relation to anisotropic diffusion. Perona–Malik diffusion also smooths less across strong gradients, but iteratively, as a partial differential equation. Durand and Dorsey showed that a bilateral filter restricted to the four nearest neighbors is a discrete Perona–Malik scheme.
- Neighborhood and patch-based filters. Yaroslavsky’s neighborhood filter is the bilateral filter with a box spatial kernel. Non-local means compares whole patches instead of single pixel values, which makes the weights more robust to noise; Adams and colleagues treat it and the bilateral filter alike as high-dimensional Gaussian filters.
Uses in Computer Vision
- Tone mapping. Durand and Dorsey (2002) split the log intensity of a high-dynamic-range image into a bilateral-filtered base layer and a residual detail layer. Compressing only the base and adding the detail back reduces contrast without the halos a Gaussian base layer produces at high-contrast edges.
- Detail enhancement, stylization, and guided upsampling. Amplifying the residual exaggerates texture, iterating the filter drives the image toward piecewise-constant, cartoon-like regions, and joint bilateral filtering upsamples low-resolution results such as depth maps from range sensors.
- Segmentation refinement. Krähenbühl and Koltun (2011) built a fully connected conditional random field whose pairwise term includes a bilateral appearance kernel over position and color, with mean-field inference computed by permutohedral-lattice filtering. The first DeepLab model (Chen and colleagues, 2014) applied such a CRF to a convolutional network’s output to sharpen segment boundaries.
Related
- Image Filtering
Computing each output pixel from a neighborhood of input pixels, the family of operations behind smoothing, sharpening, edge detection, and denoising.
- Median Filter
A nonlinear filter that replaces each pixel by the median of its neighborhood, removing impulse noise while keeping step edges sharp.
- Image Noise
The random variation in recorded pixel values that does not come from the scene, its physical sources in the camera, and how it is modeled and measured.
- Color Spaces
A color space assigns numbers to colors; choosing and converting between RGB, CIE XYZ, CIELAB, YCbCr, and HSV correctly matters for both image processing and learning.
- Image Gradients
How image gradients measure the direction and strength of intensity change, and why they underpin edges, corners, and motion estimation.
- Bilateral Filtering for Gray and Color Images
The 1998 ICCV paper by Tomasi and Manduchi that combined domain and range weighting into a single non-iterative, edge-preserving smoothing filter, named it bilateral filtering, and applied it to color images in CIE-Lab.
References
- Tomasi, C. & Manduchi, R. (1998). Bilateral Filtering for Gray and Color Images. Proceedings of the Sixth International Conference on Computer Vision (ICCV), 839–846.
- Paris, S., Kornprobst, P., Tumblin, J. & Durand, F. (2009). Bilateral Filtering: Theory and Applications. Foundations and Trends in Computer Graphics and Vision, 4(1), 1–73.
- Durand, F. & Dorsey, J. (2002). Fast Bilateral Filtering for the Display of High-Dynamic-Range Images. ACM Transactions on Graphics, 21(3), 257–266.
- Paris, S. & Durand, F. (2006). A Fast Approximation of the Bilateral Filter Using a Signal Processing Approach. Computer Vision – ECCV 2006, Lecture Notes in Computer Science 3954, 568–580.
- Chen, J., Paris, S. & Durand, F. (2007). Real-Time Edge-Aware Image Processing with the Bilateral Grid. ACM Transactions on Graphics, 26(3), Article 103.
- Adams, A., Baek, J. & Davis, M. A. (2010). Fast High-Dimensional Filtering Using the Permutohedral Lattice. Computer Graphics Forum, 29(2), 753–762.
- He, K., Sun, J. & Tang, X. (2013). Guided Image Filtering. IEEE Transactions on Pattern Analysis and Machine Intelligence, 35(6), 1397–1409.