得到底部左右TopLeft角落

时间:2018-03-19 14:40:50

标签: c++ opencv objective-c++

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

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

我想像......一样提取四个角落。

  • 左上角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&amp; amp;点向量,但我希望有人能够给我一个简短的回答我的问题,因为我现在很茫然。

修改topLeft == minX & minYtopRight == maxX & minYbottomLeft == minX & maxYbottomRight == maxX & maxY。这就是角落的定义方式。

注意:该区域将是一个矩形,并且两个值不可能像diamond一样直线上升(如提到的@Jive)。

1 个答案:

答案 0 :(得分:0)

如果您想按顺时针顺序订购4个点,请考虑以下方法。 这是从this site

引用的
//   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&amp; minY,bottomLeft = minX&amp; maxY,topRight = maxX&amp; minY,bottomRight = maxX&amp; 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: 更新了代码以使用所有点类型