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
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);
}