获取左下角和左上角

get bottomLeft & TopLeft corners

本文关键字:左上角 左下角 获取      更新时间:2023-10-16

我有一个点列表(vector<cv::Point>),如下所示:

[ 5, 10;
15, 25;
40, 30;
10, 15]

我想提取 4 个角,例如...

  • 左上角cv::Point topLeft = cv::Point(5,10) ;
  • 右上角cv::Point topRight = cv::Point(10,15) ;
  • 左下角cv::Point bottomLeft = cv::Point(15,25) ;
  • 右下角cv::Point bottomRight = cv::Point(40,30) ;

如何使用 objc++ 从列表中获取 4 个角?


注意:这是我到目前为止尝试过的,但显然它似乎不起作用。

cv::Rect rect = cv::boundingRect(points);
cv::Point topLeft = rect.tl();
cv::Point bottomRight = rect.br();
cv::Point topRight = ??
cv::Point bottomLeft = ??

我知道在openCV和点向量上已经问了很多问题,但我希望有人能给我一个简短的答案,因为我现在很茫然。

编辑topLeft == minX & minYtopRight == maxX & minYbottomLeft == minX & maxYbottomRight == maxX & maxY。这就是角的定义方式。

注意:该区域将是一个矩形,不可能像钻石中那样笔直地显示两个值(如@Jive提到的)。

如果要按顺时针顺序对 4 个点进行排序,请考虑以下方法。 这是从这个网站引用的

//   TL(1)-------TR(2)
//    |           |
//    |           |
//   BL(4)-------BR(3)
//
template<typename T>
int OrderPoints(vector<cv::Point_<T>>& ip_op_corners_orig)
{
if (ip_op_corners_orig.size() < 4)
return -1;
//Making a copy of the Original corner points
vector<cv::Point_<T>> corners = ip_op_corners_orig;
ip_op_corners_orig.clear();
ip_op_corners_orig.resize(4);
//Sorting based on the X Co-ordinates of points
vector<int> sIdx = { 0, 1, 2, 3 };
vector<cv::Point_<T>> leftMost, rightMost;
std::sort(sIdx.begin(), sIdx.end(), [&corners](int i1, int i2){return corners[i1].x < corners[i2].x; });
//Getting the Left most and Right most points and getting the top left and bottom left points
leftMost = { corners[sIdx[0]], corners[sIdx[1]] };
//Getting the Top Left and Bottom Left point
ip_op_corners_orig[0] = leftMost[0].y > leftMost[1].y ? leftMost[1] : leftMost[0];
ip_op_corners_orig[3] = leftMost[0].y < leftMost[1].y ? leftMost[1] : leftMost[0];

//Getting the Bottom right anfd top right point
rightMost = { corners[sIdx[2]], corners[sIdx[3]] };
//Getting the Top right and Bottom right point
ip_op_corners_orig[1] = rightMost[0].y > rightMost[1].y ? rightMost[1] : rightMost[0];
ip_op_corners_orig[2] = rightMost[0].y < rightMost[1].y ? rightMost[1] : rightMost[0];

return 0;
}
//template explicit definitions
template int OrderPoints(vector<cv::Point>&);
template int OrderPoints(vector<cv::Point2d>&);
template int OrderPoints(vector<cv::Point2f>&);

编辑1:由于点已经在矩形上,那么就像@beaker提到的, topLeft = minX & minY, bottomLeft = minX & maxY, topRight = maxX & minY, bottomRight = maxX & maxY.

或者你可以这样定义它们

cv::Rect rect = cv::boundingRect(points);
cv::Point topLeft = rect.tl();
cv::Point bottomRight = rect.br();
cv::Point bottomLeft = topLeft + cv::Point(0, rect.height);
cv::Point topRight = topLeft + cv::Point(rect.width, 0);

编辑 2:更新了代码以适用于所有点类型