如何用Python去除图像中的盐和胡椒噪声?

3 投票
3 回答
30063 浏览
提问于 2025-04-17 21:23

我尝试实现以下算法,但得到的图像看起来没有变化。

第一步: 读取有噪声的图像。

第二步: 选择一个3x3的窗口,把中间的像素作为正在处理的像素。假设正在处理的像素是Pij

第三步: 如果Pij是一个正常的像素(也就是说,0小于Pij小于255),那么它的值保持不变。

第四步: 如果Pij等于0或255,那么Pij就是一个损坏的像素。

第五步: 如果在选定的窗口中,有3/4或更多的像素是有噪声的,那么将窗口的大小增加到5x5。

第六步: 如果选定窗口中的所有元素都是0或255,那么用窗口中元素的平均值替换Pij,否则继续到第七步。

第七步: 从选定窗口中去掉0和255,找到剩下元素的中位数。用这个中位数替换Pij

第八步: 重复第二步到第六步,直到整个图像中的所有像素都处理完毕。

这是我的代码。请给我一些改进的建议。

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")   

3 个回答

0

你的输入图片是什么样子的?你的算法假设只有像素值为0和255的地方是噪音。如果你的噪音像素实际上有其他的值,那么你的算法就不会起作用,你可能会看到输出和输入一模一样。

3

正如Olivier所建议的,中值滤波器能提供最佳的效果。

下面是我写的代码,用来给图片添加盐和胡椒噪声。这个代码是用Python和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)

这里是使用中值滤波器的代码:

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

cv2.waitKey()
cv2.destroyAllWindows()

用来模糊噪声图片的窗口可以根据需要进行调整。

7

你应该使用中值滤波器,这个方法简单易用,对于盐和胡椒噪声(就是那种黑白点的干扰)效果很好。

撰写回答