用cvfindcontours后,再经过一系列的筛选,得到了满足条件的轮廓,如何才能得到这些轮廓上的点呢?查了一些资料,居然没查到。请坛子的朋友帮忙。谢谢了。
做了一个简单的图片,就是两个平行四边行,一大一小嵌套,中间用黑色填充,可是没能用点画出来轮廓。
所有的内容,都已经放在 cont 里面了,你为什么还构造一个 seq_cont ?
而且不知道
我想这绝对是可以得到的,因为cvDrawContorus可以将轮廓画出,用的肯定也是点的坐标。
找过了,但是没取出来。我得了三个轮廓,都是方形(有一定的旋转和畸变,用cvboundingbox计算的话误差有点大)。想得到这三个正方形的四个顶点,于是
CvSeq* seq_three_cont
……………………
经过调试此时seq_htree_cont中已经有了三个方形的轮廓
for(int i=0;i<seq_three_cont->total;i++)
{
CvSeq *seq_one_cont=cvGetSeqElem(seq_three_cont,i);
for(int j=0;j<seq_one_cont->total;j++) ///程序执行到此时seq_one_cont->total的值是-1163005939,真是搞不明白。
{
CvPoint *pt=cvGetSeqElem(seq_one_cont,j);
cvCircle(dst,*pt,cvScalar(0,0,255),1,1,0);
}
}
感谢您的热情帮助。知道自己把 总的轮廓数 和轮廓上的点数 搞错了。前者是由cvFindcontours()得到,后者是cont->total得到的。
这是自己重写的,还是没能读取出来。帖出来请大家指正。
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;
int num=cvFindContours(src,stor,&cont,sizeof(CvContour),CV_RETR_LIST); //记录总轮廓数
int *length=new int[num]; //作用是记录每个轮廓上的点数
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); //进入调试模式后这一步出现异常,不理解
for (int 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;
}
做了一个简单的图片,就是两个平行四边行,一大一小嵌套,中间用黑色填充,可是没能用点画出来轮廓。
看不懂你的代码,想干什么事情,比如:
CvSeq *seq_cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);
CvSeq *cont=NULL;
int i=0;
int num=cvFindContours(src,stor,&cont,sizeof(CvContour),CV_RETR_LIST); //记录总轮廓数
int *length=new int[num]; //作用是记录每个轮廓上的点数
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; //记录每个轮廓上的元素个数
}
上面的代码中间:
所有的内容,都已经放在 cont 里面了,你为什么还构造一个 seq_cont ?
而且不知道
for (i=0; cont; cont=cont->h_next) {
cvSeqPush(seq_cont,cont); //将轮廓压入
length[i++]=cont->total; //记录每个轮廓上的元素个数
}
十分感谢您的帮助。其实代码的目的是想找到轮廓上的每一个点,然后再把点一一画出(cvdrawcontours就可以完成)。因为我在其它应用里要用到这些轮廓上的点坐标。将修改正确的代码贴出。您说的很对,轮廓都已经可以通过cont得到,也就没有必要再把这些一一压入保存。
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 *cont=NULL;
int i=0;
for (i=0;cont;cont=cont->h_next)
{
length[i++]=cont->total; //记录每个轮廓上的元素个数
CvPoint *point =new CvPoint[cont->total];
CvSeqReader reader;
CvPoint pt=cvPoint(0,0);
cvStartReadSeq(cont,&reader);
for (int j=0;j<cont->total;j++)
{
CV_READ_SEQ_ELEM(pt,reader);
point[j]=pt;
cout<<pt.x<<" "<<pt.y<<endl;
}
for (j=0;j<cont->total;j++)
{
int k=(j+1)%cont->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;
}