滤波器是根据原有图像的某个像素的周围像素来确定新的像素值,滤波器主要的作用是用来消去噪声的,消除图像中的不合理的像素点。滤波器主要包括线性滤波器和非线性滤波器,其中线性滤波器包括均值滤波,方框滤波和高斯滤波,非线性的主要是中值滤波。主要介绍一下滤波器的原理和Opencv使用语法。
在介绍滤波器的概念之前首先说明一下线性卷积的概念,设I和I’是二维函数,I(u,v)表示像素点(u,v)代表的像素值,H为一个二维函数,线性卷积操作的定义如下:
假设我们采用滤波器核的大小为L*W(L=3,W=3),方框滤波采用的滤波矩阵如下
void boxFilter(InputArray src,OutputArray dst,int depth,Size ksize,Point anchor=Point(-1,-1),bool normalize=true,int borderType=BORDER_DEFAULT)
boxFilter的参数说明
参数名 | 说明 |
---|---|
src | 输入图像 |
dst | 输出图像 |
depth | 图像的深度,负值则为输入图像的深度 |
ksize | 滤波核的大小(K*M) |
anchor | 锚点,表示需要被重新生成像素的点,默认为(-1,-1),即为滤波核的中心点 |
normalize | 是否归一化,表示a的取值,false取1,true的话跟均值滤波相同 |
borderType | 边界模式 |
下面的这段代码实现了读取文件,并且进行方框滤波,并且展示
#include
#include
#include
#include
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;
}
原图像为
滤波操作之后的图像
可以看出来方框滤波之后的图像明显比原来的图片噪声减少了,但是很明显,整个图像变得模糊了,因为每个像素的值都是由其周围像素的均值得来,因此边缘和轮廓会更不清晰。
均值滤波在前面说过,当方框滤波的normalize取为true,即为均值滤波,但同时opencv提供了专门的均值滤波函数。
void blur(InputArray src, OutputArray dst, Size ksize,Point anchor=Point(-1,-1),int borderType=BORDER_DEFAULT)
blur方法的参数说明
参数名 | 说明 |
---|---|
src | 输入图像 |
dst | 输出图像 |
ksize | 滤波核的大小(K*M) |
anchor | 锚点,表示需要被重新生成像素的点,默认为(-1,-1),即为滤波核的中心点 |
borderType | 边界模式 |
blur方法的代码只需要把前面的代码段中的boxFilter方法更改为blur方法即可。
高斯滤波采用的滤波矩阵为根据二维高斯函数生成的高斯矩阵
Opencv提供的高斯滤波的方法为
void GaussianBlur(InputArray src,OutputArray dst,Size ksize,double sigmaX,double sigmaY=0,int borderType=BORDER_DEFAULT)
GaussianBlur方法的参数说明
参数名 | 说明 |
---|---|
src | 输入图像 |
dst | 输出图像 |
ksize | 滤波核的大小(K*M) |
sigmaX | 高斯函数在X方向的标准差 |
sigmaY | 高斯函数在Y方面的标准差,若sigmaX=sigmaY=0,那么标准差将根据ksize的大小计算得到 |
borderType | 边界模式 |
代码只需要把第一段的boxFilter改成下面的代码即可
GaussianBlur(src,dst,Size(3,3),0);
可以看到线性滤波器绝大多数把图像模糊化了,而且线性滤波有一个最大的弱点在于,如果图片中的噪声脉冲比较大(即像素值跟周围像素点差距过大),那么这个噪声并不会被消除,只是会被减弱,而且会对周围正常像素的值产生影响,这些都是因为我们采用新像素等于其周围像素线性组合得到的原因。
非线性滤波器主要是针对这种问题提出了解决方案,今天只介绍一个,叫中值滤波器,其原理为
Oopencv提供的中值滤波方法为
void medianBlur(InputArray src,OutputArray dst,int ksize)
函数的参数说明
参数名 | 说明 |
---|---|
src | 输入图像 |
dst | 输出图像 |
ksize | 滤波核孔径的大小,必须为奇数1、3、5….. |
代码的话只需要把第一个的boxFilter改成下面这句即可
medianBlur(src,dst,3);
可以看到中值滤波之后的结果是最理想的,而且图像模糊程度并没有非线性那么厉害,如果噪声的脉冲比较大,分布比较密集,可以采用中值滤波去除噪声。