OpenCV成长之路(8)直线、轮廓的提取与描述_第1页
OpenCV成长之路(8)直线、轮廓的提取与描述_第2页
OpenCV成长之路(8)直线、轮廓的提取与描述_第3页
OpenCV成长之路(8)直线、轮廓的提取与描述_第4页
OpenCV成长之路(8)直线、轮廓的提取与描述_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、OpenCV成长之路(8):直线、轮廓的提取与描述分类: OpenCV成长之路2014-01-04 18:35 689人阅读 评论(0) 收藏 举报opencv图像处理目录(?)+直线、轮廓的提取与描述基于内容的图像分析的重点是提取出图像中具有代表性的特征,而线条、轮廓、块往往是最能体现特征的几个元素,这篇文章就针对于这几个重要的图像特征,研究它们在OpenCV中的用法,以及做一些简单的基础应用。一、Canny检测轮廓在上一篇文章中有提到sobel边缘检测,并重写了soble的C+代码让其与matlab中算法效果一致,而soble边缘检测是基于

2、单一阈值的,我们不能兼顾到低阈值的丰富边缘和高阈值时的边缘缺失这两个问题。而canny算子则很好的弥补了这一不足,从目前看来,canny边缘检测在做图像轮廓提取方面是最优秀的边缘检测算法。canny边缘检测采用双阈值值法,高阈值用来检测图像中重要的、显著的线条、轮廓等,而低阈值用来保证不丢失细节部分,低阈值检测出来的边缘更丰富,但是很多边缘并不是我们关心的。最后采用一种查找算法,将低阈值中与高阈值的边缘有重叠的线条保留,其他的线条都删除。本篇文章中不对canny的算法原理作进一步说明,稍后会在图像处理算法相关的文章中详细介绍。下面我们用OpenCV中的Canny函数来检测图像边缘1. int&

3、#160;main()  2.   3.     Mat I=imread("./cat.png");  4.     cvtColor(I,I,CV_BGR2GRAY);  5.       6.     Mat contours;  7.    

4、 Canny(I,contours,125,350);  8.     threshold(contours,contours,128,255,THRESH_BINARY);  9.   10.     namedWindow("Canny");  11.     imshow("Canny",contours);  12. &

5、#160;   waitKey();  13.     return 0;  14.   显示效果如下:二、直线检测直线在图像中出现的频率非常之高,而直线作为图像的特征对于基本内容的图像分析有着很重要的作用,本文通过OpenCV中的hough变换来检测图像中的线条。我们先看最基本的Hough变换函数HoughLines,它的原型如下:1. void HoughLines(InputArray image, OutputArra

6、y lines, double rho,   2.                 double theta, int threshold, double srn=0, double stn=0 );  它的输出是一个二值的轮廓图像,往往是边缘检测得到的结果图像;它的输出是一个包

7、含多个Vec2f点的数组,数组中的每个元素是一个二元浮点数据对<rou,theta>,rou代表直线离坐标原点的距离,theta代表角度。第3和第4个参数代表步长,因为Hough变换实际上是一个穷举的算法,rho表示距离的步长,theta代表角度的步长。第5个参数是一个阈值设置直接的最低投票个数,知道Hough原理的,这个参数应该很容易理解。从这个函数的输出结果我们可以看出,得到的直线并没有指定在图像中的开始点与结束点,需要我们自己去计算,如果我们想把直接显示在图像中就会比较麻烦,而且会有很多角度接近的直线,其实它们是重复的,为了解决上面这些问题,OpenCV又提供了一个函数Hou

8、ghLinesP()。它的输出是一个Vector of Vec4i。Vector每一个元素代表一条直线,是由一个4元浮点数组构成,前两个点一组,后两个点一组,代表了在图像中直线的起始和结束点。1. void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta,  2.            &

9、#160;     int threshold, double minLineLength=0, double maxLineGap=0 );  解释一下最后两个参数,minLineLength指定了检测直线中的最小宽度,如果低于最小宽度则舍弃掉,maxLineGap指定通过同一点的直线,如果距离小于maxLineGap就会进行合并。下面是一个用HoughLinesP检测直线的例子:1. int main()  2.  

10、60;3.     Mat image=imread("./car.png");  4.     Mat I;  5.     cvtColor(image,I,CV_BGR2GRAY);  6.       7.     Mat contours; 

11、0;8.     Canny(I,contours,125,350);  9.     threshold(contours,contours,128,255,THRESH_BINARY);  10.   11.     vector<Vec4i> lines;  12.     / 检测直线,最小投票为90,线条不短于50,

