opencv学习(7)图像的各种滤波函数的介绍
图像的滤波⽬的有两个:
⼀是抽出图像的特征作为图像识别的特征模式;
另⼀个是为适应图像处理的要求,消除图像数字化时所混⼊的噪声;
1、图像的平滑处理:
平滑滤波是指低频增强的空间滤波技术。主要⽬的是模糊和消除噪⾳;
2、常⽤的5种图像平滑处理操作⽅法:
1)⽅框滤波——boxFilter函数
2)均值滤波——Blur函数
3)⾼斯滤波——GaussianBlur函数
4)中值滤波——medianBlur函数
5)双边滤波——bilateralFilter函数
前三种都属于线性滤波,后两种属于⾮线性滤波;
滤波和模糊:滤波是将信号中特定波段频率滤除的操作,是抑制和防⽌⼲扰的⼀项重要措施。模糊是滤波的⼀种。⾼斯滤波是指⽤⾼斯函数
作为滤波函数的滤波操作。⾼斯模糊就是⾼斯低通滤波。
1)⽅框滤波——boxFilter函数
函数原型:
void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
参数详解:
第⼀个参数:InputArray类型的src,输⼊图像,即源图像,填Mat类的对象即可。该函数对通道是独⽴处理的,且可以处理任意通道数的
图⽚,但需要注意,待处理的图⽚深度应该为CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之⼀。
第⼆个参数:OutputArray类型的dst,即⽬标图像,需要和源图⽚有⼀样的尺⼨和类型。
第三个参数:int类型的ddepth,输出图像的深度,-1代表使⽤原图深度,即src.depth()。
第四个参数:Size类型(对Size类型稍后有讲解)的ksize,内核的⼤⼩。⼀般这样写Size( w,h )来表⽰内核的⼤⼩( 其中,w 为像素宽度,
h为像素⾼度)。Size(3,3)就表⽰3x3的核⼤⼩,Size(5,5)就表⽰5x5的核⼤⼩
第五个参数:Point类型的anchor,表⽰锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表⽰
取核的中⼼为锚点,所以默认值Point(-1,-1)表⽰这个锚点在核的中⼼。
第六个参数:bool类型的normalize,默认值为true,⼀个标识符,表⽰内核是否被其区域归⼀化(normalized)了。
第七个参数:int类型的borderType,⽤于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们⼀般不去管它。
2)均值滤波——Blur函数
函数原型:
C++: void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
第⼀个参数:InputArray类型的src,输⼊图像,即源图像,填Mat类的对象即可。该函数对通道是独⽴处理的,且可以处理任意通道数的
图⽚,但需要注意,待处理的图⽚深度应该为CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之⼀。
第⼆个参数:OutputArray类型的dst,即⽬标图像,需要和源图⽚有⼀样的尺⼨和类型。⽐如可以⽤Mat::Clone,以源图⽚为模板,来初
始化得到如假包换的⽬标图。
第三个参数:Size类型(对Size类型稍后有讲解)的ksize,内核的⼤⼩。⼀般这样写Size( w,h )来表⽰内核的⼤⼩( 其中,w 为像素宽度,
h为像素⾼度)。Size(3,3)就表⽰3x3的核⼤⼩,Size(5,5)就表⽰5x5的核⼤⼩
第四个参数:Point类型的anchor,表⽰锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表⽰
取核的中⼼为锚点,所以默认值Point(-1,-1)表⽰这个锚点在核的中⼼。
第五个参数:int类型的borderType,⽤于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们⼀般不去管它。
3)⾼斯滤波——GaussianBlur函数
原型:
C++: void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, intborderType=BORDER_DEFAULT )
第⼀个参数:InputArray类型的src,输⼊图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图⽚,但需要注意,图⽚深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之⼀。
第⼆个参数:OutputArray类型的dst,即⽬标图像,需要和源图⽚有⼀样的尺⼨和类型。⽐如可以⽤Mat::Clone,以源图⽚为模板,来初始化得到如假包换的⽬标图。
第三个参数:Size类型的ksize⾼斯内核的⼤⼩。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数。或者,它们可以是零的,它们都是由sigma计算⽽来。
第四个参数:double类型的sigmaX,表⽰⾼斯核函数在X⽅向的的标准偏差。
第五个参数:double类型的sigmaY,表⽰⾼斯核函数在Y⽅向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
为了结果的正确性着想,最好是把第三个参数Size,第四个参数sigmaX和第五个参数sigmaY全部指定到。
第六个参数:int类型的borderType,⽤于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们⼀般不去管它。
下⾯是线性滤波的综合事例:
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat g_srcImage,g_dstImage1,g_dstImage2,g_dstImage3;//存储图⽚的Mat类型
int g_nBoxFilterValue=3; //⽅框滤波参数值
int g_nMeanBlurValue=3; //均值滤波参数值
int g_nGaussianBlurValue=3; //⾼斯滤波参数值
/
/轨迹条的回调函数
static void on_BoxFilter(int, void *); //⽅框滤波
static void on_MeanBlur(int, void *); //均值滤波
static void on_GaussianBlur(int, void *); //⾼斯滤波
//-----------------------------------【main( )函数】---------------------------------------
int main( )
{
//改变console字体颜⾊
system("color5E");
//载⼊原图
g_srcImage= imread( "1.jpg", 1 );
if(!g_srcImage.data ) { printf("Oh,no,读取srcImage错误~!\n"); return false; }
//克隆原图到三个Mat类型中
g_dstImage1= g_srcImage.clone( );
g_dstImage2= g_srcImage.clone( );
g_dstImage3= g_srcImage.clone( );
//显⽰原图
namedWindow("【<0>原图窗⼝】", 1);
imshow("【<0>原图窗⼝】",g_srcImage);
//=================【<1>⽅框滤波】==================
//创建窗⼝
namedWindow("【<1>⽅框滤波】", 1);
/
/创建轨迹条
createTrackbar("内核值:", "【<1>⽅框滤波】",&g_nBoxFilterValue, 40,on_BoxFilter );
on_MeanBlur(g_nBoxFilterValue,0);
imshow("【<1>⽅框滤波】", g_dstImage1);
//=================【<2>均值滤波】==================
//创建窗⼝
namedWindow("【<2>均值滤波】", 1);
//创建轨迹条
createTrackbar("内核值:", "【<2>均值滤波】",&g_nMeanBlurValue, 40,on_MeanBlur );
on_MeanBlur(g_nMeanBlurValue,0);
//=================【<3>⾼斯滤波】=====================
/
/创建窗⼝
namedWindow("【<3>⾼斯滤波】", 1);
//创建轨迹条
createTrackbar("内核值:", "【<3>⾼斯滤波】",&g_nGaussianBlurValue, 40,on_GaussianBlur );
on_GaussianBlur(g_nGaussianBlurValue,0);
//输出⼀些帮助信息
cout<<endl<<"\t嗯。好了,请调整滚动条观察图像效果~\n\n"
<<"\t按下“q”键时,程序退出~!\n"
<<"\n\n\t\t\t\tby浅墨";
//按下“q”键时,程序退出
while(char(waitKey(1))!= 'q') {}
return0;
}
// 描述:⽅框滤波操作的回调函数
static void on_BoxFilter(int, void *)
{
//⽅框滤波操作
boxFilter(g_srcImage, g_dstImage1, -1,Size( g_nBoxFilterValue+1, g_nBoxFilterValue+1));
//显⽰窗⼝
imshow("【<1>⽅框滤波】", g_dstImage1);
}
// 描述:均值滤波操作的回调函数
static void on_MeanBlur(int, void *)
{
//均值滤波操作
blur(g_srcImage, g_dstImage2, Size( g_nMeanBlurValue+1, g_nMeanBlurValue+1),Point(-1,-1));
//显⽰窗⼝
imshow("【<2>均值滤波】", g_dstImage2);
}
static void on_GaussianBlur(int, void *)
{
//⾼斯滤波操作
GaussianBlur(g_srcImage, g_dstImage3, Size( g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1 ), 0, 0);
//显⽰窗⼝
imshow("【<3>⾼斯滤波】", g_dstImage3);
}
刚刚介绍的都是线性滤波,即两个信号之和的响应和他们各⾃响应之和相等。也就是每个像素的输出值是⼀些输⼊像素的加权和,线性滤波器易于构造,并且易于从频率响应⾓度来进⾏分析。其实在很多情况下,使⽤邻域像素的⾮线性滤波也许会得到更好的效果。
中值滤波(Median filter)是⼀种典型的⾮线性滤波技术,基本思想是⽤像素点邻域灰度值的中值来代替该像素点的灰度值,该⽅法在去除脉冲噪声、椒盐噪声的同时⼜能保留图像边缘细节。
中值滤波在⼀定的条件下可以克服常见线性滤波器如最⼩均⽅滤波、⽅框滤波器、均值滤波等带来的图像细节模糊,⽽且对滤除脉冲⼲扰及图像扫描噪声⾮常有效,也常⽤于保护边缘信息, 保存边缘的特性使它在不希望出现边缘模糊的场合也很有⽤,是⾮常经典的平滑噪声处理⽅法。
缺点:中值滤波花费的时间是均值滤波的5倍以上。
双边滤波(Bilateral filter)是⼀种⾮线性的滤波⽅法,是结合图像的空间邻近度和像素值相似度的⼀
种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的⽬的。具有简单、⾮迭代、局部的特点。
双边滤波器的好处是可以做边缘保存(edge preserving),⼀般过去⽤的维纳滤波或者⾼斯滤波去降噪,都会较明显地模糊边缘,对于⾼频细节的保护效果并不明显。双边滤波器顾名思义⽐⾼斯滤波多了⼀个⾼斯⽅差sigma-d,它是基于空间分布的⾼斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的⾼频信息,对于彩⾊图像⾥的⾼频噪声,双边滤波器不能够⼲净的滤掉,只能够对于低频信息进⾏较好的滤波。
在双边滤波器中,输出像素的值依赖于邻域像素值的加权值组合:
4)中值滤波——medianBlur函数
medianBlur函数使⽤中值滤波器来平滑(模糊)处理⼀张图⽚,从src输⼊,⽽结果从dst输出。
且对于多通道图⽚,每⼀个通道都单独进⾏处理,并且⽀持就地操作(In-placeoperation)。
原型:
参数详解:
第⼀个参数:InputArray类型的src,函数的输⼊参数,填1、3或者4通道的Mat类型的图像;当ksize为3或者5的时候,图像深度需为CV_8U,CV_16U,或CV_32F其中之⼀,⽽对于较⼤孔径尺⼨的图⽚,它只能是CV_8U。
htmlborder第⼆个参数:OutputArray类型的dst,即⽬标图像,函数的输出参数,需要和源图⽚有⼀样的尺⼨和类型。我们可以⽤Mat::Clone,以源图⽚为模板,来初始化得到如假包换的⽬标图。 第三个参数:int类型的ksize,孔径的线性尺⼨(aperture linear size),注意这个参数必须是⼤于1的奇数,⽐如:3,5,7,9。
C++: void medianBlur(InputArray src,OutputArray dst, int ksize)
#include "opencv2/core/core.hpp"
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应⽤程序的⼊⼝函数,我们的程序从这⾥开始
//-----------------------------------------------------------------------------------------------
int main( )
{
//载⼊原图
Mat image=imread("1.jpg");
/
/创建窗⼝
namedWindow("中值滤波【原图】" );
namedWindow("中值滤波【效果图】");
//显⽰原图
imshow("中值滤波【原图】", image );
//进⾏中值滤波操作
Mat out;
medianBlur( image, out, 7);
//显⽰效果图
imshow("中值滤波【效果图】" ,out );
waitKey(0 );
}
5)双边滤波——bilateralFilter函数
原型:
C++: void bilateralFilter(InputArray src, OutputArraydst, 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。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论