ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

时间:2024-03-23 22:47:20

滤波目的:消除图像中混入的噪声。为图像识别抽取出图像特征。
滤波要求:不能损坏图像轮廓及边缘 。图像视觉效果应当更好。

图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。消除图像中的噪声成分叫作图像的平滑化或滤波操作。

信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的,而在较高频段,感兴趣的信息经常被噪声淹没。因此一个能降低高频成分幅度的滤波器就能够减弱噪声的影响。平滑滤波是低频增强的空间域滤波技术。

它的目的有两类:一类是模糊;另一类是消除噪音。空间域的平滑滤波一般采用简单平均法进行,就是求邻近像元点的平均亮度值。邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。

关于滤波器,一种形象的比喻法是:我们可以把滤波器想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口放到图像之上,透过这个窗口来看我们得到的图像。

1、方框滤波(盒式滤波)

方框滤波(盒式滤波)是一种线性滤波技术,它的实现借鉴了积分图像的原理思想,在快速积分图像求解中,将计算某个矩阵像素间的和值运算,转化为求矩阵对应边角点的求和差值运算。盒式滤波的实现最关键的步骤就是初始化数组S,数组S的每个值是存放像素邻域内的像素和值,在求解某矩形块中的像素和时,只需要索引对应区域的位置存放的和值就可以完成计算。

原理:先给出内核,用内核各点的值与对应的图像像素值相乘:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)
OpenCV将盒式滤波封装在boxFilter()函数中,作用是输入一副图像对其进行盒式滤波。感兴趣的同学可以看看其源代码。下面来看下boxFilter()函数的定义:

void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize,
Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT );

参数说明:

参数1:输入要处理的图像。

参数2:得到处理后的的输出图像。

参数3:图像的深度。-1代表使用原图深度,即src.depth()。

参数4:内核的大小。一般用Size(w,h)来表示内核大小,其中w为像素宽度,h为像素高度,正奇数或0。例:Size(3,3)就代表3×3的核大小。

参数5:表示锚点,即被平滑的那个点。如果这个点坐标是负值的话,就表示取核的中心点为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。

参数6:默认值为true,一个标识符,表示内核是否被其区域归一化了,具体见下面介绍。

参数7:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT,我们一般不用管它。

boxFilter()函数盒式滤波所用的核表示如下:
ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)
对参数6具体解释:

当normalize = true 时,盒式滤波就变成了均值滤波。也就是说,均值滤波是盒式滤波归一化(normalized)后的特殊情况。其中,归一化就是把要处理的量都缩放到一个范围内,比如(0,1),以便统一处理和直观量化。

当normalize = false时,为非归一化的盒式滤波,用于计算每个像素邻域内的积分特性,比如密集光流算法(dense optical flow algorithms)中用到的图像倒数的协方差矩阵(covariance matrices of image derivatives)。

显示结果

非归一化情况
ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)
归一化情况
ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波) 可以发现,非归一化的时候,得到图像就是一片白色,对源图像毁坏太大,根本无法使用。
而归一化的时候,得到图像是一种模糊的效果,此时与均值滤波一样。

2、均值滤波

均值滤波,是最简单的一种线性滤波操作,输出图像的每一个像素是核窗口内输入图像对应像素的像素的平均值( 所有像素加权系数相等),其实说白了它就是归一化后的方框滤波。

均值滤波算法比较简单,计算速度快,但是均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时,也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。但均值滤波对周期性的干扰噪声有很好的抑制作用。

blur()函数——均值滤波

OpenCV将均值滤波封装在blur()函数中,作用是输入一副图像对其进行均值滤波。感兴趣的同学可以看看其源代码。下面来看下blur()函数的定义:

void blur( InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT );

参数说明:

参数1:输入要处理的图像。

参数2:得到处理后的输出图像。

参数3:内核的大小。一般用Size(w,h)来表示内核大小,其中w为像素宽度,h为像素高度,正奇数或0。

参数4:表示锚点,即被平滑的那个点。如果这个点坐标是负值的话,就表示取核的中心点为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。

参数5:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT,我们一般不用管它。

显示结果
ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)
blur()函数中的参数3,若核越大,则处理后的图像越模糊。上一节讲的盒式滤波(方框滤波),若将boxFilter()函数中的参数6,设为true,则表现的就是均值滤波,即归一化后的方框滤波。

3、高斯滤波

高斯滤波(高斯平滑)是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波是最有用的滤波器 (尽管不是最快的)。高斯平滑滤波器对于抑制服从正态分布的噪声非常有效。

什么是高斯滤波?

首先,它引入了数学中的高斯函数(正态分布函数)(PS:对于平面图像来说,往往用到的是二维函数)。

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

高斯滤波的思路就是:对高斯函数进行离散化,以离散点上的高斯函数值为权值,对我们采集到的灰度矩阵的每个像素点做一定范围邻域内的加权平均,即可有效消除高斯噪声。

离散的高斯卷积核H:(2k+1)×(2k+1)维,其元素计算方法为:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

其中Sigma为方差,k确定核矩阵的维数。

通过上述公式,我们可以方便地求出高斯模板,从而进行高斯滤波处理。这里不得不提在图像处理中,高斯滤波一般有两种实现方式,一是用离散化窗口滑窗卷积,另一种通过傅里叶变换。最常见的就是第一种滑窗实现,只有当离散化的窗口非常大,用滑窗计算量非常大(即使用可分离滤波器的实现)的情况下,可能会考虑基于傅里叶变化的实现方法。

