No description has been provided for this image

Median Filtering¶

Faisal Qureshi
Professor
Faculty of Science
Ontario Tech University
Oshawa ON Canada
http://vclab.science.ontariotechu.ca

Copyright information¶

© Faisal Qureshi

License¶

Creative Commons Licence
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

Lesson Plan¶

  • Median filtering
In [1]:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

Salt-and-pepper noise¶

Lets add some salt-and-pepper (or impulse) noise to the image. This noise can be caused by sharp and sudden disturbances in the image signal. It presents itself as sparsely occurring white and black pixels.

Check here for more information.

In [2]:
im = cv.imread('data/bambi.jpg',0).astype(np.uint8)

plt.figure(figsize=(10,10))
plt.imshow(im, cmap='gray');
No description has been provided for this image

Lets add some salt and pepper noise

In [3]:
black = 10
white = 250
mask = np.empty(im.shape, np.uint8)
mask = cv.randu(mask, 0, 255)
im[mask < black] = 0
im[mask > white] = 255

plt.figure(figsize=(10,10))
plt.imshow(im, cmap='gray');
No description has been provided for this image

Gaussian smoothing to get rid of salt-and-pepper noise¶

The following example supports the assertion that Gaussian smoothing fails to get rid of the salt-and-pepper noise.

In [4]:
half_width = 2
sigma = 1

plt.figure(figsize=(10,10))
plt.imshow(cv.GaussianBlur(im, (2*half_width+1, 2*half_width+1), sigma), cmap='gray');
No description has been provided for this image

Median filtering¶

This is a non-linear filtering technique. (What does that mean?) It is widely used in digital image processing and signal processing to get rid of speckle and salt-and-pepper noise while preserving edges.

From Wikipedia article on median filtering

For small to moderate levels of Gaussian noise, the median filter is demonstrably better than Gaussian blur at removing noise whilst preserving edges for a given, fixed window size. However, its performance is not that much better than Gaussian blur for high levels of noise, whereas, for speckle noise and salt-and-pepper noise (impulsive noise), it is particularly effective. Because of this, median filtering is very widely used in digital image processing.

Aside: Speckle is a granular interference that inherently exists in and degrades the quality of the active radar, synthetic aperture radar (SAR), medical ultrasound and optical coherence tomography images. See here) for more information.

No description has been provided for this image
(Image from Meskine, Fatiha & Miloud, chikr el-mezouar & Taleb, Nasreddine. (2010). A Rigid Image Registration Based on the Nonsubsampled Contourlet Transform and Genetic Algorithms. Sensors. 10. 8553-8571.)

Median filtering in 1D¶

Replace a value at location $i$ with the median of its neighbourhood values.

(Treat neighbourhood in a similar vein as the filter width in the case of linear filtering.)

In [5]:
x = np.random.rand(10)*255
x = x.astype(np.uint8)
print(f'x = {x}')
x = [ 99 108  51   0 195 209   5 172 206 161]

Code examples¶

Picking values around $i$

In [6]:
# %load solutions/median-filtering/solution-01.py

half_width = 2
s = half_width
e = len(x)-half_width

for i in range(s,e):
    print(f'center = {i}, values={x[i-half_width:i+half_width+1]}')
center = 2, values=[ 99 108  51   0 195]
center = 3, values=[108  51   0 195 209]
center = 4, values=[ 51   0 195 209   5]
center = 5, values=[  0 195 209   5 172]
center = 6, values=[195 209   5 172 206]
center = 7, values=[209   5 172 206 161]

Picking median values for $i$ using its neighbourhood

In [7]:
# %load solutions/median-filtering/solution-02.py

result = np.copy(x)
for i in range(s,e):
    neighbourhood = x[i-half_width:i+half_width+1]
    result[i] = np.median(neighbourhood)
    
print(f'result = {result}')
result = [ 99 108  99 108  51 172 195 172 206 161]

Median filtering in 2D¶

In [8]:
half_width = 1

plt.figure(figsize=(20,15))
plt.subplot(121)
plt.title('Gaussian smoothing')
plt.imshow(cv.GaussianBlur(im, (2*half_width+1, 2*half_width+1), sigma), cmap='gray')
plt.subplot(122)
plt.title('Median filtering')
plt.imshow(cv.medianBlur(im, 2*half_width+1), cmap='gray');
No description has been provided for this image
No description has been provided for this image
In [ ]: