您的位置:首页 > 运维架构

OpenCV学习之旅2—边缘检测技术

2011-08-11 15:40 197 查看
有一段时间没做总结了,天天不知道在忙什么啊!现在花一个小时的时间将第这几天学习的总结一下。

边缘检测技术是图像分析的第一步,主要是利用图像的一阶导数的极值或者是二阶导数过零点点信息来提取边缘。

说得简单点就是图像灰度变化的问题,在某些地方图像变化缓慢,那么它的一阶导数就小甚至为零,在变化剧烈的地方,就较大。书本上说的梯度,也就相当于导数,只是它有自己的方向而已。二阶导数是用来判断像素是在边缘亮的一边还是在暗的一边。

这几句话就说明了边缘检测的基本理论和方法。

具体在OpenCV中怎么来实现啊!主要是通过用图像与各种不同的算子来做卷积实现。在这儿我根据openCV分成两大阵营的来实现。

第一阵营:有函派:就是在openCV中有具体的函数,我们只要调用就好了。这个做起来很简单。

主要有sobel、Canny、Laplace。

cvSmooth(img_Elged_src,img_Elged_8u,CV_GAUSSIAN,3,0,0);
//cvShowImage("Elged",img_Elged_8u);
cvSobel(img_Elged_8u,img_Elged_16S,m_nSobelx,m_nSobely,m_nKernel);
//cvSobel(img_Elged_8u,img_Elged_16S,0,1,3);
cvConvertScaleAbs(img_Elged_16S,img_Elged_dest,1,0);
cvShowImage("Elged",img_Elged_dest);
cvSmooth(img_Elged_src,img_Elged_8u,CV_GAUSSIAN,3,0,0);
cvCanny(img_Elged_8u,img_Elged_dest,m_nCanny1,m_nCanny2,m_nKernel);
cvShowImage("Elged",img_Elged_dest);
cvSmooth(img_Elged_src,img_Elged_8u,CV_GAUSSIAN,3,0,0);
cvLaplace(img_Elged_8u,img_Elged_16S,m_nKernel);
cvConvertScaleAbs(img_Elged_16S,img_Elged_dest,1,0);
cvShowImage("Elged",img_Elged_dest);

使用这几个函数的时候,有几个要注意的地方。

1.cvSobel、cvLaplace函数里面要求的dest图像是IPL_DEPTH_16S;

2.如何将IPL_DEPTH_16S转换成IPL_DEPTH_8U型需要用到的函数是cvConvertScaleAbs

3.kernel核只能是1,3,5,7再大就会出错,目前来讲是这样的。

第二阵营:无函数派;如:Robert\Prewit\Krish等。只是没有直接可以调用的函数,并不是说在OpenCV中就不能实现。这些算法不仅能实现而且要比上面的函数实现起来更加灵活。这儿要用到的函数有:

cvFilter2D函数,这是一个做卷积的函数。正是因为这个函数可以帮我们省去了想VisualC++那样的for循环来实现。而且边缘处理就是卷积的一个过程。那么如何实现能?

首先,你得要有自己的kernel也就是通俗的模板。在这个函数具体形式如下;

cvFilter2D(

constCvArr*src,

CvArr*dst,

constCvMat*kernel,

CvPointanchor=cvPoint(-1,-1));

可以看出这模板必须是Cvmat*型才可以。创建Cvmat型有以下几种办法:
指针型:
CvMat*Tempt3;
Tempt3=cvCreateMat(3,3,CV_32F);
floata[9]={-3,5,5,-3,0,5,-3,-3,-3};
cvInitMatHeader(Tempt3,3,3,CV_32F,a);

变量型:
CvMatTempt3;
Tempt3=cvCreateMat(3,3,CV_32F);
floata[9]={-3,5,5,-3,0,5,-3,-3,-3};
Tempt3=cvMat(3,3,CV_32F,a);


然后就可以调用cvFilter2D来实现了,这个模板主要是靠数组先定义。
最后要注意的一些问题:
1.模板CvMat必须是浮点型;CV_F32等形式;
2.数组a的定义也必须是浮点型;
3.如果是定义变量型的时候要记得加上&Tempt3;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: