0

I have this image which has been heavily obscured by impulse(salt&pepper) noise and I am trying to filter it using a median filter. I was able to filter the picture to a slightly readable state, but I want them to filter out to a much more clear image. How can my median filter be improved?

The picture is represented by a (n,m,4) array, with grayscale rgb values between 0 (black) and 1 (white). I used a 3x3 matrix for my median filter, and gave the image a 1-pixel wide white border around each edge.

def medianFilter(image=np.ndarray):
for i in range(1,image.shape[0]):
    for j in range(1,image.shape[1]):
        square = np.array(image[i-1:i+2,j-1:j+2])            
        if(square[1,1][0]==1 or square[1,1][0]==0):
            square[1,1] = np.median((square))
            image[i-1:i+2,j-1:j+2] = square
return image

Unfiltered Image Image Data)first 5 rows,columns) Filtered Image

Full Original Picture

M. Gaddaffi
  • 41
  • 1
  • 7
  • You could try using an Opening or closing filter. But I still think median is the best filter for salt and pepper noise. – Aishwarya Patange Apr 09 '22 at 05:23
  • @M.Gaddaffi I suggest that you use `OpenCV`: `cv2.medianBlur(img, kernel)` and try different kernel sizes, then you can do thresholding and after that you can apply Morphological operations. – Bilal Apr 09 '22 at 06:20
  • If you can load the original image It would help us help you :) – Tomer Geva Apr 09 '22 at 07:40
  • 1
    "original image" means the image itself, not a plot of it. -- make a mask for the noise pixels. then **ignore** those in all restoration work. -- someone might want you to use inpainting? -- this is a class assignment. please state that upfront. and state the whole assignment. – Christoph Rackwitz Apr 09 '22 at 08:40
  • @TomerGeva I added the original image to the post – M. Gaddaffi Apr 09 '22 at 19:03
  • @TomerGeva thank you! The kernel size change was very helpful! – M. Gaddaffi Apr 10 '22 at 01:02

1 Answers1

4

OK so starting with the picture you uploaded, we can do the following:

import numpy as np
from scipy.signal import medfilt2d
import matplotlib.pyplot as plt
import cv2

img           = cv2.imread('fBq2z.png', cv2.IMREAD_GRAYSCALE)

Median Filtering

The best way to handle salt & pepper noise is to use median filter. Since the median filter is directly affected by the kernel size, too small is not enough for a good median estimation and too big will catch artifacts in the median filter. After playing with different kernel sizes, 11 was best.

median_kernel = 11
# median filtering
median_filtered = medfilt2d(img, kernel_size=median_kernel)

The result of the median filterring is: enter image description here

Image inpainting

The next stage will be to fix the places where the salt & pepper was prominent. This is done using image inpainting. Two algorithms are typically used for traditional inpainting, modern approaches use neural networks for that.

I will use Telea's method. We first generate the mask where we have residuals of noise:

# creating a mask for the salt&pepper
mask = np.zeros_like(median_filtered)
mask[median_filtered < 5]   = 255
mask[median_filtered > 250] = 255

the resulted mask:

enter image description here

And apply the inpainting

last = cv2.inpaint(median_filtered,mask,3,cv2.INPAINT_TELEA)

This gives us the final result:

enter image description here

Tomer Geva
  • 1,764
  • 4
  • 16