提取轮廓两种方法及绘制轮廓中最大等级分析

Posted zcube

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了提取轮廓两种方法及绘制轮廓中最大等级分析相关的知识,希望对你有一定的参考价值。

/************************************************************************/  
/* 提取轮廓两种方法对比及绘制轮廓'最大等级'分析                         */  
/************************************************************************/  
#include "stdafx.h"  
#include "cv.h"  
#include "highgui.h"  
  
int main()  
  
    IplImage* img = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);  
    IplImage* img_temp = cvCreateImage(cvGetSize(img), 8, 1);  
      
    cvThreshold(img, img, 128, 255, CV_THRESH_BINARY);  
      
    CvMemStorage* mem_storage = cvCreateMemStorage(0);  
    CvSeq *first_contour = NULL, *c = NULL;  
      
    
    //  
    // 1、  
    cvNamedWindow("contour1");  
    cvCopyImage(img, img_temp);  
	double t = (double)cvGetTickCount();
    cvFindContours(img_temp, mem_storage, &first_contour);  
    cvZero(img_temp);  
    cvDrawContours(  
        img_temp,   
        first_contour,  
        cvScalar(100),  
        cvScalar(100),  
        1  
        );  
	t = (double)cvGetTickCount() - t; 
    cvShowImage("contour1", img_temp);  
  
    printf("run1 = %gms\\n", t/(cvGetTickFrequency()*1000.));  
      
    cvClearMemStorage(mem_storage);  
      
    
    //  
    // 2、  
    cvNamedWindow("contour2");  
    cvCopyImage(img, img_temp);  
	t = (double)cvGetTickCount();
    CvContourScanner scanner = cvStartFindContours(img_temp, mem_storage);  
    while (cvFindNextContour(scanner));  
    first_contour = cvEndFindContours(&scanner);  
      
    cvZero(img_temp);  
    cvDrawContours(  
        img_temp,   
        first_contour,  
        cvScalar(100),  
        cvScalar(100),  
        1  
        );  
	t = (double)cvGetTickCount() - t; 
    cvShowImage("contour2", img_temp);  
	
	printf("run2 = %gms\\n", t/(cvGetTickFrequency()*1000.));  
      
    cvClearMemStorage(mem_storage);  
    cvReleaseImage(&img);  
    cvReleaseImage(&img_temp);  
  
    cvWaitKey();  

    /************************************************************************/  
    /* 经测试 run1 = 16.1431ms run2 = 15.8677ms (参考)
	   不过可以肯定这两中算法时间复杂度是相同的                                     */  
    /************************************************************************/  
      
    //  
    // 上述两种方法完成了对轮廓的提取,如想绘制轮廓都得配合cvDrawContours来使用  
    // 而cvDrawContours 函数第5个参数为 max_level 经查ICVL含义如下:  
    //  
    // 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。  
    // 如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。如果值为负数,  
    // 函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。  
    //  
    // 相信好多读者初次都无法理解等级的含义,而且测试时候输入>=1 的整数效果几乎一样  
    // 只有提取轮廓时候的提取模式设为 CV_RETR_CCOMP CV_RETR_TREE 时这个参数才有意义  
    //  
    // 经查FindContours 函数里面这样介绍提取模式(mode)的这两个参数:  
    // CV_RETR_CCOMP - 提取所有轮廓,并且将其组织为两层的 hierarchy: 顶层为连通域的外围边界,次层为洞的内层边界。   
    // CV_RETR_TREE - 提取所有轮廓,并且重构嵌套轮廓的全部 hierarchy   
    //   
    // 下面用第一种方法进行测试  
  
    cvNamedWindow("contour_test");  
    cvNamedWindow("contour_raw");  
    img = cvLoadImage("contour.jpg", CV_LOAD_IMAGE_GRAYSCALE);  
    cvShowImage("contour_raw", img);  
    cvThreshold(img, img, 128, 255, CV_THRESH_BINARY);  
    img_temp = cvCloneImage(img);  
    cvFindContours(  
        img_temp,   
        mem_storage,   
        &first_contour,  
        sizeof(CvContour),  
        CV_RETR_CCOMP           //#1 需更改区域  
        );  
  
    cvZero(img_temp);  
    cvDrawContours(  
        img_temp,   
        first_contour,  
        cvScalar(100),  
        cvScalar(100),  
        1                       //#2 需更改区域  
        );  
    cvShowImage("contour_test", img_temp);  
    /************************************************************************/  
    /* (1, 2) = (CV_RETR_CCOMP, 1)  如图1 
       (1, 2) = (CV_RETR_CCOMP, 2)  如图2 
       (1, 2) = (CV_RETR_TREE, 1)   如图3 
       (1, 2) = (CV_RETR_TREE, 2)   如图4 
       (1, 2) = (CV_RETR_TREE, 6)   如图5 
       经分析CV_RETR_CCOMP 只把图像分为两个层次,顶层和次层,一等级轮廓只匹配与其最接近 
       的内侧轮廓即2等级 
       CV_RETR_TREE 则从轮廓外到内按等级1 - n 全部分配         
       CV_RETR_LIST 全部轮廓均为1级                        */  
    /************************************************************************/  
  
    cvWaitKey();  
    cvReleaseImage(&img);  
    cvReleaseImage(&img_temp);  
    cvReleaseMemStorage(&mem_storage);  
    cvDestroyAllWindows();  
    return 0;  
  

 

原图

图一

图二


图三

图四

图五


以上是关于提取轮廓两种方法及绘制轮廓中最大等级分析的主要内容,如果未能解决你的问题,请参考以下文章

程序媛过中秋的正确打开方式——使用Python绘制月饼消消乐,素描图,词云图,字符画图及提取轮廓

高级特征提取

MATLAB应用实战系列(四十五)-matlab任意图形轮廓坐标提取含源代码

Python,OpenCV提取图片中的多个茄子种子轮廓,并按从左到右排序后显示

图像轮廓之查找并绘制轮廓

matlab怎么将图像处理的轮廓坐标连线起来