2017-05-10 9 views
1

私はなど、intfloatdoubleのようなデータ型の最高値を見つける方法を知っているが、ここで私はPoint3fを使用することによりxy、& z座標で働いています。だから誰でもx,yまたはzの最高値がstd::vectorからstd::vectorになるよう助けることができますか?最高値<ベクトルは<Point3f>>

std::vector< std::vector<Point3f> > cluster_points; 

簡略化のために、中でもx軸の最高値を探したいとします。

+0

ベクトルをMatに変換し、[this](http://docs.opencv.org/2.4/modules/core/)を使用してください。 doc/operations_on_arrays.html?highlight = minmaxloc#minmaxloc)を使用して、minとmaxを検索します。 –

+0

@RickMありがとうございました。私は前にこれについて考えましたが、他の参考文献でPoint3fを使用しているので、私はMatに変換したくありません。私がそうするなら、私は必要な時にいつでもそれを逆行させなければならない。そしてそれはそれを少し遅くするでしょう。 –

+1

[this](http://www.swarthmore.edu/NatSci/mzucker1/opencv-2.4.10-docs/doc/user_guide/ug_mat.html#memory-management)のようにすると、遅くなることはありません参照カウント)。これは単なるデータへのポインタです。 –

答えて

2

私は、ラムダ関数のカップルとstd::for_each()のカップルについて

何OpenCVのを知らないので、シンプルなソリューションすることができますが...?あなたはauto引数を持つC++ 14ので、ラムダ関数を使用できる場合

std::vector<std::vector<Point3f>> vvp { /* some data */ }; 

auto mx = vvp[0][0].x; 
auto my = vvp[0][0].y; 
auto mz = vvp[0][0].z; 

std::for_each(vvp.cbegin(), vvp.cend(), 
    [&](std::vector<Point3f> const & vp) 
     { std::for_each(vp.cbegin(), vp.cend(), 
      [&](Point3f const & p) 
       { mx = std::max(mx, p.x); 
       my = std::max(my, p.y); 
       mz = std::max(mz, p.z); }); }); 

、ダブルstd::for_each()一部は、単にので、他のポイント-3DでPoinf3fと使用可能にexplicitingずに

std::for_each(vvp.cbegin(), vvp.cend(), [&](auto const & vp) 
{ std::for_each(vp.cbegin(), vp.cend(), [&](auto const & p) 
    { mx = std::max(mx, p.x); 
     my = std::max(my, p.y); 
     mz = std::max(mz, p.z); }); }); 

のように記述することができますタイプのようなタイプ。

+0

ああ、C++ 11あなたの美しさ、**涙**。 @RickM。 –

+1

- そしてC++ 14はさらに改善されました(回答が修正されました) – max66

+0

ちょうど1つの単語** ** EPIC ** –

1

これはC++ 14です。

これは、クライアントコードの明示的なループがないソリューションです。

template<class F> 
auto foreacher(F&& f) { 
    return [f=std::forward<F>(f)](auto&& r)mutable{ 
    for (auto&& e:decltype(r)(r)) 
     f(decltype(e)(e)); 
    }; 
} 

std::vector<std::vector<Point3f>> data = {whatever}; 
auto mx = data[0][0].x; 
auto task = foreacher(foreacher([&](Point3f const& e){ 
    mx = (std::max)(mx, e.x); 
})); 

task(data); 

我々は、我々はそれが引数の内容を反復処理する二つの修飾子でそれをラップし、要素に問題を解決し、当社のラムダを取ります。

Live example

1

あなたはかなりよく、このタスクにマップstd::accumulate使用することができます。

const auto min = std::numeric_limits<float>::min(); 
Point3f init(min, min, min); 
std::vector< std::vector<Point3f> > cluster_points; 
auto max = std::accumulate(cluster_points.begin(), cluster_points.end(), init, [](const Point3f &p, const std::vector<Point3f> &v) { 
    return std::accumulate(v.begin(), v.end(), p, [](const Point3f &p1, const Point3f &p2) { 
     return Point3f(std::max(p1.x, p2.x), std::max(p1.y, p2.y), std::max(p1.z, p2.z)); 
    } 
})); 

をそして、これはC++ 14それはラムダにauto引数を使用することによって単純化することができて、唯一のC++ 11を必要と

1

いくつかの素晴らしい答えがありますが、私はちょうど純粋なopencvであるものを書いています、私はあなたに最も速い方法で調査を残します。

std::vector<Point3f> points; 
// .. fill the array 
Mat pointsMat = Mat(points).reshape(1); 

Quoting - 結果として、我々は代わりに1列と32FC3行列の3列の32FC1行列を取得します。 pointsMatはポイントからのデータを使用し、破棄されるとメモリの割り当てを解除しません。しかし、この特定の例では、開発者はポイントの有効期間がpointsMatよりも長くなるようにしなければなりません。

次に、今、あなたはすべてのあなたのPoint3fでマットを持っていることは、次のように使用できます。

minMaxLoc(pointsMat, &minVal, &maxVal); 

あなたがstd::vector<std::vector<Point3f>> All_pointsのためにこれを行いたい場合は、列の数と単一チャネルMatを作ることができます= All_points.size() * 3と同じ機能を使用してくださいminMaxLoc。これにより、すべてのポイントに沿ってminValmaxValが得られます。

あなたはまたのようなminValmaxValの場所を取得することができます

minMaxLoc(pointsMat, &minVal, &maxVal, &minLoc, &maxLoc); 

マット作り直さにはもちろんです。

希望すると助かります!

P.S. C++ 11とC++ 14の回答へのご意見

関連する問題