我使用一個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);
}