[英]How to replace my 'for' loop to find min/max by STL mimax algorithm
我必須從a中找到最小值/最大值(min x,min y,max x,max y)
vector<cv::Point>
這是我的代碼:
vector<cv::Point> contour;
...
Min = Point(640, 480) ;
Max = Point(0,0) ;
for (int j=0; j<(int)contour.size(); j++)
{
if (contour[j].x < Min.x) Min.x = contour[j].x ;
if (contour[j].y < Min.y) Min.y = contour[j].y ;
if (contour[j].x > Max.x) Max.x = contour[j].x ;
if (contour[j].y > Max.y) Max.y = contour[j].y ;
}
這很好用。 我使用mimmax STL開發了一個版本:
auto XminXmax = minmax_element(contour.begin(), contour.end(), [](Point p1,Point p2) {return p1.x < p2.x; });
auto YminYmax = minmax_element(contour.begin(), contour.end(), [](Point p1,Point p2) {return p1.y < p2.y; });
Point Min = Point((*XminXmax.first).x, (*YminYmax.first).y );
Point Max = Point((*XminXmax.second).x, (*YminYmax.second).y );
這也很好,並給出相同的結果。 但是,由於算法minmax被調用兩次,執行時間是兩次。 是否可以通過一次調用minmax算法來優化它?
minmax_element
在Point
對象上運行比較並返回Point
對象。
x
和y
值是獨立的, min(x)
和min(y)
可能屬於不同的對象。
我會用於這種特殊情況的for range
。
Min = Point(640, 480) ;
Max = Point(0,0) ;
for (auto &p : contour)
{
Min.x = std::min(p.x, Min.x)
Min.y = std::min(p.y, Min.y)
Max.x = std::max(p.x, Max.x)
Max.y = std::max(p.y, Max.y)
}
不可以通過單次調用minmax_element
來優化它,因為minmax_element
不是此問題的最佳解決方案。
如果你堅持使用某些STL算法,請使用accumulate
:
std::accumulate(begin(contour), end(contour), Bound{}, [](Bound acc, Point p)
{
return Bound{minpos(acc.bottomleft, p), maxpos(acc.topright, p)};
});
但這需要一些准備工作:
#include <numeric>
struct Point
{
int x;
int y;
Point(int x, int y)
: x(x), y(y) {}
};
Point minpos(Point a, Point b)
{
return {std::min(a.x, b.x), std::min(a.y, b.y)};
}
Point maxpos(Point a, Point b)
{
return {std::max(a.x, b.x), std::max(a.y, b.y)};
}
struct Bound
{
Point bottomleft;
Point topright;
Bound(Point bl = {640, 480}, Point tr = {0, 0})
: bottomleft(bl), topright(tr) {}
};
將accumulate
方法與循環方法的范圍進行比較,我們可以考慮兩個方面:
accumulate
方法略微更好地表達了從幾個點收集單個邊界框的意圖。 但它導致代碼略長。 accumulate
。 從C ++ 17開始,我們將使parallelizm TS標准化。 accumulate
並行對應物將是reduce
算法,因此accumulate/reduce
方法將允許更多的靈活性。 結論:范圍和accumulate/reduce
都有一些(dis)優勢。 但是可能一個完全不同的方法是最好的方法:如果OP中的cv::Point
意味着你使用openCV庫,那么同一個庫就有了boundingRect函數,它正是你想要實現的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.