#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"highgui.lib")
#pragma comment(lib,"ml.lib")
#pragma comment(lib,"cvcam.lib")
#pragma comment(lib,"cvaux.lib")
#include <stdio.h>
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace std;
int main()
{
/*
用来创建一个内存存储器,来统一管理各种动态对象的内存。
函数返回一个新创建的内存存储器指针。
参数block_size对应内存器中每个内存块的大小,为0时内存块默认大小为64k。
*/
CvMemStorage *storage=cvCreateMemStorage(0);
IplImage* img=cvLoadImage("img//contour.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;//CvSeq本身就是一个可增长的序列,不是固定的序列
cvZero(contoursImage);
//二值化
/*
对灰度图像进行阈值操作得到二值图像
threshold_type:阈值类型 threshold_type=CV_THRESH_BINARY:
如果 src(x,y)>threshold ,dst(x,y) = max_value(255); 否则,dst(x,y)=0;
*/
cvThreshold(img,img,100,255,CV_THRESH_BINARY);
//img 备份
cvCvtColor(img,imgcolor,CV_GRAY2RGB);
/*
提取图像img的轮廓信息 存储在storage
contours指向第一个轮廓
*/
int total=cvFindContours(
img,
storage,
&contours,sizeof(CvContour),
CV_RETR_CCOMP,//轮廓的排列方式 ccomp 从里到外,从右到左
CV_CHAIN_APPROX_NONE,//以坐标的形式显示 点
cvPoint(0,0)
);
contoursTemp=contours;
int count=0;
//遍历轮廓
for (;contoursTemp!=0;contoursTemp=contoursTemp->h_next)//h_next 遍历外轮廓
{
//遍历 第一个 外轮廓 上的所有坐标点
for (int i=0;i<contoursTemp->total;i++)
{
CvPoint *pt=(CvPoint*)cvGetSeqElem(contoursTemp,i);
cvSetReal2D(contoursImage,pt->y,pt->x,255.0);//画点 255 白点
cvSet2D(imgcolor,pt->y,pt->x,cvScalar(0,0,255,0));//0,255,0 彩色点
}
count++;
//提取 内轮廓 的 左右坐标点
CvSeq *intercon=contoursTemp->v_next;//垂直访问
for (;intercon!=0;intercon=intercon->h_next)
{
for (int i=0;i<intercon->total;i++)
{
CvPoint* pt=(CvPoint*)cvGetSeqElem(intercon,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);
return 0;
}