本文是OpenCV图像视觉入门之路的第10篇文章,本文详细的在图像上面进行了图像均值滤波、方框滤波 、高斯滤波、中值滤波、双边滤波、2D卷积等操作。
OpenCV 图像平滑处理目录
1 均值滤波
2 方框滤波
3 高斯滤波
4 中值滤波
5 双边滤波
6 2D卷积(自定义卷积核实现卷积)
1 均值滤波
OpenCV 中的简单滤波(例如均值滤波或中值滤波)可能会使图像变得模糊,因为它们会平滑图像中的细节和边缘。如果滤波的程度过强,则可能会导致图像失真,使其看起来更差。因此,滤波的程度需要适当地控制,以获得最佳效果。
import cv2
import numpy as np
from numpy import unicode
if __name__ == '__main__':
img1 = cv2.imread("D:/Jupyter_Notebooks/0.jpg") # 读取彩色图像(BGR)
# 均值滤波
# 简单的平均卷积操作
img_blur1 = cv2.blur(img1, (3, 3)) # 使用3*3的卷积核
img_blur2 = cv2.blur(img1, (30, 30)) # 使用30*30的卷积核
cv2.imshow("blur1", img_blur1) # 显示叠加图像 dst
cv2.imshow("blur2", img_blur2) # 显示叠加图像 dst
cv2.imshow("image", img1) # 显示叠加图像 dst
cv2.waitKey(0)
cv2.destroyAllWindows()
2 方框滤波
方框滤波是一种图像平滑技术,在 OpenCV 中可以使用。方框滤波的主要作用是对图像进行去噪和平滑处理,使图像变得更加平滑,减少图像的锯齿状、噪声等不规则的部分。在图像处理中,方框滤波通常作为预处理步骤,以提高图像的质量和处理效果。
import cv2
import numpy as np
from numpy import unicode
if __name__ == '__main__':
img1 = cv2.imread("D:/Jupyter_Notebooks/0.jpg") # 读取彩色图像(BGR)
# 方框滤波
# 基本和均值一样,可以选择归一化
img_box1 = cv2.boxFilter(img1, -1, (3, 3), normalize=True)
img_box2 = cv2.boxFilter(img1, -1, (2, 2), normalize=False)
cv2.imshow("box1", img_box1) # 显示叠加图像 dst
cv2.imshow("box2", img_box2) # 显示叠加图像 dst
cv2.imshow("image", img1) # 显示叠加图像 dst
cv2.waitKey(0)
cv2.destroyAllWindows()
3 高斯滤波
高斯滤波是图像处理中一种常用的平滑处理方法。在使用OpenCV处理图像时,高斯滤波可以用于减少图像中的噪声和模糊不清的细节。此外,它还可以用于图像的边缘检测和图像分割,因为高斯滤波能够保留图像的主要特征,同时去除小的干扰。
import cv2
import numpy as np
from numpy import unicode
if __name__ == '__main__':
img1 = cv2.imread("D:/Jupyter_Notebooks/0.jpg") # 读取彩色图像(BGR)
# 高斯滤波
# 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
img_aussian1 = cv2.GaussianBlur(img1, (5, 5), 0, 0)
img_aussian2 = cv2.GaussianBlur(img1, (5, 5), 13, 13)
cv2.imshow("aussian1", img_aussian1) # 显示叠加图像 dst
cv2.imshow("aussian2", img_aussian2) # 显示叠加图像 dst
cv2.imshow("image", img1) # 显示叠加图像 dst
cv2.waitKey(0)
cv2.destroyAllWindows()
4 中值滤波
OpenCV 中值滤波是一种图像去噪方法,它通过在图像上选择一个掩码,并将其中的每个像素与周围像素值进行比较,以计算该像素的新值。新值是该像素周围像素值的中位数。这样,中值滤波能够有效去除图像中的噪声和椒盐噪声,使图像更清晰、更加稳定。
import cv2
import numpy as np
from numpy import unicode
if __name__ == '__main__':
img1 = cv2.imread("D:/Jupyter_Notebooks/0.jpg") # 读取彩色图像(BGR)
# 中值滤波
# 相当于用中值代替
img_median1 = cv2.medianBlur(img1, 3) # 中值滤波
img_median2 = cv2.medianBlur(img1, 9) # 中值滤波
cv2.imshow("median1", img_median1) # 显示叠加图像 dst
cv2.imshow("median2", img_median2) # 显示叠加图像 dst
cv2.imshow("image", img1) # 显示叠加图像 dst
cv2.waitKey(0)
cv2.destroyAllWindows()
5 双边滤波
双边滤波是一种图像模糊技术,它在保持图像边缘清晰的同时,对图像中的噪声进行有效去除。双边滤波算法通过比较图像上相邻像素的颜色差异和空间差异来确定每个像素的权重,从而决定每个像素的最终颜色值。在OpenCV中,双边滤波算法可用于处理图像的模糊、去噪、抗抖动等问题。
均值滤波、方框滤波、高斯滤波、中值滤波都是只单纯的考虑了像素点之间的空间信息而进行滤波的方式,这些方式都或多或少都会模糊图像的边缘信息,就是把图像里面的边缘线条弄模糊了,就是在去除图像噪音的同时把图像也弄模糊了,造成图像边界信息的部分丢失,这是这些方法的一个共同的缺点。
双边滤波就可以很好的规避这个缺点。因为双边滤波不仅考虑了像素的空间信息(距离越远权重越小)同时还考虑了像素的色彩信息(色彩差别越大,权重越小),这样就可以很好的去除噪声还可以较好的保护边缘信息,所以双边滤波器也是一个保边去噪的滤波器。
import cv2
import numpy as np
from numpy import unicode
if __name__ == '__main__':
img1 = cv2.imread("D:/Jupyter_Notebooks/0.jpg") # 读取彩色图像(BGR)
img_bilateralFilter1 = cv2.bilateralFilter(img1, 15, 150, 1000)
img_bilateralFilter2 = cv2.bilateralFilter(img1, 3, 255, 1000)
cv2.imshow("bilateralFilter2", img_bilateralFilter2) # 显示叠加图像 dst
cv2.imshow("bilateralFilter1", img_bilateralFilter1) # 显示叠加图像 dst
cv2.imshow("image", img1) # 显示叠加图像 dst
cv2.waitKey(0)
cv2.destroyAllWindows()
6 2D卷积(自定义卷积核实现卷积)
OpenCV 中的 2D 卷积的作用是图像滤波,它可以用来消除图像中的噪声、提取图像的特征、边缘检测等。它通过对图像中的每一个像素与一个固定的卷积核进行卷积操作来实现这些目的。
如果上面的均值滤波卷积核、方框滤波卷积核、高斯滤波卷积核、中值滤波卷积核、双边滤波卷积核都不能满足我们对图像的处理要求,此时我们就需要一个更加灵活的核——即我们自定义一个我们想要的核。如何实现呢?opencv中的cv2.filter2D()函数可以帮助我们实现:
cv2.filter2D(img, ddepth, kernel, anchor, delta, borderType)
img:要处理的原图
ddepth: 默认-1,表示与原图图像相同的深度
kernel: 卷积核,是一个单通道的数组。如果想处理彩图时,让每个通道使用不同的核,就必须先将彩图分解后再使用不同的核去卷积操作。
anchor: 默认值是(-1,-1),默认计算的结果位于核的中心位置。
delta:这个参数可写可不写。如果写,表示在卷积操作时,对应位置相乘相加后再加一个偏置,这个偏置就是delta。
borderType: 边界处理方式,一般用默认值即可。
import cv2
import numpy as np
from numpy import unicode
if __name__ == '__main__':
img1 = cv2.imread("D:/Jupyter_Notebooks/0.jpg") # 读取彩色图像(BGR)
kernel = np.ones((9, 9), np.float32) / 81 # 在实际中我们可以定义更复杂的卷积核,以实现自定义滤波操作
img_kernel1 = cv2.filter2D(img1, -1, kernel) # 这个滤波器就相当于均值滤波
kernel = np.ones((18, 18), np.float32) / 81 # 在实际中我们可以定义更复杂的卷积核,以实现自定义滤波操作
img_kernel2 = cv2.filter2D(img1, -1, kernel) # 这个滤波器就相当于均值滤波
cv2.imshow("kernel1", img_kernel1) # 显示叠加图像 dst
cv2.imshow("kernel2", img_kernel2) # 显示叠加图像 dst
cv2.imshow("image", img1) # 显示叠加图像 dst
cv2.waitKey(0)
cv2.destroyAllWindows()