第一次发博客。。。,程序参考于此处
关于轮廓提取cvFindContours函数和cvDrawContours函数的使用,不同的参数配合,有不同的功能,这个是比较迷惑的,自己动手实验才是正道。
// 2017-3-8-绘制轮廓.cpp
////////////////////////////////////////////////////
// 对轮廓的提取,如想绘制轮廓都得配合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
#include"opencv2/opencv.hpp"
int main()
{
cvNamedWindow("contour_test");
cvNamedWindow("contour_raw");
IplImage* img = cvLoadImage("轮廓原图.png", 0);
cvShowImage("contour_raw", img);
cvThreshold(img, img, 128, 255, CV_THRESH_BINARY);
IplImage* img_temp = cvCloneImage(img);
CvMemStorage* mem_storage = cvCreateMemStorage(0);
CvSeq *first_contour = NULL, *c = NULL;
cvFindContours(
img_temp,
mem_storage,
&first_contour,
sizeof(CvContour),
// CV_RETR_CCOMP - 提取所有轮廓,并且将其组织为两层的 hierarchy: 顶层为连通域的外围边界,次层为洞的内层边界。
// CV_RETR_TREE - 提取所有轮廓,并且重构嵌套轮廓的全部 hierarchy
CV_RETR_TREE //#1 需更改区域
);
cvZero(img_temp);
cvDrawContours(
img_temp,
first_contour,
cvScalar(100),
cvScalar(100),
// 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。
// 如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。
//如果值为负数,
// 函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。
2 //#2 需更改区域
);
cvShowImage("contour_test", img_temp);
/************************************************************************/
/*经分析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;
}
CV_RETR_CCOMP,2 如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓
图一
CV_RETR_CCOMP,0 如果等级为0,绘制单独的轮廓
图二
CV_RETR_CCOMP,1如果为1,绘制轮廓及在其后的相同的级别下轮廓
图三
CV_RETR_CCOMP,-1如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。
图四
CV_RETR_TREE 提取所有轮廓,并且重构嵌套轮廓的全部 hierarchy
CV_RETR_TREE ,-1
V_RETR_TREE ,0
V_RETR_TREE ,1
V_RETR_TREE ,2
// 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。
// 如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。
//如果值为负数, 函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。