滤波器原理及其使用

转载自:http://blog.csdn.net/xiaopihai1993/article/details/50464488

滤波器是根据原有图像的某个像素的周围像素来确定新的像素值,滤波器主要的作用是用来消去噪声的,消除图像中的不合理的像素点。滤波器主要包括线性滤波器和非线性滤波器,其中线性滤波器包括均值滤波,方框滤波和高斯滤波,非线性的主要是中值滤波。主要介绍一下滤波器的原理和Opencv使用语法。

    • 滤波器的概念
    • 线性滤波器
      • 方框滤波
      • 均值滤波
      • 高斯滤波
    • 非线性滤波器

滤波器的概念

在介绍滤波器的概念之前首先说明一下线性卷积的概念,设I和I’是二维函数,I(u,v)表示像素点(u,v)代表的像素值,H为一个二维函数,线性卷积操作的定义如下: 

I(u,v)=i=j=I(ui,vj)H(i,j)


新图像的像素值I’(u,v)是由旧像素的所有周围像素及本身像素与其权重H(i,j)乘积的和,如果H(i,j)只在某个范围内取到值,而在其他范围内值均为0,那么对每个像素来说,对于其新像素的值,只有特定范围的相邻像素贡献了值,在这里,H(i,j)就可以被称为滤波器的核或者滤波矩阵,这个过程描述的是线性滤波器的原理,对于非线性滤波器,后面会有相应的介绍。

线性滤波器

方框滤波

假设我们采用滤波器核的大小为L*W(L=3,W=3),方框滤波采用的滤波矩阵如下 

K=a111111111


这里a有两个取值 



a={1LM1


在第一种情况下,方框滤波即为均值滤波,下面介绍一下opencv提供的方框滤波的方法

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

boxFilter的参数说明

参数名 说明
src 输入图像
dst 输出图像
depth 图像的深度,负值则为输入图像的深度
ksize 滤波核的大小(K*M)
anchor 锚点,表示需要被重新生成像素的点,默认为(-1,-1),即为滤波核的中心点
normalize 是否归一化,表示a的取值,false取1,true的话跟均值滤波相同
borderType 边界模式

下面的这段代码实现了读取文件,并且进行方框滤波,并且展示

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>using namespace std;
using namespace cv;int main(){Mat src,dst;src=imread("测试.jpg");  //读取测试文件boxFilter(src,dst,-1,Size(3,3)); //选择3*3的滤波器大小namedWindow("方框滤波",WINDOW_NORMAL);imshow("方框滤波",dst); //显示文件waitKey(6000);return 0;
}   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

原图像为 
原图像 
滤波操作之后的图像 
方框滤波 
可以看出来方框滤波之后的图像明显比原来的图片噪声减少了,但是很明显,整个图像变得模糊了,因为每个像素的值都是由其周围像素的均值得来,因此边缘和轮廓会更不清晰。

均值滤波

均值滤波在前面说过,当方框滤波的normalize取为true,即为均值滤波,但同时opencv提供了专门的均值滤波函数。

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

blur方法的参数说明

参数名 说明
src 输入图像
dst 输出图像
ksize 滤波核的大小(K*M)
anchor 锚点,表示需要被重新生成像素的点,默认为(-1,-1),即为滤波核的中心点
borderType 边界模式

blur方法的代码只需要把前面的代码段中的boxFilter方法更改为blur方法即可。

高斯滤波

高斯滤波采用的滤波矩阵为根据二维高斯函数生成的高斯矩阵 

H(i,j)=ei2÷j22σ2


其中

σ
表示的函数的宽度(标准差)—具体高斯函数的解释请查阅相关数学书,我也不太懂。。。

Opencv提供的高斯滤波的方法为

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

GaussianBlur方法的参数说明

参数名 说明
src 输入图像
dst 输出图像
ksize 滤波核的大小(K*M)
sigmaX 高斯函数在X方向的标准差
sigmaY 高斯函数在Y方面的标准差,若sigmaX=sigmaY=0,那么标准差将根据ksize的大小计算得到
borderType 边界模式

代码只需要把第一段的boxFilter改成下面的代码即可

GaussianBlur(src,dst,Size(3,3),0);
  • 1

高斯滤波后的结果为 
高斯滤波

非线性滤波器

可以看到线性滤波器绝大多数把图像模糊化了,而且线性滤波有一个最大的弱点在于,如果图片中的噪声脉冲比较大(即像素值跟周围像素点差距过大),那么这个噪声并不会被消除,只是会被减弱,而且会对周围正常像素的值产生影响,这些都是因为我们采用新像素等于其周围像素线性组合得到的原因。

非线性滤波器主要是针对这种问题提出了解决方案,今天只介绍一个,叫中值滤波器,其原理为 

I(u,v)=median{I(u+i,v+j)|(i,j)H}


即新像素的值为滤波区域H内的所有像素值得中位数,有时候可能会做一些处理,比如说先对所有的像素值做加权,然后再去求中位数。

Oopencv提供的中值滤波方法为

void medianBlur(InputArray src,OutputArray dst,int ksize)
  • 1

函数的参数说明

参数名 说明
src 输入图像
dst 输出图像
ksize 滤波核孔径的大小,必须为奇数1、3、5…..

代码的话只需要把第一个的boxFilter改成下面这句即可

medianBlur(src,dst,3);
  • 1

中值滤波的图像为 
中值滤波

可以看到中值滤波之后的结果是最理想的,而且图像模糊程度并没有非线性那么厉害,如果噪声的脉冲比较大,分布比较密集,可以采用中值滤波去除噪声。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平