《学习openCV》例程解析 ex_8_3 (轮廓)
/*
我本人感觉例程有误,下面是修改后的英文(如:max_level)和例程,
运行时按住除ESC 键以外任意一个按键,可观察到轮廓从下往上的顺序
依次画出。外部轮廓为红色,内部轮廓为蓝色。
效果图:
我本人感觉例程有误,下面是修改后的英文(如:max_level)和例程,
运行时按住除ESC 键以外任意一个按键,可观察到轮廓从下往上的顺序
依次画出。外部轮廓为红色,内部轮廓为蓝色。
*/
/** In this example, we find contours on an input image and then proceed to draw them one by one. This is a good example to play with yourself and see what effects result from changing either the contour finding mode (CV_RETR_LIST in the code) or the max_level that is used to draw the contours (0 in the code). If you set max_level to a larger number, notice that the example code steps through the contours returned by cvFindContours() by means of h_next. Thus, for some topologies (CV_RETR_TREE, CV_RETR_CCOMP, etc.), you may see the same contour more than once as you step through. See Example 8-3. Example 8-3. Finding and drawing contours on an input image */ #include "stdafx.h" #include "cv.h" #include "highgui.h" #include "stdio.h" #define CVX_RED CV_RGB(0xff, 0x00, 0x00) #define CVX_GREEN CV_RGB(0x00, 0xff, 0x00) #define CVX_BLUE CV_RGB(0x00, 0x00, 0xff) int main() { IplImage* img_8uc1 = NULL; cvNamedWindow("img_contour", CV_WINDOW_AUTOSIZE); if (img_8uc1 = cvLoadImage("lena.jpg", 0)) //CV_LOAD_IMAGE_GRAYSCALE == 0 加载lena.jpg 灰度图 { IplImage* img_edge = cvCreateImage(cvGetSize(img_8uc1), 8, 1); IplImage* img_8uc3 = cvCreateImage(cvGetSize(img_8uc1), 8, 3); cvThreshold(img_8uc1, img_edge, 128, 255, CV_THRESH_BINARY); //对灰度图img_8uc1 像进行阈值操作得到二值图像 img_edge CvMemStorage* storage = cvCreateMemStorage(); //创建一个内存储存器 默认为 64K CvSeq* first_contour = NULL; //创建一个动态序列指针,用其指向第一个存储轮廓单元地址 int NC = cvFindContours( //cvFindContours从二值图像中检索轮廓,并返回检测到的轮廓的个数 img_edge, storage, //存储轮廓元素的储存容器 &first_contour, //指向第一个输出轮廓 sizeof (CvContour), CV_RETR_LIST //提取所有轮廓,并且放置在 list 中 ); printf("Total Contours Detected: %d\n", NC); cvCvtColor(img_8uc1, img_8uc3, CV_GRAY2BGR); //色彩空间转换,将img_8uc1 转换为BGR空间,img_8uc3 为转换后结果 int n = 0; //用于下面轮廓的记数 for (CvSeq* c=first_contour; c!=NULL; c = c->h_next) { //从第一个轮廓开始遍历,直到所有轮廓都遍历结束 cvDrawContours( img_8uc3, //用于绘制轮廓的图像 c, //指向目前轮廓所在地址空间 CVX_RED, //外层轮廓颜色 CVX_BLUE, //内层轮廓颜色 0, //等级为0,绘制单独的轮廓 1, //轮廓线条粗细 8 //线段类型为(8邻接)连接线 ); printf("Contour #%d\n", n); //输出第 n 个轮廓 cvShowImage("img_contour", img_8uc3); //显示目前已绘制的轮廓图像 printf("%d elements:\n", c->total); //输出构成目前轮廓点的个数 for (int i=0; i<c->total; i++) { CvPoint* p = CV_GET_SEQ_ELEM(CvPoint, c, i); //查找轮廓序列中索引所指定的点,并返回指向该点的指针 printf(" (%d, %d)\n", p->x, p->y); //输出该点坐标 } if (cvWaitKey() == 27) //按下ESC 键退出循环 break; n++; } printf("Finished all contours. Hit ESC to finish\n"); while (cvWaitKey() != 27); cvReleaseImage(&img_edge); cvReleaseImage(&img_8uc3); } cvDestroyWindow("img_contour"); cvReleaseImage(&img_8uc1); return 0; }