一张图片经过二值化处理后,用cvfindcontours找出所有的轮廓,根据先验条件来筛选这些轮廓,
将合格的压入CvSeq, 然后将合格的取出,再得到这些轮廓上的点,做下一步分析,为了方便,我把下一步分析的工作 设置 为输出点,并将点一一画出。
int main(int argc, char* argv[]) { IplImage *src=cvLoadImage("d:/1.bmp",0); IplImage *dst=cvCreateImage(cvSize(src->width,src->height),8,3); CvMemStorage *stor=cvCreateMemStorage(0); CvSeq *seq_cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor); //储存合格的轮廓 CvSeq *cont=NULL; int i=0,j=0; int num=cvFindContours(src,stor,&cont,sizeof(CvContour),CV_RETR_LIST); //记录总轮廓数 int *length=new int[num]; //每个轮廓都有不同的点数,所以length[i]的值就是第i个轮廓上的点数。这里不太好理解,只能想出这样的办法了。 for (i=0;i<num;i++)length[i]=0; // for (i=0;cont;cont=cont->h_next) //开始遍历全部的轮廓 { /*为了简单,假设全部都符合条件*/ cvSeqPush(seq_cont,cont); //将轮廓压入 length[i++]=cont->total; //记录每个轮廓上的点个数,为下面的分配数组做准备。 } for (i=0;i<num;i++) { CvPoint *point=new CvPoint[length[i]]; //分配不同长度的数组,为了存储每个轮廓的点坐标。 CvSeq* c=(CvSeq*)cvGetSeqElem(seq_cont,i); //将每个轮廓取出 CvSeqReader reader; CvPoint pt=cvPoint(0,0); cvStartReadSeq(c,&reader);/*程序在此出现错误,令我感到奇怪的是,当我直接执行(ctrl+F5),没有异常提示,当然也没结果。 但是当我单步调试的时候,却出现了错误。进入cvStartReadSeq()会发现,异常出现在这一步 reader->ptr = first_block->data; cxdatastructs.cpp 第1114行, 这一行的作用我觉得是把轮廓的数据块的地址赋给reader。觉得问题出在cvseqpush () 或者是cvSeqgetElem()中。 能是在获得元素的时候执行的是浅复制。但是自己看代码的时候在却没有找到证据。 */ for (j=0;j<c->total;j++) { CV_READ_SEQ_ELEM(pt,reader); point[j]=pt; cout<<pt.x<<" "<<pt.y<<endl; //运行的时候这一步没有执行, } for (j=0;j<c->total;j++) //画出每个轮廓上的点 { int k=(j+1)%c->total; cvLine(dst,point[j],point[k],cvScalar(0,0,255),1,4,0); } delete point; } cvNamedWindow("dst",1); cvShowImage("dst",dst); cvWaitKey(0); cvReleaseMemStorage(&stor); cvDestroyWindow("dst"); cvReleaseImage(&dst); return 0; }
问题出在cvSeqPush(seq_cont,cont);
自己压进去的是一个轮廓的指针(占4个字节),但是在这个序列里每个元素却是占56个字节的CvSeq结构体变量。
所以在压入的时候必须是一个完整的结构体变量的地址(因为CvSeqPush()的第二个参数是一个指针变量,而且在这个函数内部会进行深度复制,就是把这个结构体的内容完全copy并在加入到栈底.)
只需要在压栈前 加入一行,就可搞定,当然压入栈的不再是cont,而是&seq.
CvSeq seq=*cont;
cvSeqPush(seq_cont,&seq);
另外还需要注意的是
CvSeq *seq_cont=cvCreateSeq(CV_SEQ_ELTYPE_GENERIC,sizeof(CvSeq),sizeof(CvSeq),stor);
就是第一个参数设置为CV_SEQ_ELTYPE_GENRIC。
详情可查看:http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=8652