【问题标题】:Highest values in vector< vector<Point3f> >vector<vector<Point3f>> 中的最大值
【发布时间】:2017-05-10 15:12:11
【问题描述】:

我知道如何为intfloatdouble 等数据类型找到最高值。但在这里我使用的是xyz 坐标通过使用Point3f。那么任何人都可以帮助从std::vectorstd::vector 中找到xyz 的最高值吗?

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

为简单起见,假设我只想找到 x 轴的最高值。

【问题讨论】:

  • 您可以将vector&lt;Point3f&gt; 转换为Mat 并使用this 来查找最小值和最大值。
  • @RickM 感谢您的建议。我之前考虑过这一点,但由于我在其他参考文献中使用 Point3f,我不想将其转换为 Mat。如果这样做,我必须在需要时将其反转。这会让它有点慢。
  • 如果你像this 那样做它不会让它变慢。它只是一个指向数据的指针。
  • @RickM 好的,我会看一下文档,然后尝试一下。感谢您的建议
  • vector&lt;vector&lt;double&gt; &gt; 做任何事情,但提供一个自定义比较器,它只比较 x 坐标。

标签: c++ opencv c++11 vector


【解决方案1】:

我不知道opencv,所以可以更简单的解决方案但是......

有几个 lambda 函数的 std::for_each() 怎么样?

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

如果你可以使用 C++14,所以带有 auto 参数的 lambda 函数,双 std::for_each() 部分可以简单地写成

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

因此无需显式 Poinf3f 并可供其他类似 point-3d 的类型使用。

【讨论】:

  • 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!
  • @RickM。 - C++14 更好(答案已修改)
  • 只有一个字 - EPIC
【解决方案2】:

您可以使用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++11,使用 C++14 可以通过在 lambdas 中使用 auto 参数来简化

【讨论】:

    【解决方案3】:

    虽然有几个很好的答案,但我只是写一个纯opencv,我把最快的方法留给你调查。

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

    Quoting - 结果,我们得到一个 32FC1 的 3 列矩阵,而不是 32FC3 的 1 列矩阵。 pointsMat 使用来自点的数据,并且在销毁时不会释放内存。然而,在这种特殊情况下,开发人员必须确保点的生命周期比 pointsMat 的生命周期长。

    那么,既然你有一个包含所有 Point3f 的 Mat,你可以使用以下内容:

    minMaxLoc(pointsMat, &minVal, &maxVal);
    

    如果您希望为std::vector&lt;std::vector&lt;Point3f&gt;&gt; All_points 执行此操作,您可以使用列数 = All_points.size() * 3 的单个通道 Mat 并使用相同的函数 minMaxLoc。这将为您提供所有点集的minValmaxVal

    还可以获取minValmaxVal的位置,比如:

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

    这当然是在重塑的垫子中

    希望对你有帮助!

    附注感谢 C++11 和 C++14 的答案

    【讨论】:

      【解决方案4】:

      这是 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);
      

      我们采用解决元素问题的 lambda,然后将其包装在两个修饰符中,使其遍历参数的内容。

      Live example.

      【讨论】:

        猜你喜欢
        • 2012-03-08
        • 2017-12-01
        • 1970-01-01
        • 2014-02-14
        • 1970-01-01
        • 2017-10-26
        • 2019-02-05
        • 2022-01-24
        • 2018-11-27
        相关资源
        最近更新 更多