For each pixel p, the bilateral filter computes a weighted average of its neighbors q:
BF[I](p) = (1/W_p) · Σ_q G_σs(||p−q||) · G_σr(|I(p)−I(q)|) · I(q)
Where:
- G_σs(||p−q||) — Spatial Gaussian: weights based on distance between pixels p and q. Close neighbors get high weight.
- G_σr(|I(p)−I(q)|) — Range Gaussian: weights based on intensity difference. Similar-intensity neighbors get high weight; different-intensity neighbors (across edges) get near-zero weight.
- W_p — Normalization factor ensuring weights sum to 1.
The key insight: on a flat region, all neighbors have similar intensity, so range weights are high and the filter behaves like a regular Gaussian blur. At an edge, neighbors on the other side have very different intensity, their range weights drop to zero, and the filter only averages pixels on the same side of the edge.