时间:2023-03-17 13:21:18 | 栏目:Python代码 | 点击:次
滤波器是对图像做平滑处理 的一种常用工具。
平滑处理即在尽可能地保留原图像信息的情况下,对像素值进行微调,使邻近的像素值之间,值的大小趋于“平滑”,以去除图像内的噪声、降低细节层次信息等的一系列的操作过程。本篇blog将为大家展示OpenCV中的均值滤波器 、中值滤波器 、高斯滤波器 和 双边滤波器。
滤波器的算法逻辑为,指定一个滤波核的大小(该大小表示参与计算的像素数据的范围),以图像中的每一个像素都作为波的核心,通过该范围内的数据,以一定的计算方式进行计算,将计算结果该值赋值给该像素。
以大小为n×n的滤波核为例,对于每一个像素数据,我们可以在数组中得到以一个像素为中心的n×n的矩阵,此即参与计算的数据的范围(边界)。这样的矩阵结构即被称为滤波核。
使用图像《龙门石窟》(longmen.jpg) shape:(350, 600, 3)
均值滤波器,也称低通滤波器
顾名思义,均值滤波器即对滤波核内的数据求均值,然后将这个值赋值给矩阵核心位置。
均值滤波器可以使用cv2.blur() 方法实现
cv2.blur()的语法:
dst = blur(src, ksize, dst=None, anchor=None, borderType=None)
其中
下边以3×3,5×5,10×10三种滤波核为例,分别展示图像经过均值滤波器处理后的效果。
2.2.1 3×3 滤波核为例
import cv2 img = cv2.imread("longmen.jpg") dst1 = cv2.blur(img, (3, 3)) cv2.imshow("3*3", dst1) cv2.waitKey() cv2.destroyAllWindows()
滤波效果如下:
2.2.2 5×5 滤波核为例
import cv2 img = cv2.imread("longmen.jpg") dst2 = cv2.blur(img, (5, 5)) cv2.imshow("5*5", dst2) cv2.waitKey() cv2.destroyAllWindows()
滤波效果如下:
2.2.3 10×10滤波核为例
import cv2 img = cv2.imread("longmen.jpg") dst3 = cv2.blur(img, (10, 10)) cv2.imshow("10*10", dst3) cv2.waitKey() cv2.destroyAllWindows()
可以看出,滤波核大小越大,图像越趋于模糊。
中值滤波器,即对滤波核内所有数据排序,将中间值赋值给滤波核核心位置的数字。
medianBlur(src, ksize, dst=None)
其中 ksize必须是奇数,是偶数的话会发生报错。
不同于均值滤波器的方法,cv2.blur(),cv2.blur()的ksize参数是一个元组,而cv2.blur()的ksize参数是一个数值。
import cv2 img = cv2.imread("longmen.jpg") dst1 = cv2.medianBlur(img, 3) cv2.imshow("3*3", dst1) cv2.waitKey() cv2.destroyAllWindows()
滤波后效果如下:
高斯滤波器也被称为高斯模糊 或 高斯平滑 。
高斯滤波器可以在降低图片噪声、细节层次的同时保留更多的图像信息,使经过处理的图像呈现出“磨砂玻璃”的滤镜效果。
使用均值滤波时,每个像素都是均等权重的。使用高斯滤波器求的是不同权重下的均值,越靠近核心的像素的权重越大,约靠近边缘的像素的权重则越小。
与滤波核对应的由每个数据权重组成的矩阵结构,是一个卷积核。卷积核中所有权重值的和为1。卷积核中的数值会随着核的大小而变化。
OpenCV使用cv2.GaussianBlur()方法实现高斯滤波器。其语法如下:
GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
其中
修改sigmaX 和 sigmaY都会改变卷积核中的权重值。这里涉及卷积方面的知识。
borderType 是边界类型。
以9×9的滤波核为例
import cv2 img = cv2.imread("longmen.jpg") dst1 = cv2.GaussianBlur(img, (9, 9), 0, 0) cv2.imshow("9*9", dst1) cv2.waitKey() cv2.destroyAllWindows()
滤波后效果如下:
前三种滤波方式都会使图像变得平滑的同时,边缘区域变得模糊不清。
双边滤波是可以在滤波过程中起到保护图像边界信息作用的滤波操作方法。
其逻辑为:
如果图像在边缘区域,则加大边缘像素的权重,尽可能地让边缘区域的像素值保持不变。如果不在边缘区域(在平坦区域),则使用类似高斯滤波器的算法进行。
双边滤波器的语法为:
bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)
scr 即目标图像
d过滤期间使用的每个像素邻域的直径。如果为非正,则根据sigmaSpace计算。即如果为15,则表示15×15的滤波核。
sigmaColor参与计算的颜色的范围,只有像素小于这个值时,以其为核心的滤波核才参与滤波计算。否则不参与。当sigmaColor值为255时,表示所有像素值为核心的滤波核都会参与。
sigmaSpace坐标空间的σ \sigmaσ值,σ \sigmaσ越大,参与计算的像素数量就越多。
borderType边界的样式。
还以图片"longmen.jpg"为例,
选择20×20的滤波核,
参与计算的像素值范围为:小于125的像素值;
坐标空间的σ \sigmaσ值为,200
import cv2 img = cv2.imread("longmen.jpg") # 双边滤波,选取范围直径为15,颜色范围为125 dst = cv2.bilateralFilter(img, 15, 125, 200) cv2.imshow("bilateral", dst) cv2.waitKey() cv2.destroyAllWindows()
双边滤波效果如下:
可以看出,相比以上滤波效果,双边滤波保留了较清晰的图像边缘信息。