Spatial Filtering: Box and Gaussian Blur
Learning Objectives
- Construct a normalized box-blur kernel and a Gaussian blur kernel of a given size and sigma, and explain why kernel normalization (weights summing to 1) is required.
- Run a small image through both kernels by hand and compare the results.
- Explain the real, practical reason the Gaussian kernel's separability into two 1D passes matters for performance.
Context & Motivation
the-convolution-and-correlation-operation defined the sliding-window mechanic in the abstract, using a generic averaging kernel as its worked example. This concept makes that concrete with the two most common, real fixed kernels used for smoothing: the box blur and the Gaussian blur. Both are genuinely simple, hand-designed, closed-form kernels, exactly the kind of fixed-kernel processing this discipline's scope boundary (drawn precisely in the-convolution-and-correlation-operation against convolution-as-a-sliding-dot-product in ai-theory/deep-learning) is about.
Smoothing is not an end in itself here; it is preparation. the-sobel-operator-and-gradient-based-edge-detection and the-canny-edge-detector, immediately next, both depend on suppressing pixel-level noise before computing a gradient, since a gradient operator amplifies noise as readily as it detects real edges. Getting a working, well-understood blur kernel in hand now is what makes that later step's smoothing stage more than a black box.
Core Theory
The box blur: uniform averaging, normalized
The simplest smoothing kernel weights every pixel in its neighborhood equally. A 3x3 box blur kernel is:
textw_box = (1/9) * [1 1 1] [1 1 1] [1 1 1]
Normalization means the kernel's weights sum to exactly 1 (here, 9 * 1/9 = 1). This is required because convolving a constant-intensity region with an unnormalized kernel would scale its brightness up or down by the sum of the kernel's weights; normalizing guarantees a uniformly bright or dark region is left unchanged in average brightness after blurring, only its local variation is smoothed away.
The Gaussian blur: weighting by distance
The box blur treats a pixel 3 cells away exactly like an adjacent pixel, which is not how real optical or sensor blur behaves. The Gaussian kernel instead samples the 2D Gaussian function:
textG(x, y) = (1 / (2*pi*sigma^2)) * exp(-(x^2 + y^2) / (2*sigma^2))
at integer offsets (x, y) from the kernel's center, then normalizes the resulting samples to sum to 1. Larger sigma produces a wider, flatter kernel (stronger blur, since more distant pixels still get meaningful weight); smaller sigma concentrates weight near the center (a gentler blur, close to identity).
Separability: why Gaussian blur is fast in practice
A key, real, practically important property of the Gaussian: it is separable, the 2D Gaussian function factors exactly into a product of two 1D Gaussians, G(x, y) = G(x) * G(y). This means a 2D Gaussian convolution can be computed as two 1D convolutions in sequence, first blurring every row, then blurring every column of the result, an O(k) + O(k) = O(2k) per-pixel cost instead of O(k^2) for a direct 2D kernel of the same size k x k. This is the specific, concrete reason real image libraries implement Gaussian blur as two passes rather than one big 2D kernel; the box blur can also be separated this way (it is a product of two 1D uniform kernels), but the saving matters most as kernel size grows.
Worked Examples
Example 1: box blur on the 4x4 stripe image
Reusing digital-images-as-discrete-functions's image, computing the box-blur output at (1,1), exactly as done in the-convolution-and-correlation-operation's Example 1: output = 660/9 = 73.33. At (2,2) (also 200 in the original), the 3x3 neighborhood is:
text[200 10 10] [ 10 10 10] [ 10 10 200] Sum = 200+10+10+10+10+10+10+10+200 = 470 Output = 470/9 = 52.22
Both bright diagonal pixels are pulled toward their darker surroundings, the visual effect of blurring made numerically concrete.
Example 2: a small Gaussian kernel, sigma = 1, and normalization check
A common discretized 3x3 Gaussian approximation for sigma ~= 1 (before normalization):
text[1 2 1] [2 4 2] [1 2 1] Sum of raw weights = 1+2+1+2+4+2+1+2+1 = 16
Normalized kernel: divide every entry by 16:
textw_gauss = (1/16) * [1 2 1] [2 4 2] [1 2 1]
Applying this to the same neighborhood at (1,1) from Example 1 ([10,10,200 / 10,200,10 / 200,10,10]):
text(1*10 + 2*10 + 1*200 + 2*10 + 4*200 + 2*10 + 1*200 + 2*10 + 1*10) / 16 = (10+20+200+20+800+20+200+20+10) / 16 = 1300 / 16 = 81.25
Compare to the box blur's 73.33 at the same position: the Gaussian's center-weighted kernel (weight 4 at the center versus the box blur's uniform 1) preserves more of the original bright pixel's influence, a smaller, gentler blur than the uniform box kernel at the same 3x3 size, exactly the qualitative difference Core Theory describes.
Example 3: separability in practice, counting operations
For a 5x5 kernel applied to a single pixel: a direct 2D convolution requires 25 multiplications and 24 additions per output pixel. Using separability (two 1D passes of length 5), each pass requires 5 multiplications and 4 additions, for a total of 2*(5+4) = 18 operations, versus 49 for the direct 2D approach. The gap widens as kernel size k grows: O(k^2) direct versus O(2k) separable, a genuinely large, real saving for the larger kernels a strong blur requires.
Common Misconceptions & Pitfalls
- "A bigger blur kernel always just means 'more of the same,' with no real cost difference." Example 3 shows kernel cost grows quadratically (O(k^2)) without separability, a real, first-order performance concern for large kernels, which is exactly why separability matters practically, not just theoretically.
- "An unnormalized kernel would just produce a slightly-off blur, no big deal." An unnormalized kernel systematically brightens or darkens the entire image by the kernel's weight sum, a first-order visible defect, not a minor rounding issue, which is why normalization is a hard requirement, not a refinement.
- "Gaussian blur and box blur are basically interchangeable." Example 2 shows they produce different numeric outputs on the same input at the same kernel size, because the Gaussian's center-weighted structure treats near and far neighborhood pixels differently, while the box blur treats every neighbor identically; the visual and numeric difference is real, not cosmetic.
Summary
The box blur (uniform, normalized averaging) and the Gaussian blur (weights sampled from a 2D Gaussian, also normalized) are the two standard, real fixed smoothing kernels built directly on the-convolution-and-correlation-operation's sliding-window mechanic, and the Gaussian's separability into two 1D passes is the specific, practical reason it can be computed efficiently at larger kernel sizes. Smoothing is not this discipline's endpoint; it is preparation for the noise-sensitive gradient computations the-sobel-operator-and-gradient-based-edge-detection builds next.