opencv笔记(二十三)——寻找以及绘制一幅图像的轮廓

我们常常需要对一幅图像做轮廓的查找,尤其是在做物体的检测与识别的时候。

一般的步骤就是先使用canny方法来得到一幅图像的边缘情况。然后使用findContours方法来得到边缘图像的轮廓。最后使用drawContours方法来绘制轮廓。

canny我们都很清楚它的使用方法了。

这里简单地说一下findContours和drawContours

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

image是canny(或者其他方法)处理好的8位单通道图像。findContours方法把非零的值都认为是1。零值认为是0。即image认为是二值图像。

contours就是输出的轮廓。vector<vector<Point> > contours;是一组点的向量。

hierarchy是描述轮廓信息的信息。vector<Vec4i> hierarchy;每个contours[i]对应hierarchy[i][0]到hierarchy[i][3]这四个值。For each i-th contour contours[i] , the elements hierarchy[i][0] , hiearchy[i][1] , hiearchy[i][2] , and hiearchy[i][3] are set to 0-based indices in contours of the next and previous contours at the same hierarchical level, the first child contour and the parent contour, respectively. If for the contour i there are no next, previous, parent, or nested contours, the corresponding elements of hierarchy[i] will be negative.

mode是轮廓检索的模式。有CV_RETR_EXTERNAL, CV_RETR_LIST, CV_RETR_CCOMP, CV_RETR_TREE这四种,一般我们使用最后一种。

method是轮廓估算的方法。有CV_CHAIN_APPROX_NONE, CV_CHAIN_APPROX_SIMPLE, CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS,一般我们使用CV_CHAIN_APPROX_SIMPLE

offset是偏移量,这里不叙。保持默认。

void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )

有了findContours的说明,这个drawContours就比较简单了。看下面的代码,一目了然。

 1     Mat canny_output;
 2     vector<vector<Point> > contours;
 3     vector<Vec4i> hierarchy;
 4
 5     /// Detect edges using canny
 6     Canny( src_gray, canny_output, thresh, thresh*2, 3 );
 7     /// Find contours
 8     findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
 9
10     /// Draw contours
11     Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
12     for( int i = 0; i< contours.size(); i++ )
13     {
14         Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
15         drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
16     }
17
18     /// Show in a window
19     namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
20     imshow( "Contours", drawing );
时间: 2024-10-11 20:15:29

opencv笔记(二十三)——寻找以及绘制一幅图像的轮廓的相关文章

angular学习笔记(二十三)-$http(1)-api

之前说到的$http.get和$http.post,都是基于$http的快捷方式.下面来说说完整的$http: $http(config) $http接受一个json格式的参数config: config的格式如下: { method:字符串 , url:字符串, params:json对象, data:请求数据, headers:请求头, transformRequest:函数,转换post请求的数据的格式, transformResponse:函数,转换响应到的数据的格式, cache:布尔

OpenCV笔记(十三)——为图像加上边框

看这个题目,为什么要为一幅图像加上边框呢? 第一,做卷积的需要.当我们做卷积的时候,kernel往往不小于3X3的矩阵,那么首行.末行.首列.末列的元素就不能正确地与这个kernel做卷积.当我们给图像加上边框之后,就解决了这个问题. 第二.两幅大小不一致的图像进行操作的时候,为了保证运算的正确性,我们也要为图像加上边框,使两幅图像大小一致. 加边框有什么方法呢? 第一,很直接地,我们把图像的扩大之后,将边框的值设为一个固定的常量,常常是0,其他值亦可.这在OpenCV中叫BORDER_CONS

(转)【D3D11游戏编程】学习笔记二十三:Cube Mapping进阶之动态环境图

(注:[D3D11游戏编程]学习笔记系列由CSDN作者BonChoix所写,转载请注明出处:http://blog.csdn.net/BonChoix,谢谢~) 在前面两篇介绍Cube Mapping的文章中,我们所使用到的Cube Map都是事先制作好的,这样的一个好处就是运行时效率很高,适合于大多数情形.但如果对于即时动态变化的场景来说,依靠静态图来实现反射效果就不再适用了.因为在不同时刻,一个物体周围的场景是不断变化的,想要把这些变化在物表的反射中体现出来,就需要一张动态的环境图. 1.C

Android学习笔记二十三.Service组件入门(一).什么是Service?

什么是Service? 一.Service 1.Service简介 Service为Android四大组件之一,Service与Activity组件相似,都代表可执行的程序且有自己的生命周期,唯一的区别是Activity组件提供界面方便人机交互而Service只在后台运行且没有交互界面.需要注意的是,Service不是一个单独的进程或为了防止应用出现无反应错误单独的线程,它像其他应用对象一样运行在其托管进程的主线程中.当然,如果我们希望自己的Service能够在后台运行MP3或者网络下载,我们可

《Programming in Lua 3》读书笔记(二十三)

日期:2014.8.7 PartⅣ The C API 27 Calling C from Lua 在这里说Lua调用C函数,并不意味着Lua可以调用任意的C函数.与之前C调用Lua函数一样,在这里同样需要遵循一些规则:传递参数,得到结果.不仅如此,Lua要调用C函数,我们首先需要注册这个函数,即需要将该函数的地址传递给Lua. 当Lua调用C函数的时候,也是使用栈来做参数和返回结果的传递.C函数从栈中得到参数,然后将结果push至栈中. 在这里一个重要的概念是:栈不是一个全局结构:每个函数都有

Android笔记二十三.Android基于事件监听器处理机制

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Android的事件处理 Android事件处理包括两个部分:Android事件处理机制(基本)和Android消息传递机制(进阶).前者包含三种处理方式,即基于监听的事件处理.基于回调的事件处理.直接绑定到标签;后者包含两种处理方式,即Handler消息传递.异步任务处理. 1.Android的事件处理机制 (1)基于监听的事件处理方式 通常做法是为Android界面组件绑定特定的事件监听

Java基础学习笔记二十三 Java核心语法之反射

类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化三步来实现对这个类进行初始化. 加载就是指将class文件读入内存,并为之创建一个Class对象.任何类被使用时系统都会建立一个Class对象. 链接指的是将Java类的二进制代码合并到JVM的运行状态之中的过程.在链接之前,这个类必须被成功加载.类的链接包括验证.准备和解析等几个步骤. 验证:是否有正确的内部结构,并和其他类协调一致. 准备:负责为类的静态成员分配内存,并设置默认初始化值 解析:

Java笔记二十三.网络编程基础与UDP编程

网络编程基础与UDP编程 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.网络编程基础 1.TCP/IP协议:TCP/IP协议是一个非常实用的网络应用程序通信协议,包括TCP(传输控制协议)和IP地址(计算机唯一标识号). 2.IP地址:IP在互联网中能唯一标识一台计算机,是每一台计算机的唯一标识(身份证),通过这个标识号来指定接收数据的计算机和识别发送数据的计算机,该标识号即为IP地址. (1)Ipv4:指在计算机中IP地址用4个字节(

PHP学习笔记二十三【This】

<?php Class Person { function test1() { $this->test2();//类里面的方法互相调用要加$this } protected function test2() { echo "test2"; } } ?>