图像平滑
准备工作:
使用低通滤波器可以达到图像模糊的目的。这对去除噪音很有帮助。其实就是去除图像中的高频成分(噪音,边界)
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 显示函数
def cv_show(name, img):
cv2.imshow(name, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread('chen3.jpg')
1.2D卷积
# 2D卷积
'''
和信号一样,我们可以对2D图像实施低通滤波(LPF)高通滤波(HPF)
LPF帮助我们去除噪音,模糊图像。HPF帮助我们找到图像的边缘
'''
'''
filter2D(src,ddepth,kernel, anchor,deltaborderType);
src: 输入图像
ddepth: 目标图像深度 -1 目标图像和原图像深度保持一致
kernel: 卷积核 一个单通道浮点型矩阵
anchor: 内核的基准点,默认值是(-1,-1),位于kernel中心距离
基准点即kernel中与进行处理的像素点重合的点
delt:存储目标图像前可选的添加到像素的值,默认值为0
aborderType:像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算
'''
img = cv2.imread('chen1.jpg', 0)
# 给出卷积核
kernel = np.ones((5, 5), np.float32) / 25
res = cv2.filter2D(img, -1, kernel)
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('img')
plt.subplot(122), plt.imshow(res, 'gray'), plt.title('res')
plt.show()
输出结果:
2.平均
# 平均
'''
用卷积框覆盖区域所有像素的平均值来代替中心元素。
'''
img = cv2.imread('lenaNoise.png')
blur = cv2.blur(img, (5, 5))
# 3*3的矩阵 9个像素点,每个像素点的和除以9 一般都是奇数矩阵3,5,7
res = np.hstack((img, blur))
cv_show('res', res)
输出结果:
3.方框滤波
# 方框滤波
# 基本和均值一样,可以选择归一化
img = cv2.imread('lenaNoise.png')
box = cv2.boxFilter(img, -1, (3, 3), normalize=False)
'''
-1 :颜色通道数表示一致
(3,3): 3*3的矩阵
True: 做归一化,和均值滤波一样
false: 所有的和加起来 不除以9 超过255 就是255
'''
res = np.hstack((img, box))
cv_show('res', res)
输出结果:
4.高斯模糊
# 高斯模糊
'''
把卷积核换成高斯核(方框不变,将原来每个方框的值是相等的换为是符合高斯分布的,
方框中心的值最大,其余方框根据距离中心元素的距离递减,构成一个高斯小山包。
原来的求平均值变为现在求加权平均值。)
'''
img = cv2.imread('lenaNoise.png')
aussian = cv2.GaussianBlur(img, (3, 3), 1)
'''
img:输入的图像
(3, 3): 高斯核的大小
1:高斯内核在x方向的标准偏差
'''
res = np.hstack((img, aussian))
cv_show('res', res)
输出结果:
5.中值模糊
# 中值模糊
'''
用与卷积框对应像素的中值来替代中心像素的值。这个滤波器常用来去除椒盐噪声。
前面的滤波器都是用计算得到的一个值取代中心像素的值,而中值滤波是用中心像素
周围的值来取代他。
'''
img = cv2.imread('lenaNoise.png')
median = cv2.medianBlur(img, 3)
res = np.hstack((img, median))
cv_show('res', res)
输出结果:
6.双边滤波
# 双边滤波
'''
cv2.bilateralFilter()
能够保持边界清楚的情况下有效去除噪声。这种操作较慢。
双边滤波在同时使用空间高斯权重和灰度值相似性高斯权重。空间高斯函数确保只有
近邻区域的像素对中心点有影响。灰度值相似性高斯函数确保只有与中心像素灰度值
相近的才会被用来做模糊运算。
'''
img = cv2.imread('lenaNoise.png')
bilate = cv2.bilateralFilter(img, 3, 75, 75)
'''
9:邻域直径
75:空间高斯函数标准差
75:灰度值相似性高斯函数标准差
'''
res = np.hstack((img, bilate))
cv_show('res', res)
输出结果:
7.图像平滑处理对比
# 图像平滑处理对比
img = cv2.imread('lenaNoise.png')
blur = cv2.blur(img, (5, 5)) # 平均
box = cv2.boxFilter(img, -1, (3, 3), normalize=False) # 方框
aussian = cv2.GaussianBlur(img, (3, 3), 1) # 高斯
median = cv2.medianBlur(img, 3) # 中值
bilate = cv2.bilateralFilter(img, 3, 75, 75) # 双边
images = [img, blur, box, aussian, median, bilate]
titles = ['img', 'blur', 'box', 'aussian', 'median', 'bilate']
for i in range(6):
# BGR 转为RGB
b, g, r = cv2.split(images[i])
images[i] = cv2.merge((r, g, b))
plt.subplot(231 + i), plt.imshow(images[i]), plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
输出结果:
放大之后就可以看出来不同