【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)

一、图像平滑(smoothing)

         图像平滑(smoothing)也称为“模糊处理”(bluring), 是一项简单且使用频率很高的图像处理方法。可以用来压制、弱化或消除图像中的细节、突变、边缘和噪声。但最常见的是用来减少图像上的噪声或者失真。降低图像分辨率时,平滑处理是很重要的。

说到噪声,两种噪声应该提一下:

椒盐噪声:噪声的幅值基本上相同,但是噪声出现的位置是随机的;(中值滤波效果好)

高斯噪声:每一点都存在噪声,但噪声的幅值是随机分布的。

二、图像滤波与滤波器

         何为图像滤波呢?指的是在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像处理中不可缺少的一项操作。好的滤波可以有效的图像处理的有效性和可靠性。我们知道,信号或者图像的能量大部分是集中在幅度谱的低频和中频段,而高频段往往会伴有噪声的存在。因此,我们设计好的滤波器必须能够较好区分高低频段。

对于图像滤波一般有两点要求:(1)不能损坏图像的重要特征信息(如轮廓和边缘等);

                                                        (2)图像经滤波处理后清晰度更高;

还有两点目的:(1)抽出图像的特征作为图像识别的特征模式;

                            (2)适应图像处理时项目的要求,尽可能的降低噪声;

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

空间滤波技术分类

      一、根据空间滤波增强目的可分为:平滑滤波和锐化滤波;

     二、根据空间滤波的特点可分为:线性滤波和非线性滤波。

  (1)平滑滤波,能减弱或消除图像中的高频分量,但不影响低频分量。因为高频分量对应图像中的区域边缘等灰度值具有较大、较快变化的部分,平滑滤波将这些分量绿区可减少局部灰度的起伏,使图像变得比较平滑。实际应用中,平滑滤波即可以用来消除噪声,又可以用在提取较大的目标前过滤去除较小的细节或将目标内的小间断连接起来。

 (2)锐化滤波,能减弱或消除图像中的低频分量,但不影响高频分量。因为低频分量对应图像中灰度值缓慢变化的区域,因而与图像的整体特性如整体对比度和平均灰度值等有关。锐化滤波将这些分量滤去可使图像反差增加,边缘明显。实际应用中,锐化滤波可用于增强图像中被模糊的细节或景物的边缘。

下面是常用的一些滤波器,分为线性滤波和非线性滤波

         方框滤波–> boxblur函数来实现 –>线性滤波 
         均值滤波(邻域平均滤波)–> blur函数 –>线性滤波 
         高斯滤波–>GaussianBlur函数 –>线性滤波 
         中值滤波–>medianBlur函数 –>非线性滤波 
         双边滤波–>bilateralFilter函数 –>非线性滤波

三、线性滤波器Linear Filter

几种常见的线性滤波器: 
(1)低通滤波器:允许低频率通过;
(2)高通滤波器:允许高频率通过; 
(3)带通滤波器 :允许一定区域的频率通过;
(4)带阻滤波器 :阻止一定范围内的频率并且允许其他频率通过;
(5)全通滤波器 :允许所有频率通过,仅仅改变相位;
(6)陷波滤波器(Band stop filter):阻止一个狭窄频率范围通过的特殊带阻滤波器。

线性滤波的原理分析:

        线性邻域滤波是一种常用的邻域算子;邻域算子(局部算子)是利用给定像素周围的像素值的决定此像素的最终输出值的一种算子。下面这个图解可以很好的说明这个过程:

邻域算子(局部算子)是利用给定像素周围的像素值的决定此像素的最终输出值的一种算子。而线性邻域滤波是一种常用的邻域算子,像素的输出值取决于输入像素的加权和,具体过程如下图。

邻域算子(局部算子)是利用给定像素周围的像素值的决定此像素的最终输出值的一种算子。而线性邻域滤波是一种常用的邻域算子,像素的输出值取决于输入像素的加权和,具体过程如下图:

