2014-01-26 51 views
-1

我使用一个beaglebone OpenCV的跟踪水平和垂直的矩形转乘。OpenCV的矩形高度和宽度保持

为了确定矩形是否是水平或垂直的我使用从minAreaRect提取的高宽比。

但是我注意到有时候,如果我让程序在同一个图像上的一个循环上运行,相同的固定矩形交换的宽度和高度的值,它报告之前的宽度值作为它的当前高度,类似于之前的身高值。

这使得该代码不能令人满意,因为它不再能成功地使用高/宽比。

有人能请解释一下是什么引发了矩形的高度/宽度交换自身?

下面是一个示例输出,注意迭代之间的高度和宽度

Hierarchy: 1 
Contour Size: 53 
Contour: 0 
    X: 350 
    Y: 196 
    Height: 236 
    Width: 26 
    Ratio (W/H): 0.110169 
    Ratio (H/W): 9.07692 
    Vert: 0 
    Horiz: 0 
Image proc. time: 1.9ms 
Contours: 1 
Hierarchy: 1 
Contour Size: 83 
Contour: 0 
    X: 244 
    Y: 300 
    Height: 26 
    Width: 236 
    Ratio (W/H): 9.07692 
    Ratio (H/W): 0.110169 
    Vert: 0 
    Horiz: 0 
Image proc. time: 2.2ms 
Contours: 1 
Hierarchy: 1 
Contour Size: 59 
Contour: 0 
    X: 350 
    Y: 196 
    Height: 236 
    Width: 26 
    Ratio (W/H): 0.110169 
    Ratio (H/W): 9.07692 
    Vert: 0 
    Horiz: 0 
Image proc. time: 2.4ms 

这里是我用来生成此输出

vector<Vec4i> hierarchy; 
Target targets; 


/// Show in a window 
namedWindow("Contours", WINDOW_AUTOSIZE); 


//Find rectangles 
findContours(thresholded, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 

cout<<"Contours: "<<contours.size()<<endl; 
cout<<"Hierarchy: "<<hierarchy.size()<<endl; 


//run through all contours and remove small contours 
unsigned int contourMin = 25; 
for (vector<vector<Point> >::iterator it = contours.begin(); it!=contours.end();) 
{ 
    cout<<"Contour Size: "<<it->size()<<endl; 
    if (it->size()<contourMin) 
     it=contours.erase(it); 
    else 
     ++it; 
} 

//Vector for Min Area Boxes 
vector<RotatedRect> minRect(contours.size()); 

/// Draw contours 
Mat drawing = Mat::zeros(original.size(), CV_8UC3); 

NullTargets(targets); 

//run through large contours to see if they are our targerts 
if(!contours.empty() && !hierarchy.empty()) 
{ 



    for(unsigned int i = 0; i < contours.size(); i++) 
    { 
     //capture corners of copntour 
     minRect[i] = minAreaRect(Mat(contours[i])); 

     //if(hierarchy[i][100] != -1) 
     drawContours(drawing, contours, i, RED, 2, 8, hierarchy, 0, Point()); 



     //draw a minimum box around the target in green 
     Point2f rect_points[4]; 
     minRect[i].points(rect_points); 
     for (int j = 0; j < 4; j++) 
     line(drawing,rect_points[j],rect_points[(j+1)%4],GREEN,1,8); 

     //define minAreaBox 
     Rect box; 
     box.x = minRect[i].center.x - (minRect[i].size.width/2); 
     box.y = minRect[i].center.y - (minRect[i].size.height/2); 
     box.width = minRect[i].size.width; 
     box.height = minRect[i].size.height; 


     double WHRatio = box.width/((double)box.height); 
     double HWRatio = ((double)box.height)/box.width; 

     //check if contour is vert, we use HWRatio because it is greater that 0 for vert target 
     if ((HWRatio > MinVRatio) && (HWRatio < MaxVRatio)) 
     { 
      targets.VertGoal = true; 
      targets.VerticalTarget = box; 
      targets.VerticalAngle = minRect[i].angle; 
      targets.VerticalCenter = Point(box.x + box.width/2, box.y + box.height/2); 
      targets.Vertical_H_W_Ratio = HWRatio; 
      targets.Vertical_W_H_Ratio = WHRatio; 

     } 
     //check if contour is horiz, we use WHRatio because it is greater that 0 for vert target 
     else if ((WHRatio > MinHRatio) && (WHRatio < MaxHRatio)) 
     { 
      targets.HorizGoal = true; 
      targets.HorizontalTarget = box; 
      targets.HorizontalAngle = minRect[i].angle; 
      targets.HorizontalCenter = Point(box.x + box.width/2, box.y + box.height/2); 
      targets.Horizontal_H_W_Ratio = HWRatio; 
      targets.Horizontal_W_H_Ratio = WHRatio; 
     } 

     if(targets.HorizGoal && targets.VertGoal) 
      targets.HotGoal = true; 

     cout<<"Contour: "<<i<<endl; 
     cout<<"\tX: "<<box.x<<endl; 
     cout<<"\tY: "<<box.y<<endl; 
     cout<<"\tHeight: "<<box.height<<endl; 
     cout<<"\tWidth: "<<box.width<<endl; 
     cout<<"\tangle: "<<minRect[i].angle<<endl; 
     cout<<"\tRatio (W/H): "<<WHRatio<<endl; 
     cout<<"\tRatio (H/W): "<<HWRatio<<endl; 
     cout<<"\tVert: "<<targets.VertGoal<<endl; 
     cout<<"\tHoriz: "<<targets.HorizGoal<<endl; 
     cout<<"\tHot Goal: "<<targets.HotGoal<<endl; 
     //rectangle(drawing,box,YELLOW); 


     //ID the center in yellow 
     Point center(box.x + box.width/2, box.y + box.height/2); 
     line(drawing, center, center, YELLOW, 3); 
     line(drawing ,Point(320,240),Point(320,240),YELLOW,3); 

    } 

回答

3

当你与RotatedRect您使用的代码应该记住,它没有真正的宽度或高度,因为如果将角度增加90度,它们可以交换。作为使用“宽度”或RotatedRect的“高度”来初始化“盒子”的结果是有问题的,至少可以说。如果你想计算RotatedRect的比率,你应该考虑角度。或者,如果你不想使用角度使用矩形的,而不是RotatedRect从一开始(更换minAreaRect与boundingRect)。

在附注中,您不是通过数字顶点过滤多边形,这通常是非常不可靠的数字。大的多边形可能有很少的顶点,小的可能有很多顶点。自从您计算出它之后,您最好使用轮廓区域(来自contourArea函数)或其边界框的区域。

相关问题