Actual combat | Use OpenCV to implement switch median filtering to remove periodic linear noise (steps + source code)

guide

    This article mainly introduces an example of how to use OpenCV to implement switch median filter to remove periodic linear noise, including implementation steps and source code.  

background introduction

    We all know that median filtering can remove impulse noise or salt and pepper noise in images, similar to the following figure:

picture

    We can use the median filter function provided by OpenCV to easily filter out noise and better preserve image edge features.

    Code demo:

import cv2import numpy as np
img=cv2.imread('snow.jpg',0) cv2.imshow('src',img)
dst = cv2.medianBlur(img,3)cv2.imshow('dst',dst)  
cv2.waitKey(0)  cv2.destroyAllWindows()

    3 x 3 median filter effect:

picture

    If it is linear periodic noise, can median filter still be used?

Implementation steps

    The picture below, instead of discrete salt and pepper noise, contains linear periodic noise:

picture

    Can we also directly use median filtering to remove the noise above? Try it first!

    3 x 3 median filter effect (line noise still exists):

picture

    5 x 5 median filtering effect (less line noise, but blurred image):

picture

    The above two effects are not what we want, so what should we do? A simple and effective method is provided here, referred to as switching median filtering .

    The switching median filter is to detect noise pixels first, and then only perform median filtering on the detected noise pixels, while the pixels judged to be non-noisy will no longer participate in median filtering. In this way, the details of the image are better preserved while filtering out the noise.

    Implementation steps:

  [1] Detect noisy pixels. Traverse each row in turn, calculate the gray value sum of the current row, if the gray value sum is greater than 100000, the current row is judged as a noise row, set it to 0, otherwise it is 1.

def detect(img):  (w,h) = img.shape  flt = np.ones((w,h),dtype = int)  bright = []  for y in range(h):      bright.append(np.sum(img[:][y]))  x=np.arange(512)  plt.plot(x,bright,c='b')  plt.ylabel('Brightness')  plt.savefig('Brightness.jpg')  for i in range(h):      if bright[i]>100000:          flt[:][i]=0  return flt

  [2] Do a median filter on the pixels of the noisy row. The following code demonstrates the result of mean filtering corresponding to noise pixels. Median filtering needs to be sorted to take the median value, and the effect is similar. ​​​​​​​​

def medianBlur(img): (w,h) = img.shape for i in range(2,w-1):    for j in range(2,h-1):      n = 0      s = 0      if img[i][j] == 0:          for ii in range(i-1,i+1):              for jj in range(j-1,j+1):                  if img[ii][jj] != 0:                    n = n + 1                    s = s + img[ii][jj]      if n != 0:          img[i][j] = int(s/n) return img

  【3】Call the test and process the result. ​​​​​​​​

if __name__ == '__main__':    fileName = 'lena.jpg'    gray = cv2.imread(fileName,0)    cv2.imshow('src', gray)    flt = detect(gray)    grayWithoutNoise = gray*flt    mb = medianBlur(grayWithoutNoise)    mb = mb[1:512,1:512]       mb = np.array(mb,dtype=np.uint8)    cv2.imshow('result',mb)    cv2.waitKey(0)    cv2.destroyAllWindows()

picture

    Overall, the effect is not bad. While removing noise, the details are better preserved. Of course, there are other implementation methods, we will introduce them later, so stay tuned.

Guess you like

Origin blog.csdn.net/stq054188/article/details/132257273