#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char** argv )
{
int i, j;
CvMemStorage* storage = cvCreateMemStorage(0);
IplImage* img = cvLoadImage("1.jpg",CV_LOAD_IMAGE_GRAYSCALE);
IplImage* imgColor = cvCreateImage(cvGetSize(img),8,3);
IplImage* contoursImage = cvCreateImage(cvSize(img->width,img->height),8,1);
CvSeq* contours = 0 , *contoursTemp=0;
cvZero(contoursImage);
//对图像进行二值化
cvThreshold(img,img,100,255,CV_THRESH_BINARY);
//img的备份
cvCvtColor(img,imgColor,CV_GRAY2BGR);
// 提取图像img的轮廓信息 contours指向第一个轮廓
int total = cvFindContours( img, storage, &contours, sizeof(CvContour),
CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0) );
contoursTemp = contours ;
int count=0;
//对轮廓进行循环
for(;contoursTemp!=0 ; contoursTemp=contoursTemp->h_next)
{
//提取外轮廓 上的所以坐标点
for( i=0; i<contoursTemp->total; i++)
{
CvPoint * pt = (CvPoint*)cvGetSeqElem(contoursTemp, i); // 读出第i个点。
cvSetReal2D(contoursImage , pt->y , pt->x , 255.0);
cvSet2D(imgColor,pt->y,pt->x,cvScalar(0,0,255,0));
}
count++;
//提取内轮廓上的所以坐标点
CvSeq* InterCon = contoursTemp->v_next;
for(;InterCon!=0;InterCon=InterCon->h_next)
{
for(i=0;i<InterCon->total;i++)
{
CvPoint * pt = (CvPoint*)cvGetSeqElem(InterCon, i); // 读出第i个点。
cvSetReal2D(contoursImage , pt->y , pt->x , 255.0);
cvSet2D(imgColor,pt->y,pt->x,cvScalar(0,255,0,0));
}
}
}
cvNamedWindow( "image", 1 );
cvShowImage( "image", imgColor );
cvNamedWindow( "contours");
cvShowImage("contours",contoursImage);
cvWaitKey(0);
cvReleaseMemStorage( &storage );
cvReleaseImage( &img );
cvReleaseImage(&contoursImage);
cvReleaseImage(&imgColor);
return 0;
}
注意三点:
1、调用cvFindContours时输入的图像是二值图像。
2、cvFindContours函数会改变输入的图像,如果原图像在后续还有作用时,必须先原图像进行复制。
3、cvFindContours中第二个参数storage在调用时系统会自动的分配轮廓的存储空间,但是在程序结束时需要显示的释放该空间。