how to remove salt and pepper noise from images using python?

20,541

Solution 1

You should use median filter, it is easy to implement and work very fine for salt and pepper noise.

Solution 2

As Olivier suggested, the median filter provides the best result.

Here is the code I generated for adding salt and pepper noise into an image. The code is for python with OpenCV 3.0.0 :

import numpy as np
import cv2

img = cv2.imread('3.jpg', 1)
row,col,ch = img.shape
p = 0.5
a = 0.009
noisy = img

  # Salt mode
num_salt = np.ceil(a * img.size * p)
coords = [np.random.randint(0, i - 1, int(num_salt))
          for i in img.shape]
noisy[coords] = 1

  # Pepper mode
num_pepper = np.ceil(a * img.size * (1. - p))
coords = [np.random.randint(0, i - 1, int(num_pepper))
          for i in img.shape]
noisy[coords] = 0

cv2.imshow('noisy', noisy)

Here is the code to use the median filter:

median_blur= cv2.medianBlur(noisy, 3)
cv2.imshow('median_blur', median_blur)  

cv2.waitKey()
cv2.destroyAllWindows()

The window used to blur the noisy image can be modified as per requirement.

Share:
20,541
Admin
Author by

Admin

Updated on September 30, 2020

Comments

  • Admin
    Admin over 3 years

    I have tried to implement the following algorithm but the resulting image looks the same.

    Step 1: Read Noisy Image.

    Step 2: Select 2D window of size 3x3 with centre element as processing pixel. Assume that the pixel being processed is P ij .

    Step 3: If P ij is an uncorrupted pixel (that is, 0< P ij <255), then its value is left unchanged.

    Step 4: If P ij = 0 or P ij = 255, then P ij is a corrupted pixel.

    Step 5: If 3/4 th or more pixels in selected window are noisy then increase window size to 5x5. Step 6: If all the elements in the selected window are 0‟s and 255‟s, then replace P ij with the mean of the elements in the window else go to step 7.

    Step 7: Eliminate 0‟s and 255‟s from the selected window and find the median value of the remaining elements. Replace Pij with the median value.

    Step 8: Repeat steps 2 to 6 until all the pixels in the entire image are processed.

    Here is my code. Please suggest improvements.

    import Image
    
    im=Image.open("no.jpg")
    im = im.convert('L')
    
    for i in range(2,im.size[0]-2):
        for j in range(2,im.size[1]-2):
            b=[]
            if im.getpixel((i,j))>0 and im.getpixel((i,j))<255:
                pass
            elif im.getpixel((i,j))==0 or im.getpixel((i,j))==255:
                c=0
                for p in range(i-1,i+2):
                    for q in range(j-1,j+2):
                        if im.getpixel((p,q))==0 or im.getpixel((p,q))==255: 
                            c=c+1
                if c>6:
                    c=0
                    for p in range(i-2,i+3):
                        for q in range(j-2,j+3):
                            b.append(im.getpixel((p,q)))
                            if im.getpixel((p,q))==0 or im.getpixel((p,q))==255:
                                c=c+1
                    if c==25:
                        a=sum(b)/25
                        print a
                        im.putpixel((i,j),a)
                    else:
                        p=[]
                        for t in b:
                            if t not in (0,255):
                                p.append(t)
                        p.sort()
                        im.putpixel((i,j),p[len(p)/2])
                else:
                    b1=[]
                    for p in range(i-1,i+2):
                        for q in range(j-1,j+2):
                            b1.append(im.getpixel((p,q)))
                    im.putpixel((i,j),sum(b1)/9)
    
    im.save("nonoise.jpg")   
    
  • Admin
    Admin about 10 years
    Even though I have some pixels with values 0 and 255, the output image is the same as the input image.