步骤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 
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_prevcvFindContours(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
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
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;}