步骤1:转化为二值图像,因为cvFindContours要求必须为二值图像:cvThreshold
步骤2:备份二值图像,因为cv FindContours 会改变原二值图像:cvClone或cvCopy
步骤3:创建彩***像(在原图上用红色边框表示轮廓)和黑白图像(只画出轮廓)用于演示:cvCreateImage,cvCvtColor
步骤4:查找轮廓: cvCreateMemStorage,cvFindContours
步骤5:打印结果:cvGetSeqElem,cvSetReal2D,cvSet2D
#include "cv.h" #include "cxcore.h" #include "highgui.h" #include <iostream> int FindContours(int argc,char** argv) { IplImage* src=cvLoadImage("e:\\FindContours.png",CV_LOAD_IMAGE_GRAYSCALE); //注意要以灰度图像方式加载,默认1为彩***像 cvNamedWindow("src"); cvShowImage("src",src); //步骤1:转化为二值图像,因为cvFindContours要求必须为二值图像 IplImage* BinaryImage=cvCreateImage(cvGetSize(src),8,1); cvZero(BinaryImage); cvThreshold(src,BinaryImage,100,255,CV_THRESH_BINARY); //cvNamedWindow("BinaryImage"); //cvShowImage("BinaryImage",BinaryImage); //步骤2:备份二值图像,因为cvThreshold会改变原二值图像 IplImage *BinaryImageClone=(IplImage *)cvClone(BinaryImage); cvNamedWindow("BinaryImageClone"); cvShowImage("BinaryImageClone",BinaryImageClone); //步骤3:创建彩***像(在原图上用红色边框表示轮廓)和黑白图像(只画出轮廓)用于演示 IplImage *ContoursColor=cvCreateImage(cvGetSize(src),8,3); cvZero(ContoursColor); cvCvtColor(BinaryImage,ContoursColor,CV_GRAY2BGR); //把原图处理成的灰度二值图转换为BGR彩*** IplImage *ContoursGray=cvCreateImage(cvGetSize(src),8,1); cvZero(ContoursGray); //步骤4:查找轮廓 CvMemStorage* storage=cvCreateMemStorage(0); cvClearMemStorage(storage); CvSeq* FirstPoint=0; //方式1:CV_RETR_EXTERNAL,只寻找最外轮廓 //cvFindContours(BinaryImage,storage,&FirstPoint,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE,cvPoint(0,0)); //方式2:CV_RETR_LIST,寻找所有轮廓,并且用CvSeq*的h_next和h_prev和从右到左,从内到外串起来 //cvFindContours(BinaryImage,storage,&FirstPoint,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_NONE,cvPoint(0,0)); //方式3:CV_RETR_CCOMP,寻找所有轮廓,并且用CvSeq*的h_next,h_prev和v_next,v_prev和从右到左,从内到外串起来 //内轮廓和外轮廓之间用v_next,v_prev;内轮廓和内轮廓,外轮廓和外轮廓之间用h_next,h_prev cvFindContours(BinaryImage,storage,&FirstPoint,sizeof(CvContour),CV_RETR_CCOMP,CV_CHAIN_APPROX_NONE,cvPoint(0,0)); //方式4:CV_RETR_TREE,从最高到最低按照树形结构用双向指针串起来 //cvFindContours(BinaryImage,storage,&FirstPoint,sizeof(CvContour),CV_RETR_TREE,CV_CHAIN_APPROX_NONE,cvPoint(0,0)); cvNamedWindow("FindContours"); cvShowImage("FindContours",BinaryImage); CvSeq* PointTemp=FirstPoint; //步骤5:打印结果 for(;PointTemp!=NULL;PointTemp=PointTemp->h_next) { for(int i=0;i<PointTemp->total;i++) { CvPoint *point=(CvPoint *)cvGetSeqElem(PointTemp,i); cvSetReal2D(ContoursGray,point->y,point->x,255.0); cvSet2D(ContoursColor,point->y,point->x,cvScalar(0,0,255,NULL)); } CvSeq* vnext=PointTemp->v_next; for(;vnext!=NULL;vnext=vnext->h_next) { for(int k=0;k<vnext->total;k++) { CvPoint *point=(CvPoint *)cvGetSeqElem(vnext,k); cvSetReal2D(ContoursGray,point->y,point->x,255.0); cvSet2D(ContoursColor,point->y,point->x,cvScalar(0,0,255,NULL)); } } } cvNamedWindow("ContoursColor"); cvShowImage("ContoursColor",ContoursColor); cvNamedWindow("ContoursGray"); cvShowImage("ContoursGray",ContoursGray); cvWaitKey(0); cvDestroyWindow("src"); cvDestroyWindow("BinaryImage"); cvDestroyWindow("BinaryImageClone"); cvDestroyWindow("ContoursColor"); cvDestroyWindow("ContoursGray"); cvReleaseImage(&src); cvReleaseImage(&BinaryImage); cvReleaseImage(&BinaryImageClone); cvReleaseImage(&ContoursColor); cvReleaseImage(&ContoursGray); cvReleaseMemStorage(&storage); return 0; }