opencv学习笔记(二)寻找轮廓

  opencv中使用findContours函数来查找轮廓,这个函数的原型为:

 void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierar-
 chy, int mode, int method, Point offset=Point())

 /*
 参数说明:

 image:输入图像image必须为一个2值单通道图像;

 contours:为检测的轮廓数组,每一个轮廓用一个point类型的vector表示,vector<Point>,则轮廓的集合可表示为vector<vector<Point>>;

 hiararchy:参数和轮廓个数相同,每个轮廓contours[i]对应hierarchy元素hierarchy[i][0]—hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数;

 mode:轮廓的检索模式

 a.CV_RETR_EXTERNAL:表示只检测外轮廓

 b.CV_RETR_LIST:检测的轮廓不建立登记关系

 c.CV_RETR_CCOMP:建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。

 d.CV_RETR_TREE:建立一个等级树结构的轮廓。

 method:轮廓的近似方法

 a.CV_CHAIN_APPROX_NONE:存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2)),abs(y2-y1))==1

 b.CV_CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
   c.CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法offset表示代表轮廓点的偏移量,可以设置为任意值。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数还是很有用的。
 */

  findContours后会对输入的2值图像改变,所以如果不想改变该2值图像,需创建新mat来存放,findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP函数对该多边形曲线做适当近似;contourArea函数可以得到当前轮廓包含区域的大小,方便轮廓的筛选。

  findContours函数经常与drawcontours配合使用,用来将轮廓绘制出来,函数原型为:

  , , InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )

 /*
 参数说明:

 image:目标图像

 contours:输入的轮廓组,每一组轮廓由点vector构成

 contourIdx:指明画第几个轮廓,如果该参数为负值,则画全部轮廓

 color:轮廓的颜色

 thickness:轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内容

 lineType:为线型

 hierarchy:如果你想画出图像的一部分轮廓,那么你就需要它

 maxLevel:用于画轮廓的最大成,如果为0,只是画出指定轮廓,如果为1,画出第一层的所有轮廓,如果为2,画出第一和第二层的所有轮廓,依次类推,这个参数只有在有层次关系的时候被使用

 offset:每个轮廓点的偏移量

 */

  得到了复杂轮廓往往不适合特征的检测,这里再介绍一个点集凸包络的提取函数convexHull,输入参数就可以是contours组中的一个轮廓,返回外凸包络的点集。

  还可以得到轮廓的外包络矩形,使用boundingRect,函数原型为:

 Rect boundingRect(InputArray points)

 //  points:二维点集
 //  返回:包围轮廓的2D矩形的模板类Rect
 //功能:对指定的点集进行包含,使得形成一个最合适的正向矩形框把当前指定的点集都框住

  如果想得到旋转的外包络矩形,使用函数minAreaRect 函数原型:

 RotatedRect minAreaRect(InputArray points)
 //points:输入的2维向量点,其类型为:std::vector<> or Mat
 ////函数功能:为一个指定的点集计算并返回的最小边界矩形(可能旋转)4 //返回值类型:RotatedRect

  也可以得到轮廓的外包络圆,对应的函数为minEnclosingCircle;想得到轮廓的外包络椭圆,对应的函数为fitEllipse,返回值也是RotatedRect类型,可以用ellipse函数画出对应的椭圆;

  如果想根据多边形的轮廓信息得到多边形的多阶矩,可以使用类moments;

  如果想获得一点与多边形封闭轮廓信息,可以调用pointPolygonTest函数,这个函数返回值为该点距离轮廓最近边界的距离,为正值为在轮廓内部,负值为在轮廓外部,0表示在边界上。

Example

 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/imgproc/imgproc.hpp"
 #include <iostream>
 using namespace cv;
 using namespace std;
 int main()
 {

     const char* inputImage = "rice.jpg";//输入图像名称
     Mat img;
     img = imread(inputImage, );
     //判断图像存在与否
     if (img.empty())
     {
         cout << "Could not read input image file: " << inputImage << endl;
         ;
     }

     namedWindow();
     imshow("Img", img);
     //二值化,为提取轮廓做准备
     threshold(img, img, , , CV_THRESH_OTSU + CV_THRESH_BINARY);
     namedWindow();
     imshow("thr_img", img);
     //创建轮廓集合
     vector<vector<Point> > contours;
     //创建层级hierarchy
     vector<Vec4i>hierarchy;
     Mat dst = Mat::zeros(img.rows, img.cols, CV_8UC3);
     findContours(img, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
     if (!contours.empty() && !hierarchy.empty())
     {
         ;
         ; idx = hierarchy[idx][])//hierarchy[idx][0]表示当前轮廓序号idx的下一个轮廓
         {
             Scalar color((rand() & ), (rand() & ), (rand() & ));
             drawContours(dst, contours, idx, color, , , hierarchy);
         }
     }
     namedWindow();
     imshow("Connected Components", dst);
     waitKey();
     ;
 }

opencv学习笔记(二)寻找轮廓的更多相关文章

  1. opencv学习笔记(七)SVM+HOG

    opencv学习笔记(七)SVM+HOG 一.简介 方向梯度直方图(Histogram of Oriented Gradient,HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子 ...

  2. opencv学习笔记(一)IplImage, CvMat, Mat 的关系

    opencv学习笔记(一)IplImage, CvMat, Mat 的关系 opencv中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage,这三种类型都可以代表和显示图像,但是,M ...

  3. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  4. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  5. OpenCV 学习笔记(模板匹配)

    OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够 ...

  6. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  7. opencv学习笔记(六)直方图比较图片相似度

    opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...

  8. opencv学习笔记(五)镜像对称

    opencv学习笔记(五)镜像对称 设图像的宽度为width,长度为height.(x,y)为变换后的坐标,(x0,y0)为原图像的坐标. 水平镜像变换: 代码实现: #include <ios ...

  9. opencv学习笔记(四)投影

    opencv学习笔记(四)投影 任选了一张图片用于测试,图片如下所示: #include <cv.h> #include <highgui.h> using namespace ...

随机推荐

  1. 使用Lucene索引和检索POI数据

    1.简介 关于空间数据搜索,以前写过<使用Solr进行空间搜索>这篇文章,是基于Solr的GIS数据的索引和检索. Solr和ElasticSearch这两者都是基于Lucene实现的,两 ...

  2. 没有为 COM 互操作注册程序集 请使用 regasm.exe /tlb 注册该程序集——解决办法

    错误现象: 错误 6 没有为 COM 互操作注册程序集“DevExpress.Utils.v13.1, Version=13.1.7.0, Culture=neutral, PublicKeyToke ...

  3. Arcmap 安装完后使用出现visual fortran run-time error的解决方法

    今天将ArcGIS安装到自己的XP笔记本上,安装过程一帆风顺,但打开Arcmap使用的时候,出现了visual fortran run-time error. 下面是解决方法: 下载个Dforrt.d ...

  4. LXD 2.0 系列(四):资源控制

    LXD 提供了各种资源限制.其中一些与容器本身相关,如内存配额.CPU 限制和 I/O 优先级.而另外一些则与特定设备相关,如 I/O 带宽或磁盘用量限制.-- Stéphane Graber 本文导 ...

  5. java中基本类型和包装类型实践经验

    至今,小菜用java快两年了,有些事,也该有个总结. 基本类型和包装类型的概念在本文不作赘述. 如果这两种类型直接使用,倒没什么值得讨论的,无非就是自动装箱拆箱,java可以让你感觉不到他们的存在,但 ...

  6. intellJ实用技巧

    常用语句 在IntelJ中和Eclipse中稍有不同,在Eclipse中,输入main再按Alt+/即可自动补全main函数,但是在IntellJ中则是输入psvm. 在方法体内部有for循环,在In ...

  7. 一个使用高并发高线程数 Server 使用异步数据库客户端造成的超时问题

    现象 今天在做一个项目时, 将 tomcat 的 maxThreads 加大, 加到了 1024, tomcat 提供的服务主要是做一些运算, 然后插入 redis, 查询 redis, 最后将任务返 ...

  8. C语言 二级指针内存模型①

    //二级指针第一种内存模型 #include<stdio.h> #include<stdlib.h> //说明:①:类似于int a[5]={0},数组名a是一维数组a中首元素 ...

  9. iphone越狱还原

    在Cydia 里安装Impactor 就行了 .在操作时需要全程联网: .请至少保证 % 的电量以防止在恢复过程出现断电的情况(建议将设备连接至电源): .设备将恢复至出厂状态,所有用户数据都将被清除 ...

  10. java语法体系

    乱写的不具备参考性,只是一个备忘录