2-D Filtering
Intuition
Blurring replaces each pixel by an average of its neighbourhood. Slide a small grid of weights (kernel) over the image; at each position, multiply and add.
Precise explanation
For an odd-sized kernel (kh, kw) with radius , :
after padding by so the output has the same size as the input. This is
cross-correlation (no kernel flip), as in CNN layers (DL-25) and OpenCV's filter2D.
Border modes: zero padding (np.pad(..., mode="constant")) darkens edges; edge padding
(mode="edge") repeats the border pixel.
- Box kernel: all entries .
- Gaussian kernel: with , normalised to sum to 1 (so overall brightness is preserved).
Worked example
3×3 box blur on a 3×3 image of ones with zero padding: centre 1.0, edges 6/9, corners 4/9. With edge padding every output is 1.0.
Common mistakes
- Even-sized kernels (no centre) — reject them here.
- Using
np.convolve/flipping the kernel. - Not normalising blur kernels (image gets brighter).
Why this matters
Every convolutional layer is this operation with learned kernels; smoothing is also a standard pre-step before edge detection (CV-12).
Library implementation
scipy.ndimage.correlate(img, kernel, mode="constant", cval=0.0) computes the same zero-padded
filter, and mode="nearest" matches edge padding. OpenCV's cv2.filter2D is the equivalent in
OpenCV. The comparison runs when SciPy is installed.
References
- CS231n: Convolutional Neural Networks notes — Stanford University CS231n (
S015) - Scientific Python Lectures — Scientific Python developers (
S006) - OpenCV Tutorials (OpenCV 4.13.0) — OpenCV team (
S023)