Python+OpenCV中值滤波

中值滤波,图像平滑处理,可消除椒盐噪声,其基本思路是通过滤波器遍历图像,取每个滤波器区域像素值中值为新的像素值。
算法思路如下:
(1)输入图像并转灰;
(2)为灰度图添加椒盐噪声(实验需要,体现中值滤波效果,添加椒盐噪声算法思路参看上一篇博文);
(3)遍历像素点,将滤波器区域中的像素值放入一维数组中;
(4)对一维数组进行选择排序,并将中间值赋给滤波器中心,即将遍历到的原图像像素点改为滤波器区域中值;
(5)输出中值滤波后的图像。
代码如下:

import cv2 as cv
import numpy as np

def rgb2gray(img):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range(h):
        for j in range(w):
            img1[i,j]=0.144*img[i,j,0]+0.587*img[i,j,1]+0.299*img[i,j,2]
    return img1

def noise(img,snr):
    h=img.shape[0]
    w=img.shape[1]
    img1=img.copy()
    sp=h*w   # 计算图像像素点个数
    NP=int(sp*(1-snr))   # 计算图像椒盐噪声点个数
    for i in range (NP):
        randx=np.random.randint(1,h-1)   # 生成一个 1 至 h-1 之间的随机整数
        randy=np.random.randint(1,w-1)   # 生成一个 1 至 w-1 之间的随机整数
        if np.random.random()<=0.5:   # np.random.random()生成一个 0 至 1 之间的浮点数
            img1[randx,randy]=0
        else:
            img1[randx,randy]=255
    return img1

def median(img):
    h=img.shape[0]
    w=img.shape[1]
    img1 = np.zeros((h, w), np.uint8)
    for i in range (1,h-1):
        for j in range (1,w-1):
            temporary = np.zeros(9, np.uint8)
            s=0
            for k in range (-1,2):
                for l in range (-1,2):
                    temporary[s]=img[i+k,j+l]
                    s+=1
            for y in range (8):
                count=y
                for x in range (y,8):
                    if temporary[count]>temporary[x+1]:
                        count=x+1
                temporary[y],temporary[count]=temporary[count],temporary[y]
            median=temporary[4]
            img1[i,j]=median
    return img1

image=cv.imread("D:/Testdata/selina.png")
grayimage=rgb2gray(image)
SNR=0.9   # 将椒盐噪声信噪比设定为0.9
noiseimage=noise(grayimage,SNR)
medianimage=median(noiseimage)
cv.imshow("grayimage",grayimage)
cv.imshow("noiseimage",noiseimage)
cv.imshow("medianimage",medianimage)
cv.waitKey(0)
cv.destroyAllWindows()

实验结果:

从结果中可以清晰的看到椒盐噪声被中值滤波器滤清,效果相对理想。

你可能感兴趣的:(中值滤波)