- 深度学习计算机视觉实战
- 肖铃 刘东
- 1259字
- 2021-10-15 18:46:19
3.2 非线性滤波
线性滤波的实现方式是通过加减乘除等简单运算。例如,3.1 节讲到的方框滤波和均值滤波均通过计算 kernel 区域中像素值的平均值实现;高斯滤波通过计算输入图像与高斯核的加权和实现。
非线性滤波不能通过简单的加权求和的方式计算得到,输入图像数据与滤波结果之间是一种逻辑运算的关系,例如,最大值滤波、最小值滤波和中值滤波,需要比较核大小邻域内的像素值来实现,因而非线性滤波没有固定的核模板(kernel)。
本节将讲解中值滤波和双边滤波,3.3节讲解的膨胀和腐蚀即是通过本节非线性滤波中的最大值滤波和最小值滤波实现的。
3.2.1 案例4:使用中值滤波
中值滤波是使用kernel区域的中值作为kernel中心点位置的像素值来实现滤波的。
如果对如下所示的灰色区域使用中值滤波,需要两个步骤:
(1)将3×3的kernel区域的像素值按大小顺序进行排序,即40、65、78、146、156、200、201、234、245。
(2)选取中值作为kernel区域的中心点,也就是锚点位置(像素值201所在位置)的像素。此处的中值是步骤(1)中排序的中间位置的像素值,即156。
OpenCV提供了中值滤波函数medianBlur()。
C++版本对应的函数如下:
Python版本对应的函数如下:
medianBlur函数对应的参数及其含义如表3.4所示。
表3.4
由表3.4可以看出,使用中值滤波只需要提供kernel的大小即可。值得注意的是,参数ksize必须为奇数,如3、5、7……
下面通过案例来展示中值滤波的使用方法和效果,代码如下:
对源图像添加椒盐噪声的方法参见3.1.1节,使用ksize=3的中值滤波对添加了噪声的图像进行滤波,得到的图像结果如图3.9所示。
对比图3.3、图3.5、图3.7和图3.9可以看出,中值滤波对噪声的去除效果最佳,这是因为中值滤波选取的是kernel区域的中值,对于与典型像素值差别很大的值,滤波后不会采用,因此对斑点噪声和椒盐噪声的处理效果较好。
图3.9
使用ksize=15的中值滤波对添加了噪声的图像进行滤波,得到的图像结果如图3.10所示。
图3.10
由图3.10可以看出,虽然中值滤波在滤除椒盐噪声时的效果较好,但是需要选取合适的ksize,对于线条细节信息,选取的ksize过大会导致细节区域被背景区域影响而被滤除。
3.2.2 案例5:使用双边滤波
双边滤波是本节介绍的第二种非线性滤波方式,是结合图像的空间邻近度和像素值相似度的一种折中处理。滤波运算需要同时考虑空域信息和灰度相似性,进而达到滤除噪声并较好地保存边缘的目的。
OpenCV提供了双边滤波函数bilateralFilter()。
C++版本对应的函数如下:
Python版本对应的函数如下:
bilateralFilter函数对应的参数及其含义如表3.5所示。
表3.5
表3.5中相关参数说明如下:
(1)d,若该参数值使用0或负数,则它的值会通过sigmaSpace进行计算。
(2)sigmaColor,该参数值越大,在该像素邻域中会有越多的像素点参与计算。
(3)sigmaSpace,该参数值越大,会有越多的像素点参与滤波计算。若 d 为正数,则由 d指定邻域大小,该邻域大小与sigmaSpace没有关系,否则d与sigmaSpace的大小成正比。
下面通过案例展示如何使用双边滤波,代码如下:
对源图像添加椒盐噪声的方法参见3.1.1节,使用 d=0 的双边滤波后的图像结果如图3.11所示。
图3.11
使用d=10的双边滤波后的图像结果如图3.12所示。
图3.12
当d的值为非正数的时候,会通过sigmaSpace计算d的值,该过程比设置d为正数直接使用慢得多。在使用过程中,需要根据实际场景选择合适的参数。