Home

CV

๐Ÿง  Bilateral Filtering in Image Processing โ€“ Tutorial


๐ŸŸก 1. Motivation

In image denoising, we often want to remove noise but preserve edges. Classical filters like Gaussian blur are fast but blur across edges, causing loss of detail.

Bilateral filtering solves this by combining:

  • Spatial closeness (like Gaussian blur)
  • Intensity similarity (to avoid averaging across edges)

๐ŸŸฉ 2. Intuition

Imagine averaging only those pixels that:

  1. Are close in distance
  2. Have similar brightness/color

So, a pixel is influenced only by neighboring pixels that look similar.

Itโ€™s like a smart blur that doesnโ€™t mix objects of different intensities.


๐Ÿ”ข 3. Mathematical Formulation

Let $I(x)$ be the intensity at pixel $x$. Then the bilateral filter output at $x$ is:

\[I_{\text{out}}(x) = \frac{1}{W(x)} \sum_{x_i \in \Omega} I(x_i) \cdot f_s(\|x - x_i\|) \cdot f_r(|I(x) - I(x_i)|)\]

Where:

  • $\Omega$ = local neighborhood of $x$
  • $f_s$ = spatial Gaussian โ†’ penalizes far-away pixels
  • $f_r$ = range Gaussian โ†’ penalizes intensity differences
  • $W(x)$ = normalization factor:

    \[W(x) = \sum_{x_i \in \Omega} f_s(\|x - x_i\|) \cdot f_r(|I(x) - I(x_i)|)\]

๐Ÿงฎ 4. Kernel Details

  • $f_s(d) = \exp\left(-\frac{d^2}{2\sigma_s^2}\right)$
  • $f_r(\Delta I) = \exp\left(-\frac{(\Delta I)^2}{2\sigma_r^2}\right)$
Term Meaning
$\sigma_s$ Controls spatial influence radius
$\sigma_r$ Controls range sensitivity (how different intensities are tolerated)

๐Ÿ“Š 5. Visual Flowchart

For each pixel x:
    โ””โ”€ For each neighbor x_i in window:
         โ”œโ”€ Compute spatial weight: f_s(||x - x_i||)
         โ”œโ”€ Compute range weight: f_r(|I(x) - I(x_i)|)
         โ”œโ”€ Multiply both weights and image value: weight * I(x_i)
    โ””โ”€ Normalize by total weight sum

๐Ÿงช 6. Python Code Example (Simplified)

import cv2
import numpy as np

img = cv2.imread('image.jpg')
filtered = cv2.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)
Param Meaning
d Diameter of neighborhood
sigmaColor = $\sigma_r$ How much color difference is tolerated
sigmaSpace = $\sigma_s$ How much spatial distance is tolerated

๐Ÿง  7. Comparison to Non-Local Means (NLM)

Feature Bilateral Filter Non-Local Means (NLM)
Neighborhood Local (fixed radius) Non-local (can span image)
Weight based on Spatial + Intensity difference Patch similarity
Edge-preserving? Yes Yes
Texture handling OK Better (uses structure)
Computation Fast Slow (can be accelerated)
Noise removal quality Moderate High
Sensitive to parameter tuning Moderate High
Mathematical base Point-wise similarity Patch-wise similarity
Implemented in OpenCV cv2.bilateralFilter() cv2.fastNlMeansDenoising()

๐Ÿงฉ 8. Intuition: Bilateral vs NLM

Bilateral:

โ€œIโ€™ll average with nearby pixels that are close in value.โ€

Non-Local Means:

โ€œIโ€™ll average with any patch in the image that looks like me, regardless of where it is.โ€


๐Ÿงฌ 9. Non-Local Means (NLM) Brief Overview

Let $P(x)$ be a patch around pixel $x$. NLM is:

\[I_{\text{out}}(x) = \frac{1}{Z(x)} \sum_{x_i} I(x_i) \cdot \exp\left(-\frac{\|P(x) - P(x_i)\|^2}{h^2}\right)\]

Where $h$ controls filtering strength.


๐Ÿงช NLM Python Code

dst = cv2.fastNlMeansDenoisingColored(img, None, h=10, hColor=10, templateWindowSize=7, searchWindowSize=21)

๐Ÿง  10. When to Use What?

Scenario Use
Fast edge-preserving smoothing Bilateral
High-quality denoising of textures (but slow) NLM
Real-time system Bilateral
Medical, satellite, or low-light images NLM (better structure preservation)

โœ… Summary

  • Bilateral Filter: Edge-preserving blur using spatial + intensity proximity.
  • NLM: Powerful denoiser using patch-based similarity, non-local in nature.
  • Bilateral = simple, fast, local
  • NLM = accurate, slow, global

Would you like me to walk through an end-to-end image example in NumPy, or illustrate both filters side-by-side?