Computer vision
noisymedian 5×5

Image Filtering

Change each pixel using its neighbours: smooth away noise, keep the edges, or bring them out.

What is image filtering?

Image filtering applies a mathematical operation to each pixel based on its neighbourhood.

Noise reduction

Smoothing.

Edge enhancement

Sharpening.

Feature detection

Gradients, edges.

Preprocessing

For other algorithms.

Key idea: output pixel = f(input pixel + its neighbours)

Types of filters

Smoothing (low-pass)

  • Box / average: simple averaging
  • Gaussian: weighted averaging
  • Median: replaces with the median value

Sharpening (high-pass)

  • Enhances edges and details
  • The opposite of smoothing

Edge detection

  • Sobel, Prewitt, Scharr
  • Detect boundaries and gradients

See Edge Detection.

Averaging (box) filter

cv2.blur(img, (3, 3))
cv2.blur(img, (9, 9))
cv2.blur(img, (21, 21))

Blur filter in OpenCV


        import cv2
        import numpy as np
        # simple averaging blur
        blurred = cv2.blur(img, (5, 5))
        # ans: a 5x5 kernel: averages 25 pixels
        # what does the kernel size mean?
        # (5, 5) means 5 rows x 5 columns
        # ans: larger kernel = more blur
        # blur with different kernel sizes
        blur3 = cv2.blur(img, (3, 3))
        blur7 = cv2.blur(img, (7, 7))
        # ans: blur3 < blur7 (7x7 blurs more)
      

Gaussian blur

Gaussian kernel: weights the centre pixel more than the edges.

Advantages over the box filter:

  • A more natural blur (mimics optical blur)
  • Preserves edges better
  • Fewer ringing artefacts

Gaussian blur in OpenCV


        # gaussian blur
        gaussian = cv2.GaussianBlur(img, (5, 5), 0)
        # ans: 5x5 kernel, sigma=0 (computed from the kernel size)
        # what is sigma?
        # ans: the standard deviation: it controls blur strength
        # ans: larger sigma = more blur
        # gaussian with a specific sigma
        gaussian = cv2.GaussianBlur(img, (5, 5), sigmaX=2.0)
        # ans: sigma=2.0 controls the spread of the gaussian
        # kernel size must be odd
        gaussian = cv2.GaussianBlur(img, (4, 4), 0)
        # ans: ERROR! the kernel size must be odd (3, 5, 7, ...)
      

Median filter

Replace each pixel with the median of its neighbourhood.

  1. Sort all the pixels in the neighbourhood
  2. Pick the middle value (the median)
  3. Replace the centre pixel with it

Advantage: excellent for salt-and-pepper noise: it ignores outliers.

Disadvantage: slower than linear filters.

Median filter in OpenCV


        # median blur (good for salt-and-pepper noise)
        median = cv2.medianBlur(img, 5)
        # ans: 5x5 window: the median of 25 pixels
        # kernel size must be odd, and a single value
        median = cv2.medianBlur(img, 7)
        # ans: a 7x7 window
        # why median for noise?
        # ans: outliers (noise) don't affect the median
        # ans: preserves edges while removing noise
      

Bilateral filter

Smooths while preserving edges.

patch on an edge
spatial weight
intensity weight
spatial × intensity

Use case: noise reduction that keeps sharp edges, e.g. portrait smoothing.

Bilateral filter in OpenCV


        # bilateral filter (edge-preserving)
        bilateral = cv2.bilateralFilter(img, 9, 75, 75)
        # ans: d=9 (diameter), sigmaColor=75, sigmaSpace=75
        # what is d?
        # ans: the diameter of the pixel neighbourhood
        # what is sigmaColor?
        # ans: the filter sigma in colour space (intensity difference)
        # what is sigmaSpace?
        # ans: the filter sigma in coordinate space (spatial distance)
        # when to use bilateral?
        # ans: noise reduction with edge preservation
      

Every filter, on a real photo

input
output

Exercises

Answer first, then press → to check.

Exercises 1 · concepts

What does smoothing do?

Averages each neighbourhood: reduces noise, blurs the image.

What is the difference between blur and Gaussian blur?

Gaussian weights the centre more, which looks more natural.

Which filter for salt-and-pepper noise?

The median filter: it removes outliers.

Why is the bilateral filter special?

It preserves edges while smoothing.

What is the kernel size?

The neighbourhood size, e.g. 3×3 or 5×5.

Exercises 2 · concepts

What does a larger kernel mean?

More smoothing, more blur, slower processing.

Why must the kernel size be odd?

It needs a centre pixel: a symmetric neighbourhood.

What is sigma in a Gaussian?

The standard deviation: it controls the blur strength.

What is the trade-off of smoothing?

It reduces noise but also blurs edges and details.

Exercises 3 · coding


        # apply a 3x3 averaging blur
        blurred = cv2.blur(img, (3, 3))  # ans:
        # apply a 7x7 gaussian blur
        gaussian = cv2.GaussianBlur(img, (7, 7), 0)  # ans:
        # apply a median filter with kernel 5
        median = cv2.medianBlur(img, 5)  # ans:
        # apply a bilateral filter
        bilateral = cv2.bilateralFilter(img, 9, 75, 75)  # ans:
      

Exercises 4 · coding


        # gaussian blur with sigma=3
        gaussian = cv2.GaussianBlur(img, (0, 0), sigmaX=3)  # ans:
        # ans: kernel size (0, 0) is computed from sigma
        # compare blur strengths
        blur_small = cv2.blur(img, (3, 3))
        blur_large = cv2.blur(img, (9, 9))
        # ans: blur_large is much more blurred
        # apply a median blur on grayscale
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        median = cv2.medianBlur(gray, 5)  # ans:
      

Exercises 5 · mixed


        # what happens with an even kernel size?
        blurred = cv2.blur(img, (4, 4))
        # ans: works for blur, but not for GaussianBlur / medianBlur
        # which is faster: median or gaussian?
        # ans: gaussian (a linear filter) is faster than median
        # bilateral with a large sigmaColor?
        bilateral = cv2.bilateralFilter(img, 9, 150, 75)
        # ans: smooths more aggressively across similar colours
        # bilateral with a large sigmaSpace?
        bilateral = cv2.bilateralFilter(img, 9, 75, 150)
        # ans: pixels farther away count more
      

Exercises 6 · mixed


        # multiple blurs in sequence
        blur1 = cv2.GaussianBlur(img, (5, 5), 0)
        blur2 = cv2.GaussianBlur(blur1, (5, 5), 0)
        # ans: double blur = more smoothing
        # can you blur an already blurred image?
        # ans: yes: the blur accumulates
        # blur only one channel
        img[:, :, 0] = cv2.blur(img[:, :, 0], (5, 5))
        # ans: blurs only the blue channel