zoukankan      html  css  js  c++  java
  • cvFindContours函数

    cvFindContours函数:
    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) );
    image:
      8比特单通道的源二值图像。非零像素作为1处理,0像素保存不变。从一个灰度图像得到二值图像的函数有:cvThreshold,cvAdaptiveThreshold和cvCanny。
    storage:返回轮廓的容器。
    first_contour:
      输出参数,用于存储指向第一个外接轮廓。
    header_size:
      header序列的尺寸.如果选择method = CV_CHAIN_CODE, 则header_size >= sizeof(CvChain);其他,则 header_size >= sizeof(CvContour)。
    mode:
      CV_RETR_EXTERNAL:只检索最外面的轮廓;
      CV_RETR_LIST:检索所有的轮廓,并将其放入list中;
      CV_RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
      CV_RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次。

       蓝色表示v_next,绿色表示h_next
    method:
      边缘近似方法(除了CV_RETR_RUNS使用内置的近似,其他模式均使用此设定的近似算法)。可取值如下:
      CV_CHAIN_CODE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
      CV_CHAIN_APPROX_NONE:将所有的连码点,转换成点。
      CV_CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
      CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS:使用the flavors of Teh-Chin chain近似算法的一种。
      CV_LINK_RUNS:通过连接水平段的1,使用完全不同的边缘提取算法。使用CV_RETR_LIST检索模式能使用此方法。
    offset:
      偏移量,用于移动所有轮廓点。当轮廓是从图像的ROI提取的,并且需要在整个图像中分析时,这个参数将很有用。

    我的一个不知道从哪里抄来的栗子:

    #include "stdafx.h"
    
    #include "cv.h"
    #include "highgui.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)
    
    using namespace cv;
    
    int main()  
    {  
        IplImage* img_8uc1 = NULL;  
        cvNamedWindow("img_contour", CV_WINDOW_AUTOSIZE);  
    
        if (img_8uc1 = cvLoadImage("cv38.jpg", 0))          
        {  
            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
    ", 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)  
            {   //从第一个轮廓开始遍历,直到所有轮廓都遍历结束  
    
                CvRect rect = cvBoundingRect(c,1); 
    
                if (rect.height > 0 && rect.width > 0 )
                {
                    if ( (double)rect.height / (double)rect.width > 5 || (double)rect.height / (double)rect.width < 0.2 )
                    {
                        continue ;
                    }
                }
    
                if ( cvContourArea(c) < 20 )
                {
                    continue ;
                }
    
                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("Finished all contours. Hit ESC to finish
    ");  
    
            while (cvWaitKey() != 27);  
    
            cvReleaseImage(&img_edge);  
            cvReleaseImage(&img_8uc3);  
        }  
        cvDestroyWindow("img_contour");  
        cvReleaseImage(&img_8uc1);  
        return 0;  
    }  

      代码注释还算仔细,我就不想多写了。

  • 相关阅读:
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    centos 编码问题 编码转换 cd到对应目录 执行 中文解压
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    Android MVP 十分钟入门!
    mysql备份及恢复
    mysql备份及恢复
    mysql备份及恢复
  • 原文地址:https://www.cnblogs.com/betterwgo/p/6561445.html
Copyright © 2011-2022 走看看