Search code examples
c++vectorrectangles

Most efficient way to get bounding rectangle of vector of rectangles


I have an std::vector of cv::Rects (from the opencv framework) called rects, but I suppose the same logic would be applied to any rectangle object, so I'm not going to tag opencv in this question.

I am trying to find the smallest rectangle that encompasses all the rectangles in the vector, this is what I have so far:

int t = min_element(rects.begin(), rects.end(), [](cv::Rect a, cv::Rect b){ a.tl().y < b.tl().y;})->tl().y;
int l = min_element(rects.begin(), rects.end(), [](cv::Rect a, cv::Rect b){ a.tl().x < b.tl().x;})->tl().x;
int b = max_element(rects.begin(), rects.end(), [](cv::Rect a, cv::Rect b){ a.br().y < b.br().y;})->br().y;
int r = max_element(rects.begin(), rects.end(), [](cv::Rect a, cv::Rect b){ a.br().x < b.br().x;})->br().x;
cv::Rect smallest_encompassing_rect = cv::Rect(cv::Point(t, l),cv::Point(b, r)))

If it's not clear, the .tl() function gets the top left point of the rectangle, and .br() gets the bottom right.

I know this will work, but I am wondering if there is a more efficient way to solve the problem. I am working with image processing, so my code is time sensitive.

Any help would be appreciated, Thanks


Solution

  • With one loop instead of 4, you may do:

    cv::Rect result = rects[0];
    
    for (int i = 1; i != rects.end(); ++i) {
        result.tl().x = std::min(result.tl().x, rects[i].tl().x);
        result.tl().y = std::min(result.tl().y, rects[i].tl().y);
        result.br().x = std::max(result.br().x, rects[i].br().x);
        result.br().y = std::max(result.br().y, rects[i].br().y);
    }