12、间隙不小于10  13.     HoughLinesP(contours,lines,1,CV_PI/180,80,50,10);  14.     drawDetectLines(image,lines,Scalar(0,255,0);  15.   16.     namedWindow("Lines");  17.    

13、; imshow("Lines",image);  18.     waitKey();  19.     return 0;  20.   上面程序将检测到的线条保存在lines变量内,我们需要进一步将它们画在图像上:1. void drawDetectLines(Mat& image,const vector<Vec4i>& 

14、lines,Scalar & color)  2.   3.     / 将检测到的直线在图上画出来  4.     vector<Vec4i>:const_iterator it=lines.begin();  5.     while(it!=lines.end()  6.    &#

15、160;  7.         Point pt1(*it)0,(*it)1);  8.         Point pt2(*it)2,(*it)3);  9.         line(image,pt1,pt2,color,2); /  线条

16、宽度设置为2  10.         +it;  11.       12.   实际上Hough变换可以检测很多固定的形状,比如:圆、正方形等。它们的原理基本相同,都是构造一个投票矩阵。OpenCV里提供了检测圆的函数HoughCircles,它的输出是一个Vector of Vec3i,Vector的每个元素包含了3个浮点数,前2个是圆的中心坐标,最后一个是半径。三、轮廓的提取与描述在目标识

17、别中我们首先要把感兴趣的目标提取出来,而一般常见的步骤都是通过颜色或纹理提取出目标的前景图(一幅黑白图像,目标以白色显示在图像中),接下来我们要对前景图进行分析进一步地把目标提取出来,而这里常常用到的就是提取目标的轮廓。OpenCV里提取目标轮廓的函数是findContours,它的输入图像是一幅二值图像,输出的是每一个连通区域的轮廓点的集合:vector<vector<Point>>。外层vector的size代表了图像中轮廓的个数,里面vector的size代表了轮廓上点的个数。下面我们通过实例来看函数的用法。1. int main() 

18、0;2.   3.     using namespace cv;  4.   5.     Mat image=imread("./shape.png");  6.     cvtColor(image,image,CV_BGR2GRAY);  7.     vector<vect

19、or<Point>> contours;  8.     / find  9.     findContours(image,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);  10.     / draw  11.     Mat result(ima

20、ge.size(),CV_8U,Scalar(0);  12.     drawContours(result,contours,-1,Scalar(255),2);  13.   14.     namedWindow("contours");  15.     imshow("contours",result);  16.  

21、;   waitKey();  17.     return 0;  18.   上面程序中包含了2个函数,第一个是查找轮廓函数,它的第三个参数说明查找轮廓的类型,这里我们使用的是外轮廓,还可以查找所有轮廓,即包括一些孔洞的部分,像图像人物胳膊与腰间形成的轮廓。第4个参数说明了轮廓表示的方法,程序中的参数说明轮廓包括了所有点,也可以用其他参数让有点直线的地方,只保存直线起始与终点的位置点,具体参数用法可以参考手册里函数的介绍。第二个函数drawContou

22、rs是一个画轮廓的函数,它的第3个参数程序里设置-1表示所有的轮廓都画,你也可以指定要画的轮廓的序号。提取到轮廓后,其实我们更关心的是如果把这些轮廓转换为可以利用的特征,也就是涉及到轮廓的描述问题,这时就有多种方法可以选择,比如矢量化为多边形、矩形、椭圆等。OpenCV里提供了一些这样的函数。1. / 轮廓表示为一个矩形  2.     Rect r=boundingRect(Mat(contours0);  3.     rectangle(result

23、,r,Scalar(255),2);  4.       5.     / 轮廓表示为一个圆  6.     float radius;  7.     Point2f center;  8.     minEnclosingCircle(Mat(contours1),

24、center,radius);  9.     circle(result,Point(center),static_cast<int>(radius),Scalar(255),2);  10.   11.     / 轮廓表示为一个多边形  12.     vector<Point> poly;  13.   &

25、#160; approxPolyDP(Mat(contours2),poly,5,true);  14.     vector<Point>:const_iterator itp=poly.begin();  15.     while(itp!=(poly.end()-1)  16.       17.      

26、   line(result,*itp,*(itp+1),Scalar(255),2);  18.         +itp;  19.       20.     line(result,*itp,*(poly.begin(),Scalar(255),2);  21.     / 轮廓表示为凸多边形  22.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论