【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第1张图片

        假设有6x6的图像像素点矩阵。卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。

        而平滑(smoothing)/模糊(bluring)的数学理论幕后黑手——卷积:

                                                                        

      线性滤波处理的输出像素值g(i,j)也就是上面的红心的值,是输入图像f(i+k,j+l)的加权和。h(k,l)是核,也是窗口大小;

3.1 方框滤波(box Filter)

    感觉很少用到,而且当normalize=true时,实际就是均值滤波:

C++ void boxFilter(InputArray src,    //输入图像
            OutputArray dst,   //输出图像
            int depth,       //输出图像的深度,-1表示使用原图深度,即src.depth()
            Size ksize,       //内核的大小,Size(w,h)
            Point anchor=Point(-1,-1),    //锚点
            boolnormalize=true,         //一个标识符,表示内核是否被其区域归一化(narmalized)了
           int borderType=BORDER_DEFAULT )  //一般不管 

3.2 均值滤波(Mean Filter)

         均值滤波实际上就是用均值替代原图像中的各个像素值。

        均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(假设我3*3,窗口,则以目标像素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来(目标核的)像素值。对噪声图像特别是有大的孤立点的图像非常敏感,即使有极少数量点存在较大差异也会导致平均值的明显波动。

原理分析:(K为模板)

                                         【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第2张图片

 处理后的目标点像素值:  g(x,y)=\frac{1}{M}\sum f(x,y),M是包括目标像素在内的像素总和。

Opencv的API介绍:

C++ void blur(InputArray src,       //输入图像
          OutputArraydst,       //输出图像
          Size ksize,         //内核大小
          Point anchor=Point(-1,-1),     //锚点
          int borderType=BORDER_DEFAULT )  //一般不管

优缺点分析:

        在降低噪声的同时使图像变得模糊,特别是在景物的边缘和细节处,模板越大,虽然噪声的抑制效果越好,但同时画面的模糊越严重。(均值滤波的固有缺陷)

3.3 高斯滤波(Gaussian Filter)

         高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。

高斯滤波的具体操作:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。进行高斯滤波的通常原因是真实图像在空间内的像素是缓慢变化的,因此临近点的像素变化不会很明显,但是随机的两个点就可能形成很大的像素差。正是基于这一点,高斯滤波在保留信号的条件下减少噪声。遗憾的是,这种方法在接近边缘处就无效了,因此高斯滤波会破平边缘。但是,高斯平滑滤波器对于抑制服从正态分布的噪声仍然是非常有效的。

高斯函数

                            【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第3张图片

二维高斯函数:

                                               

OpenCV里面的API介绍:

C++ void GaussianBlur(InputArray src,      //输入图像
             OutputArray dst,    //输出图像
             Size ksize,       //内核的大小
             double sigmaX,     //高斯核函数在X方向的标准偏差  
             double sigmaY=0,    //高斯核函数在Y方向的标准偏差
             intborderType=BORDER_DEFAULT )  //一般不用管

四、非线性滤波(Nonlinear filtering)

4.1 中值滤波(Median bluring)

        中值滤波法是一种基于排序统计理论的一种能有效抑制噪声的非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值,也就是将中心像素的值用所有像素值的中间值(不是平均值)替换。中值滤波通过选择中间值避免图像孤立噪声点的影响,对脉冲噪声、斑点噪声、椒盐噪声有良好的滤除作用,特别是在滤除噪声的同时,能够保护信号的边缘,使之不被模糊。这些优良特性是线性滤波方法所不具有的。此外,中值滤波的算法比较简单,也易于用硬件实现。所以,中值滤波方法一经提出后,便在数字信号处理领得到重要的应用。

                                                     原理:

        其中,f(x,y),g(x,y)分别为原图像和处理后的图像,W为模板,通常为3*3、5*5区域,也可以有不同的形状,如线形、圆形、十字形、圆环形等。

优缺点分析:

优点:中值滤波在一定条件下可以克服常见的线性滤波器(最小均方滤波器、方框滤波器、均值滤波器)等给图像带来的细节模糊分影响。想想也知道,从他们的原理来看,均值滤波器加入了噪声成分进去,而中值滤波器在一定程度上有过滤噪声的作用,使得其在降噪方面也有很好的效果。

缺点:中值滤波比较耗费时间,是均值滤波的5倍以上。

OpenCV里面的API介绍:

C++:  void medianBlur(InputArray src,OutputArray dst,int ksize)
//参数详解:

//第一参数,InputArray类型的src,函数的输入参数,填1,3或者4通道的Mat类型的图像。当ksize为3或5的时候,图像深度需为CV_8U、CV_16U、CV_32F其中之一,而对于较大孔径尺寸的图片,只能是CV_8U;
//第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数需要和源图片有一样的尺寸和类型,我们可以用Mat::clone,以源图片为模板来初始化得到如假包换的目标图;
//第三个参数,int类型的ksize,孔径的现行尺寸(aperture linear size),注意这个参数必须是大于1 的奇数(3、5、7、...)

4.2  双边滤波(Bilateral Filtering)

        双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波能够提供一种不会将边缘平滑掉的方法,但作为代价,需要更多的处理时间。与高斯滤波类似,双边滤波会依据每个像素及其领域构造一个加权平均值,加权计算包括两个部分,其中第一部分加权方式与高斯平滑中相同,第二部分也属于高斯加权,但不是基于中心像素点与其他像素点的空间距离之上的加权,而是基于其他像素与中心像素的亮度差值的加权。可以将双边滤波视为高斯平滑,对相似的像素赋予较高的权重,不相似的像素赋予较小的权重,也可用于图像分割之中。

        双边滤波器的好处是可以做边缘保存(edge preserving),一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

原理分析:

                                    【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第4张图片

其中定义域滤波和值域滤波可以用下图形象表示:

                                    【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第5张图片

OpenCV里面的API介绍:

C++ void bilateralFilter(InputArray src,OutputArray dst,int d,double sigmaColor,double sigmaSpace,int borderType=BORDER_DEFAULT)
//参数详解如下:

//第一个参数,InputArray类型的src,输入图像,即源图像,需要为8为或者浮点型单通道、三通道的图像;
//第二个参数,OutputArray类型的dst,即目标图像,需要和源图像有一样的尺寸和类型;
//第三个参数,int类型的d,表示在过滤过程中每个像素邻域的直径。如果这个参数被设置为负值,那么OpenCV会从第五个参数sigmaSpace来计算出它;
//第四个参数,double类型的sigmaColor,颜色空间滤波器的sigma值,这个参数的值越大,就表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域;
//第五个参数,double类型的 sigmaSpace,坐标空间中的sigma值,坐标空间的标注方差。它的数值越大,意味着越远的像素会相互影响,从而使更大区域中足够相似的颜色获取相同的颜色,当d>0时,d制定了邻域大小且与sigmaSpace无关,否则,d正比于sigmaSpace;
//第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT。

综合示例程序: 

                                       (均值滤波)                                                                                       (高斯滤波

【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第6张图片【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第7张图片

                                              (中值滤波)                                                                               (双边高斯滤波

【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第8张图片【OpenCV学习笔记】之图像平滑(线性/非线性滤波器)_第9张图片

分析:

  1. 均值模糊无法克服边缘像素信息丢失缺陷。原因是均值滤波是基于平均权重;
  2. 高斯模糊部分克服了该缺陷,但是无法完全避免,因为没有考虑像素值的不同;
  3. 中值模糊,虽然抑制噪声算法比均值滤波略为复杂,但保持画面清晰度的效果更好;
  4.  高斯双边模糊是边缘保留的滤波方法,避免了边缘信息丢失,保留了图像轮廓不变。

你可能感兴趣的:(OpenCV)