轮廓opencv检测闭合轮廓有什么?

9732人阅读
代码片(12)
图形图像(59)
OpenCV(61)
轮廓检测(4)
计算机视觉(43)
转载请注明出处:,
OpenCV里提取目标轮廓的函数是findContours,它的输入图像是一幅二值图像,输出的是每一个连通区域的轮廓点的集合:vector&vector&Point&&。外层vector的size代表了图像中轮廓的个数,里面vector的size代表了轮廓上点的个数。
轮廓进行填充的时候我会有下面2步骤:
a)依次遍历轮廓点,将点绘制到img上
void drawMaxAreaLine(cv::Mat &dst, const std::vector&cv::Point& maxAreaPoints)
int step = dst.
auto data = dst.
for (int i = 0; i & maxAreaPoints.size(); ++i)
*(data + maxAreaPoints[i].x + maxAreaPoints[i].y * step) = 255;
b)使用floodFill以及一个种子点进行填充
floodFill(savedGrayMat, Point(currentFrameEdge[0].x + 2, currentFrameEdge[0].y + 2), 255);
主要函数用法
C++:&void&findContours(InputOutputArray&image,
OutputArrayOfArrays&contours, int&mode, int&method, Point&offset=Point())
Python:&cv2.findContours(image,
mode, method[, contours[, hierarchy[, offset]]])&→
contours, hierarchy
Python:&cv.FindContours(image,
storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0, 0))&→ contours
Parameters:
image&– Source, an 8-bit single-channel image. Non-zero pixels are treated as 1’s. Zero pixels remain 0’s, so the image is treated asbinary&.
You can use&&,&&,&&,&&,&&,
and others to create a binary image out of a grayscale or color one. The function modifies the&image&while extracting the contours. If mode
equals to&CV_RETR_CCOMP&orCV_RETR_FLOODFILL,
the input can also be a 32-bit integer image of labels (CV_32SC1).contours&– Detected contours. Each contour is stored as a vector of points.hierarchy&– Optional output vector, containing information about the image topology. It has as many elements as the number of contours. 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&–
Contour retrieval mode (if you use Python see also a note below).
CV_RETR_EXTERNAL&retrieves only the extreme outer contours. It sets&hierarchy[i][2]=hierarchy[i][3]=-1&for
all the contours.CV_RETR_LIST&retrieves all of the contours without establishing any hierarchical relationships.CV_RETR_CCOMP&retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level,
there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.CV_RETR_TREE&retrieves all of the contours and reconstructs a full hierarchy of nested contours. This full hierarchy is built and shown in the OpenCV&contours.c&demo.
Contour approximation method (if you use Python see also a note below).
CV_CHAIN_APPROX_NONE&stores absolutely all the contour points. That is, any 2 subsequent points&(x1,y1)&and&(x2,y2)&of
the contour will be either horizontal, vertical or diagonal neighbors, that is,&max(abs(x1-x2),abs(y2-y1))==1.CV_CHAIN_APPROX_SIMPLE&compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points.CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS&applies one of the flavors of the Teh-Chin chain approximation algorithm. See&for
offset&– Optional offset by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image
cvFindContours(tour_buf,storage, &contour,sizeof(CvContour),&CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);&&&
& & & &tour_buf 是需要查找轮廓的单通道灰度图像 ,& & & &storage 是临时存储区 , &&& & & &contour是存储轮廓点的CvSeq实例, &&& & & &CV_RECT_EXTERNAL 只查找外围轮廓,还有CV_RECT_TREE & &
输入图像image必须为一个2值单通道图像
contours参数为检测的轮廓数组,每一个轮廓用一个point类型的vector表示
hiararchy参数和轮廓个数相同,每个轮廓contours[ i ]对应4个hierarchy元素hierarchy[ i ][ 0 ] ~hierarchy[ i ][ 3 ],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数。
mode表示轮廓的检索模式
CV_RETR_EXTERNAL表示只检测外轮廓
CV_RETR_LIST检测的轮廓不建立等级关系
CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
CV_RETR_TREE建立一个等级树结构的轮廓。具体参考contours.c这个demo
method为轮廓的近似办法
CV_CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
CV_CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
&&&&&&&& 正确调用查找函数后,接下来就是从轮廓序列contour(这里的contour不单单只有一个轮廓序列) 提取轮廓点了. &&& contour可能是空指针,提取前最好判断一下&&&在提取之前还可以调用一个函数:&&&
&&&&&&&& contour = cvApproxPoly( contour, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 3, 1 );&&&
&&&&&&&& 可能是拟合,有这一句找出的轮廓线更直。 &&contour里面包含了很多个轮廓,每个轮廓是单独存放的. &
#include &cv.h&
#include &iostream&
#include &cxcore.h&
#include &highgui.h&
#include &math.h&
#include &vector&
#include &algorithm&
#pragma comment(lib,&opencv_core2410d.lib&)
#pragma comment(lib,&opencv_highgui2410d.lib&)
#pragma comment(lib,&opencv_imgproc2410d.lib&)
typedef struct
CvPoint cP;
//自定义排序函数
namespace my
bool less(const RecP& s1, const RecP& s2)
//if(s1.cP.x & s2.cP.x && s1.cP.y & s2.cP.y)
return s1.cP.x & s2.cP.x;
//依次增大
void PrintVector( vector&RecP& & vec)
for(vector&RecP&::iterator n = vec.begin() ; n != vec.end() ; n++ )
cout&& n-&cP.x &&'\t'&& n-&cP.y &&'\t'&& n-&height&&'\t'&& n-&width &&
CvMemStorage* storage=NULL;
int thresh=50;
void on_trackbar(int pos)
CvSeq* contour=0;
if(storage==NULL)
dst=cvCreateImage(cvGetSize(bianyuan), 8, 3);
storage=cvCreateMemStorage(0);
cvClearMemStorage(storage);
cvSmooth(bianyuan, bianyuan, CV_GAUSSIAN, 3, 3, 0, 0);
cvThreshold( bianyuan, img, thresh, 200, CV_THRESH_BINARY);
cvNamedWindow( &threshold&, 1);
cvShowImage( &threshold&, img );
cvFindContours(img, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));
//查找轮廓
cvZero( dst );
//将数组中所有通道的所有元素的值都设置为0
vector&RecP& vecP;
for( ; contour = contour-&h_next )
CvRect rect=cvBoundingRect(contour,1);
// 获取矩形边界框
if(abs(rect.width-rect.height)&3)
rect.width=0;
rect.height=0;
rect.x = rect.x + 640;
rect.y = rect.y + 480;
CvPoint pt1=cvPoint(rect.x, rect.y), pt2=cvPoint(rect.x+rect.width, rect.y+rect.height);
//定义矩形对顶点
cvRectangle(dst, pt1, pt2, CV_RGB(255,0,0), 1, CV_AA, 0);
//绘制矩形边框
cvLine(dst, pt1, pt2, CV_RGB(0,255,0), 1, CV_AA, 0);
//矩形对角线相连
pt1=cvPoint(rect.x, rect.y+rect.height),
pt2=cvPoint(rect.x+rect.width, rect.y);
cvLine(dst, pt1, pt2, CV_RGB(0,255,0), 1, CV_AA,0);
//矩形对角线相连
CvPoint p1;
p1 = cvPoint(rect.x + rect.width/2, rect.y + rect.height/2);
//矩形中心坐标
tmp.cP = p1;
tmp.height = rect.
tmp.width = rect.
vecP.push_back(tmp);
//printf(&(%d,%d)\n&, p1);
sort(vecP.begin(), vecP.end(),my::less);
//依次增大
//printf(&(%d,%d):(%d,%d)\n&, vecP[n].cP, vecP[n].height, vecP[n].width);
PrintVector(vecP);
cvShowImage( &Components&, dst );
int main()
const char* a = &Chess.jpg&;
src = cvLoadImage(a, 0);
cvSmooth(src,src,CV_GAUSSIAN,5,5,0,0);
cvNamedWindow( &Source0000&,1);
cvShowImage( &Source0000&, src);
IplImage* bw =NULL;
IplImage* color=NULL;
IplImage* jh=NULL;
IplImage* sm=NULL;
if( !src )
return -1;
jh = cvCreateImage( cvGetSize(src), 8, 1 );
sm = cvCreateImage( cvGetSize(src), 8, 1 );
bw = cvCreateImage( cvGetSize(src), 8, 1 );
color = cvCreateImage( cvGetSize(src), 8, 3 );
cvEqualizeHist( src, jh);
cvSmooth(jh, sm, CV_MEDIAN, 3, 3, 0, 0);
cvCanny(sm,bw,200,600,3);
cvCvtColor( bw, color, CV_GRAY2BGR );
cvSaveImage(&color.bmp&,color);
const char* b = &color.bmp&;
bianyuan = cvLoadImage(b, 0);
img=cvCreateImage(cvGetSize(bianyuan),8,1);
cvNamedWindow( &Source&,1);
cvShowImage( &Source&, bianyuan);
cvNamedWindow( &Components&,1);
on_trackbar(0);
cvWaitKey(0);
cvDestroyWindow( &sorce& );
cvDestroyWindow( &threshold& );
cvDestroyWindow( &Components& );
cvReleaseImage( &src);
cvReleaseImage( &img );
cvReleaseImage(&dst);
cvReleaseMemStorage(&storage);
转载请注明出处:,
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
公众号:&&&&&老王和他的IT界朋友们
欢迎投稿:&&
我们想用一段音乐,几张图片,
些许文字绘制的IT圈心路历程,
为攻城狮,为程序员带来更多的人文关怀。
投稿原创文章有稿费,杂志等福利!!!
访问:515927次
积分:7909
积分:7909
排名:第1781名
原创:153篇
转载:50篇
译文:62篇
评论:406条
文章:38篇
阅读:30641
阅读:28288
文章:10篇
阅读:26932
阅读:12875
文章:46篇
阅读:194492
(4)(3)(5)(4)(7)(8)(4)(4)(4)(4)(4)(4)(5)(4)(7)(13)(14)(17)(12)(5)(4)(22)(14)(12)(5)(15)(1)(3)(5)(1)(3)(1)(3)(3)(3)(1)(1)(2)(1)(5)(4)(5)(1)(1)(9)OpenCV 轮廓检测心得笔记_Linux编程_Linux公社-Linux系统门户网站
你好,游客
OpenCV 轮廓检测心得笔记
来源:Linux社区&
作者:xuehuic
程序采用OpenCV中国的例程,下面列举了各个详细函数的功能及简单说明。
/*************************************************** 轮廓检测* 主要函数:*& & & cvFindContours*& & & cvDrawContours**************************************************//************************************************************************ OpenCV example* By Shiqi Yu 2006***********************************************************************/&#include "cv.h"#include "cxcore.h"#include "highgui.h"&int main( int argc, char** argv ){& //声明IplImage指针& IplImage* pImg = NULL; & IplImage* pContourImg = NULL;&&& CvMemStorage * storage = cvCreateMemStorage(0);& &//创建一个堆栈,存储轮廓用& CvSeq * contour = 0;& & //设置存取提取的指针& int mode = CV_RETR_EXTERNAL;& //提取物体最外层轮廓&& if( argc == 3)& & & if(strcmp(argv[2], "all") == 0)mode = CV_RETR_CCOMP; //内外轮廓都检测&&& //创建窗口& cvNamedWindow("src", 1);& cvNamedWindow("contour",1);&&& //载入图像,强制转化为Gray& if( argc &= 2 && & & & (pImg = cvLoadImage( argv[1], 0)) != 0 )& & {&& & & cvShowImage( "src", pImg );&& & & //为轮廓显示图像申请空间& & & //3通道图像,以便用彩色显示& & & pContourImg = cvCreateImage(cvGetSize(pImg),& IPL_DEPTH_8U,& 3);& & & //copy source image and convert it to BGR image& & & cvCvtColor(pImg, pContourImg, CV_GRAY2BGR);&&& & & //查找contour& & & cvFindContours( pImg, storage, &contour, sizeof(CvContour), & mode, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));&& & }& else& & {& & & //销毁窗口& & & cvDestroyWindow( "src" );& & & cvDestroyWindow( "contour" );& & & cvReleaseMemStorage(&storage);&& & & return -1;& & }&& //将轮廓画出& & & cvDrawContours(pContourImg, contour, CV_RGB(0,0,<span style="color: #), CV_RGB(<span style="color: #, 0, 0), 2, 2, 8, cvPoint(0,0));& //显示图像& cvShowImage( "contour", pContourImg );&& cvWaitKey(0);&&& //销毁窗口& cvDestroyWindow( "src" );& cvDestroyWindow( "contour" );& //释放图像& cvReleaseImage( &pImg ); & cvReleaseImage( &pContourImg ); && cvReleaseMemStorage(&storage);&& return 0;}
给出我自己搜索的一些函数介绍
可动态增长元素序列(OpenCV_1.0已发生改变,详见cxtypes.h) Growable sequence of elements
#define CV_SEQUENCE_FIELDS() /
/* micsellaneous flags */ /
int header_ /* size of sequence header */ /
struct CvSeq* h_ /* previous sequence */ /
struct CvSeq* h_ /* next sequence */ /
struct CvSeq* v_ /* 2nd previous sequence */ /
struct CvSeq* v_ /* 2nd next sequence */ /
/* total number of elements */ /
int elem_/* size of sequence element in bytes */ /
char* block_/* maximal bound of the last block */ /
char* /* current write pointer */ /
int delta_ /* how many elements allocated when the sequence grows (sequence granularity) */ /
CvMemStorage* /* where the seq is stored */ /
CvSeqBlock* free_ /* free blocks list */ /
CvSeqBlock* /* pointer to the first sequence block */
typedef struct CvSeq
CV_SEQUENCE_FIELDS()
结构CvSeq是所有OpenCV动态数据结构的基础。在1.0版本中,将前六个成员剥离出来定义成一个宏. 通过不同寻常的宏定义简化了带有附加
参数的结构 CvSeq 的扩展。为了扩展 CvSeq, 用户可以定义一新的数据结构或在通过宏CV_SEQUENCE_FIELDS()所包括的 CvSeq 的域后在放入用户自定义的域。
有两种类型的序列 -- 稠密序列和稀疏序列。稠密序列都派生自 CvSeq, 它们用来代表可扩展的一维数组 -- 向量,栈,队列,双端队列。数据间不存在空隙(即:连续存放)-- 如果元素从序列中间被删除或插入新的元素到序列中(不是两端),那么此元素后边的相关元素会被移动。稀疏序列都派生自 CvSet,后面会有详细的讨论。它们都是由节点所组成的序列,每一个节点要么被占用空间要么是空,由 flag 标志指定。这些序列作为无序的数据结构而被使用,如点集,图,哈希表等。
域 header_size(结构的大小) 含有序列头部节点的实际大小,此大小大于或等于 sizeof(CvSeq).当这个宏用在序列中时,应该等于 sizeof(CvSeq),若这个宏用在其他结构中,如CvContour,结构的大小应该大于sizeof(CvSeq); 域 h_prev, h_next, v_prev, v_next 可用来创建不同序列的层次结构。域 h_prev, h_next 指向同一层次结构前一个和后一个序列,而域 v_prev, v_next指向在垂直方向上的前一个和后一个序列,即:父亲和子孙。
域 first 指向第一个序列快,块结构在后面描述。
域 total 包含稠密序列的总元素数和稀疏序列被分配的节点数。
域 flags 的高16位描述(包含)特定的动态结构类型(CV_SEQ_MAGIC_VAL 表示稠密序列,CV_SET_MAGIC_VAL 表示稀疏序列),同时包含形形色色的信息。
低 CV_SEQ_ELTYPE_BITS 位包含元素类型的 ID(标示符)。大多数处理函数并不会用到元素类型,而会用到存放在 elem_size 中的元素大小 。如果序列中包含 CvMat 中的数据,那么元素的类型就与 CvMat 中的类型相匹配, 如:CV_32SC2 可以被使用为由二维空间中的点序列, CV_32FC1用为由浮点数组成的序列等。通过宏 CV_SEQ_ELTYPE(seq_header_ptr) 来获取序列中元素的类型。处理数字序列的函数判断: elem.size 等同于序列元素的大小。除了与 CvMat 相兼容的类型外,还有几个在头 cvtypes.h 中定义的额外的类型。
Standard Types of Sequence Elements
#define CV_SEQ_ELTYPE_POINT
/* (x,y) */
#define CV_SEQ_ELTYPE_CODE
/* freeman code: 0..7 */
#define CV_SEQ_ELTYPE_GENERIC
0 /* unspecified type of sequence elements */
#define CV_SEQ_ELTYPE_PTR
CV_USRTYPE1 /* =6 */
#define CV_SEQ_ELTYPE_PPOINT
CV_SEQ_ELTYPE_PTR
/* &elem: pointer to element of other sequence */
#define CV_SEQ_ELTYPE_INDEX
/* #elem: index of element of some other sequence */
#define CV_SEQ_ELTYPE_GRAPH_EDGE
CV_SEQ_ELTYPE_GENERIC
/* &next_o, &next_d, &vtx_o, &vtx_d */
#define CV_SEQ_ELTYPE_GRAPH_VERTEX
CV_SEQ_ELTYPE_GENERIC
/* first_edge, &(x,y) */
#define CV_SEQ_ELTYPE_TRIAN_ATR
CV_SEQ_ELTYPE_GENERIC
/* vertex of the binary tree
#define CV_SEQ_ELTYPE_CONNECTED_COMP CV_SEQ_ELTYPE_GENERIC
/* connected component
#define CV_SEQ_ELTYPE_POINT3D
/* (x,y,z)
后面的 CV_SEQ_KIND_BITS 字节表示序列的类型:
Standard Kinds of Sequences
/* generic (unspecified) kind of sequence */
#define CV_SEQ_KIND_GENERIC
(0 && CV_SEQ_ELTYPE_BITS)
/* dense sequence suntypes */
#define CV_SEQ_KIND_CURVE
(1 && CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_KIND_BIN_TREE
(2 && CV_SEQ_ELTYPE_BITS)
/* sparse sequence (or set) subtypes */
#define CV_SEQ_KIND_GRAPH
(3 && CV_SEQ_ELTYPE_BITS)
#define CV_SEQ_KIND_SUBDIV2D
(4 && CV_SEQ_ELTYPE_BITS)
CvMemStorage
Growing memory storage
typedef struct CvMemStorage
struct CvMemBlock*/* first allocated block */
struct CvMemBlock* /* the current memory block - top of the stack */
struct CvMemStorage* /* borrows new blocks from */
int block_ /* block size */
int free_ /* free space in the top block (in bytes) */
内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等动态增长数据结构的底层结构。它是由一系列以同等大小的内存块构成,呈列表型
---bottom 域指的是列首,top 域指的是当前指向的块但未必是列尾.在bottom和top之间所有的块(包括bottom, 不包括top)被完全占据了
空间;在 top和列尾之间所有的块(包括块尾,不包括top)则是空的;而top块本身则被占据了部分空间 -- free_space 指的是top块剩馀的
空字节数。
新分配的内存缓冲区(或显式的通过 cvMemStorageAlloc 函数分配,或隐式的通过 cvSeqPush, cvGraphAddEdge等高级函数分配)
总是起始于当前块(即top块)的剩馀那部分,如果剩馀那部分能满足要求(够分配的大小)。分配后,free_space 就减少了新分配的那部
分内存大小,外加一些用来保存适当列型的附加大小。当top块的剩馀空间无法满足被分配的块(缓冲区)大小时,top块的下一个存储块被
置为当前块(新的top块) -- free_space 被置为先前分配的整个块的大小。
如果已经不存在空的存储块(即:top块已是列尾),则必须再分配一个新的块(或从parent那继承,见 cvCreateChildMemStorage)并
将该块加到列尾上去。于是,存储器(memory storage)就如同栈(Stack)那样, bottom指向栈底,(top, free_space)对指向栈顶。
栈顶可通过 cvSaveMemStoragePos保存,通过 cvRestoreMemStoragePos 恢复指向, 通过 cvClearStorage 重置。
CreateMemStorage
创建内存块
CvMemStorage* cvCreateMemStorage( int block_size=0 );
block_size&存储块的大小以字节表示。如果大小是 0 byte, 则将该块设置成默认值 -- 当前默认大小为64k.
函数 cvCreateMemStorage 创建一内存块并返回指向块首的指针。起初,存储块是空的。头部(即:header)的所有域值都为 0,除了
block_size 外.
cvFindContours
cvFindContours可以得到一个图象所有的轮廓,返回的是轮廓的数量.它可以对cvCanny,cvThreshold(),cvAdaptiveThreshold()函数
处理得到的函数进行轮廓的提取.firstContour参数可以不用创建空间,在函数内部从函数cvFindNextContour返回轮廓的指针.最主要的是
method参数,这个参数涉及轮廓的存储方式,以及什么轮廓能被发现
cvFindContours的第5个参数
CV_RETR_EXTERNAL& & 查找外边缘,各边缘以指针h_next相连
CV_RETR_LIST& & & & & & &
查找所有边缘(包含内部空洞),各边缘以指针h_next相连
CV_RETR_CCOMP& & & &
查找所有边缘(包含内部空洞),按照如下方式组织
DrawContours
在图像中绘制外部和内部的轮廓。
void cvDrawContours( CvArr *img, CvSeq* contour,
CvScalar external_color, CvScalar hole_color,
int max_level, int thickness=1,
int line_type=8, CvPoint offset=cvPoint(0,0) );
img用以绘制轮廓的图像。和其他绘图函数一样,边界图像被感兴趣区域(ROI)所剪切。contour指针指向第一个轮廓。external_color外层轮廓的颜色。hole_color内层轮廓的颜色。max_level
绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。如果值为2,所有的轮廓。
如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为
abs(max_level)-1的子轮廓。
thickness绘制轮廓时所使用的线条的粗细度。如果值为负(e.g. =CV_FILLED),绘制内层轮廓。line_type线条的类型。参考cvLine.offset按照给出的偏移量移动每一个轮廓点坐标.当轮廓是从某些感兴趣区域(ROI)中提取的然后需要在运算中考虑ROI偏移量时,将会用到这个参数。
当thickness&=0,函数cvDrawContours在图像中绘制轮廓,或者当thickness&0时,填充轮廓所限制的区域。
#include "cv.h"
#include "highgui.h"
int main( int argc, char** argv )
// 第一条命令行参数确定了图像的文件名。
if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
cvThreshold( src, src, 1, 255, CV_THRESH_BINARY );
cvNamedWindow( "Source", 1 );
cvShowImage( "Source", src );
cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
cvZero( dst );
for(&; contour&!= 0; contour = contour-&h_next )
CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
/* 用1替代 CV_FILLED
所指示的轮廓外形 */
cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 );
cvNamedWindow( "Components", 1 );
cvShowImage( "Components", dst );
cvWaitKey(0);
在样本中用1替代 CV_FILLED 以指示的得到外形。
(注意:在cvFindContours中参数为CV_CHAIN_CODE时,cvDrawContours用CV_FILLED时不会画出任何图形)
&其他参数尝试的结果,下面的使用内外都检测 CV_RETR_CCOMP
--------------------------------------分割线 --------------------------------------
Linux下安装OpenCV2.4.1所需包
Ubuntu 12.04 安装 OpenCV2.4.2
下OpenCV无法读取视频文件
Ubuntu 12.04下安装OpenCV 2.4.5总结
Ubuntu 10.04中安装OpenCv2.1九步曲
基于QT和OpenCV的人脸识别系统
[翻译]Ubuntu 14.04, 13.10 下安装 OpenCV 2.4.9&
--------------------------------------分割线 --------------------------------------
OpenCV的详细介绍:OpenCV的下载地址:
本文永久更新链接地址:
相关资讯 & & &
& (02/27/:34)
& (12/11/:52)
& (01/18/:50)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款

我要回帖

更多关于 opencv检测闭合轮廓 的文章

 

随机推荐