How to reduce noise in an image using a median filter

Digital image processing is a significant aspect of data science. It is used in image modification and enhancement to lead to a greater understanding of data.

One aspect of image enhancement is the reduction of noise, which is the random variation of brightness in an image. This can be seen in the image below.

widget

To reduce the noise in an image, a median filter is used. A filter is a set of pixels that is run through each pixel of the original image, replacing them with the result of the specific operation. The median filter of size nn covers nn xx nn pixels with the current pixel at its center and replaces it with the median of the entire window.

In the code below, we use a 3x3 median filter that replaces each pixel with the median of its respective window and in turn, reduces the noise of the image.

Code

#import library
import statistics
#function for applying median filter
def medianFilter(img):
width, height= img.size
#create an array for resultant image
result = np.zeros((height, width))
#traverse through the pixels of the image
for i in range(width):
for j in range(height):
#initialize variables
currentElement=0; left=0; right=0; top=0; bottom=0; topLeft=0;
topRight=0; bottomLeft=0; bottomRight=0;
#get current pixel
currentElement = img.getpixel((i,j))
#offset is equal to 1 in a 3x3 filter
offset=1
#get left, right, bottom and top pixels
#with respect to current pixel
if not i-offset < 0:
left = img.getpixel((i-offset,j))
if not i+offset > width-offset:
right = img.getpixel((i+offset,j))
if not j-offset < 0:
top = img.getpixel((i,j-offset))
if not j+offset > height-1:
bottom = img.getpixel((i,j+offset))
#get top left, top right, bottom left and bottom right pixels
#with respect to current pixel
if not i-offset < 0 and not j-offset < 0:
topLeft = img.getpixel((i-offset,j-offset))
if not j-offset < 0 and not i+offset > width-1:
topRight = img.getpixel((i+offset,j-offset))
if not j+offset > height-1 and not i-offset < 0:
bottomLeft = img.getpixel((i-offset,j+offset))
if not j+offset > height-1 and not i+offset > width-1:
bottomRight = img.getpixel((i+offset,j+offset))
#get median of all pixels retrieved
med=statistics.median([currentElement,left,right,top,bottom,topLeft,topRight,bottomLeft,bottomRight])
#put median in the same position in resultant array
result[j][i] = med
#return resultant array
return result

Explanation

  • First, we make an array that is the same size as the original image array.

  • We then loop through the pixels of the image and get the left, right, bottom, top, top left, top right, bottom left, and bottom right pixels in addition to the current pixel and store them in temporary variables.

  • The median of these variables is then calculated and stored in the resultant array. The previous image after the application of a 3x3 median filter is displayed below, showing significant noise reduction.

widget