opencv源码解析之(1):滤波前言1

     对图像的滤波和平滑是出来数字图像处理和计算机视觉非常重要的一个步骤,那么什么是滤波呢?滤波用编程语言到底是怎么实现的呢?效果怎么样?本人打算学习opencv有关滤波的源码,进一步加强图像处理的实践能力。

     首先我们利用opencv中常见的4种滤波算法函数来实现滤波功能,让大家有个感性的认识。这4中滤波分别是均值滤波,高斯滤波,中值滤波,双边滤波。利用opencv2.3.1的参考手册中关于opencv中滤波的介绍,我这里采用的是VS2010+opencv2.3.1,新建了一个filter_test控制台工程。      

其源码和注释如下:

 

//包含图像处理和界面处理的头文件

#include "stdafx.h"

#include "opencv2/imgproc/imgproc.hpp"

#include "opencv2/highgui/highgui.hpp"



//采用cv命名空间和标准命名空间

using namespace std;

using namespace cv;



//定义全局变量

int DELAY_CAPTION=1500; //显示标题时延时至少1.5s

int DELAY_BLUR=100; //显示每次滤波时延时0.1s

int MAX_KERNEL_LENGTH=31;//最大的滤波核长度为31



Mat src,dst;

char window_name[]="Filter Demo 1:";



//函数说明

int display_caption(char *caption);

int display_dst(int delay);



//主函数

int main(int argc, _TCHAR* argv[])

{

namedWindow(window_name,CV_WINDOW_AUTOSIZE);//建立一个窗口



//将lena图片读写到矩阵src

src=imread("../images/lena.jpg",1);

//将Origin Image单词显示在dst图片中,并在窗口中显示1.5s

if(display_caption("Origin Image")!=0){return 0;}



dst=src.clone();//将lena图片复制到dst矩阵中,并显示出来,1.5s

if(display_dst(DELAY_CAPTION)!=0){return 0;}



/*利用均值滤波

其中矩阵滤波的函数原型为void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT)

其中src为滤波前图像矩阵,dst为滤波后图像矩阵,ksize为滤波矩形核,anchor为定标点,如果采用的是Point(-1,-1)则默认为核的中心点,borderType为边缘模式的展开

其滤波公式为:





也就是利用ksize个像素求平均值而已,很容易理解
*/




if(display_caption("Homogeneous Blur")!=0){return 0;}//显示Homogeneous Blur单词1.5s



for(int i=1;i<MAX_KERNEL_LENGTH;i=i+2)

{

blur(src,dst,Size(i,i),Point(-1,-1));//采用均值滤波函数

if(display_dst(DELAY_BLUR)!=0){return 0;}

}



//高斯滤波,和上面类似

if(display_caption("Gaussian Blur")!=0){return 0;}



for(int i=1;i<MAX_KERNEL_LENGTH;i=i+2)

{

GaussianBlur(src,dst,Size(i,i),0,0);

if(display_dst(DELAY_BLUR)!=0){return 0;}

}



//中值滤波,和上面类似

if(display_caption("Median Blur")!=0){return 0;}



for(int i=1;i<MAX_KERNEL_LENGTH;i=i+2)

{

medianBlur(src,dst,i);

if(display_dst(DELAY_BLUR)!=0){return 0;}

}



//双边滤波,和上面类似

if(display_caption("Bilateral Blur")!=0){return 0;}



for(int i=1;i<MAX_KERNEL_LENGTH;i=i+2)

{

bilateralFilter(src,dst,i,i*2,i/2);

if(display_dst(DELAY_BLUR)!=0){return 0;}

}



//按任意键停止

display_caption("End:Press a key!");



waitKey(0);

return 0;

}

//中间显示标题,没有按键触发时返回0

int display_caption(char *caption)

{

dst=Mat::zeros(src.size(),src.type());

//opencv2.3.1中往图片上加字用putText函数,大家一看就应该知道参数是什么意思了

putText(dst,caption,Point(src.cols/4,src.rows/2),CV_FONT_HERSHEY_COMPLEX,1, Scalar(255,255,255));



imshow(window_name,dst);



//延时1.5s,注意在c++中是waitKey,该函数参数如果是非正数的话就直接停止在该位

//置等待按键触发,否则延时至少参数时长ms

int c=waitKey(DELAY_CAPTION);

if(c>=0){return -1;}

return 0;

}



//显示滤波后的图片,没有按键触发时返回0

int display_dst(int delay)

{

imshow(window_name,dst);

int c=waitKey(delay);

if(c>=0){return -1;}

else return 0;

}

 

 

对于具体的这4种滤波的具体算法,大家可以自己查看源代码,有时间我也会去具体学习的,今天这个其实没什么内在的东西,主要是让大家对滤波有个宏观的认识,已经对开发环境熟悉一下而已。

 

在看源代码过程中有看不懂的函数可以在一下2个网站上查看,其中第一个网站非常全

Opencv2.3后的版本英文帮助文件网页:http://opencv.itseez.com/index.html

中文网页:http://www.opencv.org.cn/index.php/Template:Doc

 

 

原图像:

 

滤波后图像:

 

作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:tornadomeet,欢迎交流!)
posted on 2012-03-03 12:03  tornadomeet  阅读(9838)  评论(6编辑  收藏  举报

阿萨德发斯蒂芬