图像均值滤波与中值滤波对比研究

python实现图像读取,椒盐和高斯噪点生成,以及中值和均值滤波

PS:其实我不仅会c++,也自学过python(震惊.jpg)


不知道椒盐噪声,白噪声,高斯噪声,均值滤波或中值滤波的请自行百度。

滤波降噪

数字图像在采集和传输处理的过程中经常受到设备、环境等因素的影响,如光电转换过程中敏感元器件灵敏度的不均匀性、数字化过程中的量化噪声、传输过程中的误差以及人为因素等,均使图像质量变差,含有各种随机噪声,甚至有时候,这种随机噪声会对图像质量产生较大的影响。如果图像中噪声强度比较大的话,一方面会影响人们观赏图像时的视觉效果另一方面,用计算机对图像进行处理时,噪声还有可能影响到图像处理的结果。图像去噪就是要保留图像中的有用信息,减少或消除图像中的干扰和噪声。

——《基于中值滤波和小波变换的图像去噪研究》杨辉

噪声

噪声按照概率分类:

高斯噪声:指概率密度函数服从高斯分布(即正态分布)的一类噪声。

均匀噪声

脉冲噪声:突然爆发又很快消失的噪声

中值滤波&均值滤波介绍

中值滤波是广泛应用于去除噪声的一种基于排序统计理论的能有效抑制噪声的非线性信号处理技术。 其实现原理是将图片中的像素$f(x,y)$,用该像素周围某个范围内的所有像素值进行排序统计的中值替换掉。我们不妨设这个范围为一个边长为$2n+1$的正方形,那么这个正方形便可以称作滤波窗口。 该算法可表示为$f(i,j)=median\{f(x,y) \mid x\in[i-r,i+r],y\in[j-r,j+r]\}$。 而均值滤波则也与其类似,能表示成:$f(i,j)=\frac{1}{(2n+1)^2}\times\sum\limits_{x=i-r}^{i+r}\sum\limits_{y=j-r}^{i+r}(f(x,y))$

代码的实现原理

在白天拍摄一些几乎无噪点的图片,通过pyhton的opencv库实现其读取并转换为mat矩阵,人为生成高斯噪点(如有余力也可少量加入椒盐噪点),分别进行中值滤波,均值滤波。然后将处理后的图片每个像素的RGB色度与原图(无噪点)相减并取绝对值,然后进行统计比较。

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import cv2
import numpy as np
import random as r
def salt(origin_img, n):#椒盐噪声
    img=origin_img.copy()
    for k in range(n):
        i = int(np.random.random() * img.shape[1])
        j = int(np.random.random() * img.shape[0])
        if img.ndim == 2:
            img[j,i] = 255
        elif img.ndim == 3:
            img[j,i,0]= 255
            img[j,i,1]= 255
            img[j,i,2]= 255
    return img
def makegauss(origin_img):#高斯噪声
    img=origin_img.copy();
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            g=r.gauss(0,10)
            r1=np.where((g+img[i,j])>255,255,(g+img[i,j]))
            r2=np.where(r1<0,0,r1)
            img[i,j]=np.round(r2)
    return img
def picdiff(img1,img2):
    r=0;g=0;b=0
    for i in range(img1.shape[0]):
        for j in range(img1.shape[1]):
            r+=abs(int(img1[i,j,0])-int(img2[i,j,0]))
            g+=abs(int(img1[i,j,1])-int(img2[i,j,1]))
            b+=abs(int(img1[i,j,2])-int(img2[i,j,2]))
    print("r:",r,"g:",g,"b:",b)
#------------------------------------------
#read
path2pic=".\\"#input("input the path:") 
picname="try.bmp"#input("input pic name:")
winsize=3#int(input("size of win:"))
img01 = cv2.imread(path2pic+picname)#读取目标图片
#------------------------------------------
#salt
imgwithsalt=salt(img01,10000)
#中值滤波
img_medianBlur=cv2.medianBlur(imgwithsalt,winsize)
#均值滤波
img_Blur=cv2.blur(imgwithsalt,(winsize,winsize))
#显示
cv2.namedWindow("salt")
cv2.imshow("salt",imgwithsalt)
cv2.namedWindow("medianBlur")
cv2.imshow("medianBlur",img_medianBlur)
cv2.namedWindow("Blur")
cv2.imshow("Blur",img_Blur)
cv2.waitKey (0)
cv2.destroyAllWindows()
#还原程度
print("diff with origin pic:")
picdiff(img01,imgwithsalt)#原图与噪点图的差异
picdiff(img01,img_medianBlur)
picdiff(img01,img_Blur)
print("---------------------------")
#------------------------------------------
#gauss
imgwithgauss=makegauss(img01)
#中值滤波
img_medianBlur=cv2.medianBlur(imgwithgauss,winsize)
#均值滤波
img_Blur=cv2.blur(imgwithgauss,(winsize,winsize))
#显示
cv2.namedWindow("gauss")
cv2.imshow("gauss",imgwithgauss)
cv2.namedWindow("medianBlur")
cv2.imshow("medianBlur",img_medianBlur)
cv2.namedWindow("Blur")
cv2.imshow("Blur",img_Blur)
cv2.waitKey (0)
cv2.destroyAllWindows()
#还原程度
print("diff with origin pic:")
picdiff(img01,imgwithgauss)#原图与噪点图的差异
picdiff(img01,img_medianBlur)
picdiff(img01,img_Blur)
#------------------------------------------
#存储
#save=input("save or not?[y/n]:")
#if save=="y":
#   cv2.imwrite(path2pic+"medianBlur.bmp",img_medianBlur)
#   cv2.imwrite(path2pic+"Blur.bmp",img_Blur)
#   cv2.imwrite(path2pic+"white.bmp",imgwithgauss)