IplImage* contours_rect;
IplImage* contours;
CvMemStorage* countours_storage=NULL;
if(contours_rect==NULL)
{
contours_rect=cvCreateImage(cvSize(video_width,video_height),IPL_DEPTH_8U,);
}
if(contours==NULL)
{
contours=cvCreateImage(cvSize(video_width,video_height),IPL_DEPTH_8U,);
}else{
memcpy(contours->imageData,fgedge->imageData,fgedge->height*fgedge->width);
}
if(countours_storage==NULL)
{
countours_storage=cvCreateMemStorage();
}else{
cvClearMemStorage(countours_storage);
}
CvSeq* firstContour=NULL;
int contours_num=cvFindContours(contours,countours_storage,&firstContour); //查找所有轮廓
cvZero(contours); //图像置为全黑
CvSeq* contourlonger=NULL; //虽然赋值为NULL 但是实际上不是的
CvSeq* temp=NULL;
int n_contours=;
for(;firstContour->h_next!=NULL;firstContour=firstContour->h_next)
{
double contours_length=cvContourPerimeter(firstContour); //获取每个轮廓的长度信息
double contours_area=cvContourArea(firstContour); //获取每个轮廓的面积值
//cout<<contours_length<<endl;
if(contours_length>&&contours_length<&&contours_area>/*&&contours_length/contours_area<4*/) //根据长度面积信息挑选符合条件的序列重组
{
if(n_contours==)
{
temp=cvCloneSeq(firstContour); //直接等于会使原来的序列被破坏
contourlonger=temp;
}else{
temp->h_next=cvCloneSeq(firstContour);
temp=temp->h_next;
}
n_contours++;
} } if(contourlonger)
{
cvDrawContours(contours,contourlonger,cvScalarAll(),cvScalarAll(),);//第5个参数-1表示采用填充的方式
}
cvShowImage("Contours",contours); //获取边界框
memcpy(contours_rect->imageData,contours->imageData,fgedge->height*fgedge->width);
if(contourlonger!=NULL)
{
for(;contourlonger->h_next!=NULL;contourlonger=contourlonger->h_next)
{
//得到不一定平行于图片的最小面积矩形框
CvBox2D contours_box=cvMinAreaRect2(contourlonger);
CvPoint2D32f point4[];
cvBoxPoints(contours_box,point4); //得到contours_box四个角的坐标
CvPoint pt[];
for(int i=;i<;i++)
pt[i]=cvPoint((int)point4[i].x,point4[i].y);
CvPoint* ppt=pt;
int count=;
cvPolyLine(contours_rect,&ppt,&count,,,cvScalarAll(),);
//下面得到的是平行于图片的矩形框
//CvRect contours_boundary=cvBoundingRect(contourlonger); //这样得到的矩形坐标和长宽都是0 不知道为什么
//cvRectangle(contourlonger,cvPoint(contours_boundary.x,contours_boundary.y),cvPoint(contours_boundary.x+contours_boundary.width,contours_boundary.y+contours_boundary.height),cvScalarAll(255));
}
}
cvShowImage("Contours_boundary",contours_rect);
我已经通过其他方法提取了轮廓 用OPENCV的函数查找更完整的轮廓 并且根据轮廓的长度和面积信息将轮廓序列做一个选择性处理 最后画出外接矩形框。
在对轮廓做选择性处理的时候 发现虽然新建CvSeq* 赋值为了NULL 但实际上不是的 它本身有一个地址值 因此 不能通过(指针!=NULL )来初始化第一个序列 因此引入了n_contours。 CvCloneSeq函数也仅仅是复制当前的序列,它的前驱和后继是没有被复制过来的,需要每一次都使用复制函数。
first 3 5 2 9 1 7 8 2 设序列长度 //若只要大于5的
---》---》---》--》-》--》--》---》
temp:clone(5)-->clone(9)--->clone(7)-->clone(8)-->NULL
↑
contours :指向新建的头指针