opencv学习_9 (轮廓提取)

来源:互联网 发布:java图像局部虚化 编辑:程序博客网 时间:2024/05/16 12:17

轮廓提取——主要针对二值图像

<1> 轮廓分为外轮廓和内轮廓  如下图:外轮廓以c开头 内轮廓以h开头


<2> opencv 提供了寻找轮廓的函数 inttotals = cvFindContours(img, storage,&contours,sizeof(CvContour),  CV_RETR_LIST, CV_CHAIN_APPROX_NONE,cvPoint(0,0));

其中img是二值图像, storage是内存存储序列, contours指向存储的第一个轮廓,

CvMemStorage *storage =cvCreateMemStorage(0);  //内存存储序列

CvSeq *contours = 0;     //指向storage中的序列

 

CV_RETR_LIST表明轮廓在内存中的排列方式,有以下四种:

轮廓的排列方式<在内存中>

     CV_RETR_EXTERNAL:first = c0                         

    CV_RETR_CCOMP:从里到外 从右到左    这是一个双向链表

CV_RETR_LIST:

first = c01001 <–> c01000 <–>h0100 <–> h0000 <–> h0100 <–> h0000 <–> c010 <–>c000 <–> h01 <–> h00 <–> c0 这也是双向链表

CV_RETR_TREE

<3>案例

结果展示:

代码:

[cpp] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. #include "cv.h"  
  3. #include "cxcore.h"  
  4. #include "highgui.h"  
  5. using namespace std;  
  6. int main()  
  7. {  
  8.     CvMemStorage *storage = cvCreateMemStorage(0);   // 内存存储序列  
  9.     IplImage *img = cvLoadImage("E:\\study_opencv_video\\lesson14_1\\Debug\\55.png", 0);  
  10.     IplImage *imgColor = cvCreateImage(cvGetSize(img), 8, 3);  
  11.     IplImage *contoursImage = cvCreateImage(cvGetSize(img), 8, 1);  
  12.   
  13.     CvSeq *contours = 0, *contoursTemp = 0;    
  14.     cvZero(contoursImage);  
  15.     cvThreshold(img, img, 100, 255, CV_THRESH_BINARY);  // 二值化操作  
  16.     cvCvtColor(img, imgColor, CV_GRAY2BGR);  
  17.     int totals = cvFindContours(img, storage,&contours, sizeof(CvContour),    //img必须是一个二值图像 storage 用来存储的contours指向存储的第一个轮廓  
  18.         CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0));  
  19.     contoursTemp = contours;  
  20.     int count = 0;  
  21.     int i;  
  22.     for(;contoursTemp != 0; contoursTemp = contoursTemp -> h_next)  /// 这样可以访问每一个轮廓  ====横向轮廓  
  23.     {  
  24.         for(i = 0; i < contoursTemp -> total; i++)    // 提取一个轮廓的所有坐标点  
  25.         {  
  26.             CvPoint *pt = (CvPoint*) cvGetSeqElem(contoursTemp, i);   // 得到一个轮廓中一个点的函数cvGetSeqElem  
  27.             cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);  
  28.             cvSet2D(imgColor, pt->y, pt->x, cvScalar(0,0,255,0));  
  29.         }  
  30.         count ++;  
  31.         CvSeq *InterCon = contoursTemp->v_next;     // 访问每个轮廓的纵向轮廓  
  32.         for(; InterCon != 0; InterCon = InterCon ->h_next)  
  33.         {  
  34.             for(i = 0; i < InterCon->total; i++ )  
  35.             {  
  36.                 CvPoint *pt = (CvPoint*)cvGetSeqElem(InterCon, i);  
  37.                 cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);  
  38.                 cvSet2D(imgColor, pt->y, pt->x, cvScalar(0, 255, 0, 0));  
  39.             }  
  40.         }  
  41.     }  
  42.     cvNamedWindow("contoursImage");  
  43.     cvShowImage("contoursImage", contoursImage);  
  44.     cvNamedWindow("imgColor");  
  45.     cvShowImage("imgColor",imgColor);  
  46.     cvWaitKey(0);  
  47.     cvReleaseMemStorage(&storage);      // 也要释放内存序列空间  
  48.     cvReleaseImage(&contoursImage);  
  49.     cvReleaseImage(&imgColor);  
  50.     cvDestroyWindow("contoursImage");  
  51.     cvDestroyWindow("imgColor");  
  52.     return 0;<span style="font-family:Arial,Helvetica,sans-serif">}</span>  

作者:小村长  出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)
0 0
原创粉丝点击