Box Blur
Implement a box blur, also known as a mean filter, to an image by averaging neighboring pixels. This technique is a fundamental concept in Linear Filtering for image processing.
The box blur operates by convolving an image with a kernel, a small matrix that slides over the entire image, computing a weighted average of neighboring pixels at each position. For a given kernel size, the kernel is typically a square matrix with all elements being equal, resulting in a uniform average of the neighboring pixels.
Here are the steps to apply the box blur:
- Define the kernel size and compute the kernel elements as 1/(kernel_size2).
- Slide the kernel over the image, computing the average of neighboring pixels at each position.
- Assign the computed average to the corresponding pixel in the output image.
This technique is widely used in image processing applications to reduce noise.
Example:
image = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
kernel_size = 3[[5.0]]
Box blur (mean filter) averages all pixels in a neighborhood.
For a 3Γ3 box filter on a 3Γ3 image:
output[i,j]=k21ββm,nβinput[i+m,j+n]
-
Valid convolution produces 1Γ1 output:
- Output size: (3β3+1)Γ(3β3+1)=1Γ1
-
Calculate the average of all 9 pixels: mean=91+2+3+4+5+6+7+8+9β
-
Sum the values: sum=1+2+3+4+5+6+7+8+9=45
-
Compute mean: mean=945β=5.0
-
Result: [[5.0]]
The box blur smooths the image by replacing each pixel with the average of its neighborhood.
Constraints:
- kernel_size is odd (3, 5, 7, etc.)
- Round output to nearest integer
- Use zero-padding
A box blur is a simple linear filter that replaces each pixel with the average of its neighbors in a fixed window (here, a 3Γ3 window). Conceptually, this is a special case of convolution in image processing, where you slide a kernel (the 3Γ3 matrix of weights) over the image and compute a weighted sum at each position. For the given kernel K=91ββ111β111β111ββ, each pixel in the output is the mean of itself and its 8 neighbors.
This operation acts as a low-pass filter: it smooths local variations and reduces noise by averaging nearby values, but also blurs edges and fine details. Because all kernel entries are equal and sum to 1, the overall brightness of the image is roughly preserved (no systematic darkening or brightening), and the filter is both shift-invariant and linear (superposition holds).
2. Algorithm / General Approach
For a 3Γ3 box blur:
- For each valid center position in the image:
- Take the 3Γ3 neighborhood around that pixel.
- Sum the 9 pixel values.
- Divide by 9 to get the average.
- Store that average in the corresponding position of the output image.
Boundary handling is the only design choice:
- Easiest for coding problems: often only compute values where a full 3Γ3 window fits (i.e., output is smaller than input by 2 pixels in each dimension).
- Other possible strategies (for real applications): padding (zero, replicate, reflect), but many coding tasks avoid this by shrinking the output.
3. Step-by-Step Strategy
Assume an input image as a 2D array img[h][w] of integers or floats:
- Decide output size
- If using only fully-covered windows:
- Output height: H_out = H_in - 2
- Output width: W_out = W_in - 2
- Create out[H_out][W_out].
- Loop over valid centers
- For i from 1 to H_in - 2 (center row index).
- For j from 1 to W_in - 2 (center column index).
- Accumulate 3Γ3 neighborhood
- Initialize sum = 0.
- For di in {-1, 0, 1}:
- For dj in {-1, 0, 1}:
- sum += img[i + di][j + dj].
- Compute average and assign
- average = sum / 9 (integer division or float, depending on problem statement).
- Store in output: out[i - 1][j - 1] = average (shift because output is smaller).
- Return the output image
- Return or print out.
4. Common Pitfalls
-
Index off-by-one errors
-
Mixing input indices (i, j) with output indices (i-1, j-1) when the output is smaller.
-
Accidentally going out of bounds (i-1 or i+1 beyond the image).
-
Boundary handling
-
Trying to access neighbors at the border without checks.
-
Not matching the problemβs expected behavior: many coding problems expect that the blurred result omits the border.
-
Integer vs float division
-
If pixel values are integers and you use integer division, the average is truncated.
-
Check if the problem expects integer output (often yes in coding sites) or floating-point.
-
Mutating the input in-place
-
If you overwrite img while still using it to compute other pixels, results become incorrect.
-
Always use a separate output array.
5. Time & Space Complexity
- Let the input image size be HΓW.
Time complexity:
- For each of roughly (Hβ2)Γ(Wβ2) positions, you sum 9 values.
- This is O(HΓW) overall (constant work per pixel).
Space complexity:
- Additional output array of size (Hβ2)Γ(Wβ2).
- This is O(HΓW) extra space (same order as input).