首页 > 代码库 > 第19集 轮廓的提取

第19集 轮廓的提取

步骤1:转化为二值图像,因为cvFindContours要求必须为二值图像:cvThreshold

步骤2:备份二值图像,因为cv FindContours 会改变原二值图像:cvClone或cvCopy

步骤3:创建彩***像(在原图上用红色边框表示轮廓)和黑白图像(只画出轮廓)用于演示:cvCreateImage,cvCvtColor

步骤4:查找轮廓: cvCreateMemStorage,cvFindContours

步骤5:打印结果:cvGetSeqElem,cvSetReal2D,cvSet2D

wKiom1PsexqwcQjKAALq9OBcTJU772.jpg

#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
int FindContours(int argc,char** argv)
{
IplImage* src=http://www.mamicode.com/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;
}


本文出自 “flyclc” 博客,请务必保留此出处http://flyclc.blog.51cto.com/1385758/1540050