OpenCV函数cvFindContours

提取轮廓在OpenCV里有一个函数  cvFindContours  

  1. int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,int header_size=sizeof(CvContour),int mode=CV_RETR_LIST,int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );  

这个函数用起来很方便,但是随着你使用的深入,你会发现有一些迷惑在这里。比如当你提取轮廓时只需要最外围的一个轮廓,但是你会发现当轮廓画出来时是好几个;当你需要找一个最大轮廓时却发现找出来的却根本就不是你想要的那个。带着这样问题我们再来仔细看看 cvFindContours这个函数。
下边的是一位仁兄写的测试程序和测试图片,说明提取轮廓的两种方法及绘制轮廓中最大等级分析 问题,非常感谢他的分享,原文戳 这里
[cpp]   view plain copy
  1.       
  2.       
  3.       
  4. #include "stdafx.h"      
  5. #include "cv.h"      
  6. #include "highgui.h"      
  7.       
  8. int main()      
  9.      
  10.     IplImage* img cvLoadImage("lena.jpg"CV_LOAD_IMAGE_GRAYSCALE);      
  11.     IplImage* img_temp cvCreateImage(cvGetSize(img), 8, 1);      
  12.   
  13.     cvThreshold(img, img, 128, 255, CV_THRESH_BINARY);      
  14.   
  15.     CvMemStorage* mem_storage cvCreateMemStorage(0);      
  16.     CvSeq *first_contour NULL, *c NULL;      
  17.   
  18.     //      
  19.     // 1、      
  20.     cvNamedWindow("contour1");      
  21.     cvCopyImage(img, img_temp);      
  22.     double (double)cvGetTickCount();    
  23.     cvFindContours(img_temp, mem_storage, &first_contour);      
  24.     cvZero(img_temp);      
  25.     cvDrawContours(      
  26.         img_temp,       
  27.         first_contour,      
  28.         cvScalar(100),      
  29.         cvScalar(100),      
  30.              
  31.         );      
  32.     (double)cvGetTickCount() t;     
  33.     cvShowImage("contour1"img_temp);      
  34.   
  35.     printf("run1 %gms\n"t/(cvGetTickFrequency()*1000.));      
  36.   
  37.     cvClearMemStorage(mem_storage);      
  38.   
  39.     //      
  40.     // 2、      
  41.     cvNamedWindow("contour2");      
  42.     cvCopyImage(img, img_temp);      
  43.     (double)cvGetTickCount();    
  44.     CvContourScanner scanner cvStartFindContours(img_temp, mem_storage);      
  45.     while (cvFindNextContour(scanner));      
  46.     first_contour cvEndFindContours(&scanner);      
  47.           
  48.     cvZero(img_temp);      
  49.     cvDrawContours(      
  50.         img_temp,       
  51.         first_contour,      
  52.         cvScalar(100),      
  53.         cvScalar(100),      
  54.              
  55.         );      
  56.     (double)cvGetTickCount() t;     
  57.     cvShowImage("contour2"img_temp);      
  58.         
  59.     printf("run2 %gms\n"t/(cvGetTickFrequency()*1000.));      
  60.           
  61.     cvClearMemStorage(mem_storage);      
  62.     cvReleaseImage(&img);      
  63.     cvReleaseImage(&img_temp);      
  64.       
  65.     cvWaitKey();      
  66.     
  67.           
  68.           
  69.           
  70.           
  71.     //      
  72.     // 上述两种方法完成了对轮廓的提取,如想绘制轮廓都得配合cvDrawContours来使用      
  73.     // 而cvDrawContours 函数第5个参数为 max_level 经查ICVL含义如下:      
  74.     //      
  75.     // 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。      
  76.     // 如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。如果值为负数,      
  77.     // 函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。      
  78.     //      
  79.     // 相信好多读者初次都无法理解等级的含义,而且测试时候输入>=1 的整数效果几乎一样      
  80.     // 只有提取轮廓时候的提取模式设为 CV_RETR_CCOMP CV_RETR_TREE 时这个参数才有意义      
  81.     //      
  82.     // 经查FindContours 函数里面这样介绍提取模式(mode)的这两个参数:      
  83.     // CV_RETR_CCOMP 提取所有轮廓,并且将其组织为两层的 hierarchy: 顶层为连通域的外围边界,次层为洞的内层边界。       
  84.     // CV_RETR_TREE 提取所有轮廓,并且重构嵌套轮廓的全部 hierarchy       
  85.     //       
  86.     // 下面用第一种方法进行测试      
  87.       
  88.     cvNamedWindow("contour_test");      
  89.     cvNamedWindow("contour_raw");      
  90.     img cvLoadImage("contour.jpg"CV_LOAD_IMAGE_GRAYSCALE);      
  91.     cvShowImage("contour_raw"img);      
  92.     cvThreshold(img, img, 128, 255, CV_THRESH_BINARY);      
  93.     img_temp cvCloneImage(img);      
  94.     cvFindContours(      
  95.         img_temp,       
  96.         mem_storage,       
  97.         &first_contour,      
  98.         sizeof(CvContour),      
  99.         CV_RETR_CCOMP           //#1 需更改区域      
  100.         );      
  101.       
  102.     cvZero(img_temp);      
  103.     cvDrawContours(      
  104.         img_temp,       
  105.         first_contour,      
  106.         cvScalar(100),      
  107.         cvScalar(100),      
  108.                               //#2 需更改区域      
  109.         );      
  110.     cvShowImage("contour_test"img_temp);      
  111.           
  112.           
  113.           
  114.       
  115.     cvWaitKey();      
  116.     cvReleaseImage(&img);      
  117.     cvReleaseImage(&img_temp);      
  118.     cvReleaseMemStorage(&mem_storage);      
  119.     cvDestroyAllWindows();      
  120.     return 0;      
  121.  

原图

图一

图二


图三

图四

图五

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值