“离散化”:上面已经提到了离散的高斯卷积核,实际上就是将高斯函数进行离散化,方便程序计算高斯模板;

“窗口”:这个窗口比喻得很形象,实际上我的理解就是M*N维的高斯模板;

“滑窗”:有了这个高斯模板,接下来是结合我们待处理的灰度数据,处理一个接着一个的像素点。例如说,处理完(1,1)这个点之后,接下来要处理(1,2)这个数据点,那么模板相当于右移了一个像素点,那么我们可以把这个过程形象地看作是滑窗。在碰上待处理图像的边缘时,往往处理不了,此时要进行特殊处理,比如说在检测到边缘时,复制原来的灰度数据,即不处理;

“卷积”:在高数里有过这个概念,然而在这个地方,卷积远远没有书上的那么复杂,实际上就是待处理图像的各像素灰度数据与模板对应元素的数值的加权和的运算过程,就称之为卷积。

有了以上解释之后,我们可以把“离散化”和“窗口”看成是第一个步骤,可以称之为预处理,通过对高斯函数离散化得到的函数来编程得到你所需要的高斯模板,也就是窗口;把“滑窗”和“卷积”看作是第二个步骤,可以称之为处理过程,通过“滑窗”的方式来进行“卷积”过程。

实际上,在OpenCV中处理起来没这么复杂,因为已经将高斯滤波封装在GaussianBlur()函数中。

GaussianBlur()函数——高斯滤波

OpenCV将高斯滤波封装在GaussianBlur()函数中,作用是输入一副图像对其进行高斯滤波。下面来看下GaussianBlur()函数的定义:

void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT);

参数说明:

参数1:输入要处理的图像。

参数2:得到处理后的输出图像,与输入图像有一样的尺寸和类型。

参数3:高斯内核的大小。一般用Size(w,h)来表示内核大小,其中w为像素宽度,h为像素高度,w与h可以不同,但必须是正数和奇数,或者为0.

参数4:表示高斯核函数在X方向的标准偏差。

参数5:表示高斯核函数在Y方向的标准偏差。

参数6:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT,我们一般不用管它。

显示结果
ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)
4、中值滤波

中值滤波法是一种非线性平滑技术,将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的中值代替 ,常用于消除图像中的椒盐噪声。

与低通滤波不同的是,中值滤波对脉冲噪声有良好的滤除作用,特别是在滤除噪声的同时,能够保护信号的边缘,使之不被模糊,但它会洗去均匀介质区域中的纹理。这些优良特性是线性滤波方法所不具有的。

中值滤波能减弱或消除傅里叶空间的高频分量,同时也影响低频分量。中值滤波去除噪声的效果依赖于两个要素:邻域的空间范围和中值计算中涉及的像素数。一般说来,小于滤波器面积一半的亮或暗的物体基本上会被滤除,而较大的物体几乎会原封不动地保存下来,因此中值滤波器的空间尺寸必须根据现有的问题来进行调整。

medianBlur()函数——中值滤波
OpenCV将均值滤波封装在medianBlur()函数中,作用是输入一副图像对其进行中值滤波。下面来看下medianBlur()函数的定义:

void medianBlur( InputArray src, OutputArray dst, int ksize );

参数说明:

参数1:输入要处理的图像。

参数2:得到处理后的输出图像,与输入图像有一样的尺寸和类型。

参数3:int类型的ksize,表示内核大小,必须设置为奇数。

显示结果
ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)可以发现,中值滤波可以很好保留物体的边缘信息。

5、双边滤波

双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部的特点。

双边滤波器的好处是可以做边缘保存,这个特点对于一些图像模糊来说很有用。一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护效果并不明显。一般的高斯模糊在进行采样时主要考虑了像素间的空间距离关系,但是却并没有考虑像素值之间的相似程度,因此这样我们得到的模糊结果通常是整张图片一团模糊。

双边滤波的改进就在于在采样时不仅考虑像素在空间距离上的关系,同时加入了像素间的相似程度考虑。双边滤波器比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。对于脉冲噪声,双边滤波会把它当成边缘从而不能去除。

在双边滤波器中,输出像素的值依赖于邻域像素值的加权值组合,公式如下:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

而加权系数w(i,j,k,l)取决于定义域核和值域核的乘积。

其中定义域核表示如下:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

定义域滤波对应图示:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

值域核表示为:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

值域滤波:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

两者相乘后,就会产生依赖于数据的双边滤波权重函数:

ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)

bilateralFilter()——双边滤波

OpenCV将双边滤波封装在bilateralFilter()函数中,作用是输入一副图像对其进行双边滤波。下面来看下bilateralFilter()函数的定义:

void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT );

参数说明:

参数1:输入要处理的图像,需要为8位或者浮点型单通道、三通道的图像。

参数2:得到处理后的输出图像,与输入图像有一样的尺寸和类型。

参数3:表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。

参数4:表示颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。

参数5:double类型的sigmaSpace坐标空间中滤波器的sigma值,坐标空间的标注方差。它的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。

参数6:用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT,我们一般不用管它。

显示结果
ISP(四) 图像平滑去噪传统算法详析(方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波)可以发现双边滤波对图像物体的边缘信息保留的很完整。