一、加噪
1.加入高斯噪声与椒盐噪声
先对图片进行灰度转换,转换后的图像可以通过skimage中的库对原图分别加入高斯噪声与椒盐噪声。
import skimage
import cv2
import matplotlib.pylab as plt
img = cv2.imread('oringal.bmp',0)
img = img/255
img_g = skimage.util.random_noise(img,'gaussian',mean=0,var=0.05)
img_s = skimage.util.random_noise(img,'salt')
plt.subplot(131)
plt.imshow(img,'gray')
plt.title('oringal')
plt.subplot(132)
plt.imshow(img_g,'gray')
plt.title('gaussian')
plt.subplot(133)
plt.imshow(img_s,'gray')
plt.title('salt')
plt.show()
得到的结果为
二、去噪过程
目前有两个被噪音影响的图像,一个是被均匀噪声影响的图像,一个是被椒盐噪声影响的图像。
接下来分别使用均值滤波器、高斯滤波器、与中值滤波器进行处理。
1、均值滤波
直接对邻域内各像素的灰度值求平均,再除以像素个数,作为模板中心的新灰度值。
易于实现,速度快
使图像模糊,特别是轮廓边缘不清晰
通过噪声平均去除一定的噪声
模板越大,导致图片越模糊
2、高斯滤波器
图像上,靠近原点的位置地势高,距离原点越远则地势越低。
相应地,卷积核也是中心数值最大,并向四周减小,减小的幅度并不是随意的,而是要求整个卷积核近似高斯函数的图像。 高斯滤波实质是一种加权平均滤波。
高斯分布函数指的就是概率论中的正态分布的概率密度函数,均值为0时的一维和二维公式如下:
,
3、中值滤波
中值滤波与均值滤波的区别仅限于:中值滤波是求局部中值而不是局部均值,即对参与计算的像素灰度值按大小排序,然后取位置居中的像素灰度值。
目的:既要消除噪声又要保持图像的细节
步骤:
1)模板游走
2)将mask下对应的灰度值(奇数)排序
3)用中间值代替 f(x,y), 消除孤立的噪声点
从小到大排列,取中间值:
198 200 201 202 205 206 207 208 212
经过中值滤波,与周围像素幅度值差别比较大的像素改取与周围像素接近的值,从而达到消除孤立噪声点的目的。
中值滤波的原理:
在图像局部中,散乱噪声点的灰度值一般较大或较小,求中值可以自动将其消除。中值直接取自某个像素的灰度值,所以能较好地保持图像景物原状(既消噪声又不模糊)。
中值滤波的特点:
消噪声效果与模板的尺寸和形状(参与运算的像素数)有关图像中尺寸小于模板尺寸一半的过亮或过暗区域将会在滤波后被消除掉,对消除随机脉冲噪声非常有效。
二维中值滤波器的窗口是二维的,其形状有很多种,如直线形、方形、圆形、十字形、圆环形、菱形等。
4、代码实现
import cv2
import matplotlib.pyplot as plt
img_avg = cv2.imread('avgnoise.bmp',0)
img_salt = cv2.imread('saltnoise.bmp',0)
img_avgprocess = cv2.blur(img_avg,(5,5)) #均值滤波
img_saltprocess = cv2.blur(img_salt,(5,5))
img_avgGauss = cv2.GaussianBlur(img_avg,(5,5),0.5) #高斯滤波,核尺寸为5×5
img_saltGauss = cv2.GaussianBlur(img_salt,(5,5),0.5)
img_avgMiddle = cv2.medianBlur(img_avg,5) #中值滤波,核尺寸为5×5
img_saltMiddle = cv2.medianBlur(img_salt,5)
param = [
(img_avg,'oringalIMGavg'),
(img_salt,'oringalIMGSALT'),
(img_avgprocess,'avg_avg'),
(img_saltprocess,'salt_avg'),
(img_avgGauss,'avg_Gauss'),
(img_saltGauss,'salt_Gauss'),
(img_avgMiddle,'avg_Middle'),
(img_saltMiddle,'salt_Middle')
]
for i,(img,title) in enumerate(param,1):
plt.subplot(4,2,i)
plt.imshow(img,'gray')
plt.title(title)
plt.axis('off')
plt.show()
三、从零构建滤波器
1.均值滤波器构建
import cv2
# 求平均
def getAverage(list):
temp = 0
for i in list:
temp = temp + i
avg = temp / len(list)
return avg
def main():
image = cv2.imread('img.jpg', 0)
cv2.imshow('srcImage', image)
# 将tuple中的元素取出,赋值给height,width,channel
dst = image.copy()
height = image.shape[0]
width = image.shape[1]
# 边界不做处理
for row in range(1, height - 1):
for col in range(1, width - 1):
# 创建一个3✖️3的9阶滤波器
np = [image[row - 1][col - 1], image[row - 1][col], image[row - 1][col + 1],
image[row][col - 1], image[row][col], image[row][col + 1],
image[row + 1][col - 1], image[row + 1][col], image[row + 1][col + 1]]
# 求平均值
avg = getAverage(np)
# 给目标图像中对应像素赋灰度值
dst[row][col] = avg
cv2.imshow('dstImage', dst)
cv2.waitKey(0)
if __name__ == '__main__':
main()
部分边缘呈现模糊状况
2、中值滤波器
只更改第一个函数即可(因为当前是3×3的核),排序后得到序号为五的即可
import cv2
# 求平均
def getMiddle(list):
list.sort()
return list[4]