原文为段立辉翻译,感谢Linux公社www.linuxidc.com
此文档为自学转述,如有侵权请联系本人。
目标:
• 学习使用不同的低通滤波器对图像进行模糊
• 使用自定义的滤波器对图像进行卷积(2D 卷积)
1、2D卷积
同一维信号一样,我们也可以对2D图像实施低通滤波(LPF),高通滤波(HPF)等,LPF帮我们去除噪音,模糊图像。HPF帮我们找到图像的边缘。
Opencv 提供的函数cv2.filter2D() 可以对一副图像进行卷积操作。如下图是一个5✖️5的平均滤波器核。
操作如下,将核放在图像的一个像素A上,求与核对应的图像上25(5✖️5)个像素的和,再取平均数,用这个平均数代替像素A上的值。重复以上的操作知道将图像的每一个像素都更新一遍。
import numpy as np
import cv2
import matplotlib as mlp
mlp.use('TkAgg')
from matplotlib import pyplot as plt
img = cv2.imread('./opencv_learn/opencv.png')
# cv2.imshow('img',img)
# cv2.waitKey(0)
kernel = np.ones((5,5), np.float32)/25
dst = cv2.filter2D(img, -1, kernel)
# plt.subplot(121),plt.imshow(img),plt.title('original')
# plt.xticks([]),plt.yticks([])
# plt.subplot(122),plt.imshow(dst),plt.title('averaging')
# plt.xticks([]),plt.yticks([])
# plt.show()
while(1):
cv2.imshow('img',img)
cv2.imshow('dst',dst)
k = cv2.waitKey(1)
if k == ord('q'):
break
cv2.destroyAllWindows()
2、平均
这是由一个归一化的卷积完成的,他只是用卷积框覆盖区域所有像素的平均值来代替中心元素。
使用函数:cv2.blur()和 cv2.boxFilter()
注意:如果你不想使用归一化卷积框,你应该使用 cv2.boxFilter(),这时要 传入参数 normalize=False
blur = cv2.blur(img,(3,3))
3、高斯模糊
现在把卷积核换成高斯核(简单来说,方框不变,原来的每个方框的值是相等的,现在里面的值是符合高斯分布的,方框中心的值最大,其余值根据距离中心元素的距离递减,原来的求平均数变成求加权平均数,权就是方框里面的值)
实现函数是cv2.GaussianBlur()
需要指定高斯核的宽和高(必须是奇数),以及高斯函数沿X,Y方向的标准差,两个方向的标准差取值相同,如果都为0,则函数会根据核函数的大小自己计算。高斯滤波可以有效的从图像中去除高斯噪音。blur = cv2.GaussianBlur(img, (5,5)0)
4、中值模糊
用卷积框对应像素的中值来替代中心像素的值。去除椒盐噪声效果比较好。
median = cv2.medianBlur(img,5)
5、双边滤波
cv2.bilateralFilter() 能在保持边界清晰的情况下有效的去除噪音。缺点速度较慢
高斯滤波器只考虑像素之间的空间关系,而不会考虑像素值之间的关系(像素的相似度),所以这种方式会把边界也模糊掉。
双边滤波在同时使用空间高斯权重和灰度值相似性高斯权重。空间高斯权重确保只有领近区域的像素对中心点有影响,灰度值相似性高斯函数确保只有与中心像素灰度值相似才会被用来做模糊运算。
#cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace)
#d – Diameter of each pixel neighborhood that is used during filtering. # If it is non-positive, it is computed from sigmaSpace
# 9 邻域直径,两个 75 分别是空间高斯函数标准差,灰度值相似性高斯函数标准差
blur = cv2.bilateralFilter(img,9,75,75)