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 = [213 109  37 253 123 153 146 233 150 106]

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=[213 109  37 253 123]
center = 3, values=[109  37 253 123 153]
center = 4, values=[ 37 253 123 153 146]
center = 5, values=[253 123 153 146 233]
center = 6, values=[123 153 146 233 150]
center = 7, values=[153 146 233 150 106]

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 = [213 109 123 123 146 153 150 150 150 106]

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 [ ]: