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. W3School-CSS 分类 (Classification) 实例

    CSS 分类 (Classification) 实例 CSS 实例 CSS 背景实例 CSS 文本实例 CSS 字体(font)实例 CSS 边框(border)实例 CSS 外边距 (margin) ...

  2. .Net程序员飞扬有用的85个工具

    1.Visual Studio Visual Studio Productivity Power tool:Visual Studio专业版(及以上)的扩展,具有丰富的功能,如快速查找,导航解决方案, ...

  3. poj 2153

    题意:题目还是很简单的,就是求Li Ming 在班上的排名,而且成绩是相加的. 思路:用map就行.不然好像用qsort+二分也可以,不过我在那里碰到了一些状况,然后就没用这种方法了,简单的map就可 ...

  4. 数论初步(费马小定理) - Happy 2004

    Description Consider a positive integer X,and let S be the sum of all positive integer divisors of 2 ...

  5. OAViewObject中clearCache(),reset(),setMaxFetchSize(-1)的使用

    今天在页面跳转之后,明明执行了查询,且查询语句正确的情况下,页面不显示数据,且点击SubmitButton包浏览器后退异常. 代码如下: OAViewObjectImpl vo=(OAViewObje ...

  6. lotus 公式

    函数 描述@UserName 返回用户名或服务器名.@Name([key]; name) 更改用户名的格式.关键字包含 [CN] 以从一个专有名字中解析出公共名,[Abbreviate] 缩写规范格式 ...

  7. jar转dll

    IKVM http://www.cnblogs.com/luckeryin/archive/2012/03/28/2421274.html

  8. 【BZOJ1468】Tree

    Description 给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K Input N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是 ...

  9. 用bootstrap的tab插件做一个图层切换效果(感觉会误导淫们,大家当乐子看吧)

    小伙伴们啊,我JS真的是个渣渣,所以总想要偷懒,于是为了实现效果就把tab插件给改了(各位大神轻拍啊,我是小白,很纯洁滴,小心脏也很脆弱)…… 最近做的项目为了考虑以后的移动设备兼容性,所以用了Boo ...

  10. 使用匿名管道在进程间通信 (System.IO.Pipes使用)(转)

    原文地址:http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html 管道的用途是在同一台机器上的进程之间通信,也 ...