【问题标题】:How to find a set of points in a spherical space with specific radius around one point in a unorganized point cloud如何在无组织点云中的一个点周围找到具有特定半径的球形空间中的一组点
【发布时间】:2017-03-01 20:52:14
【问题描述】:

我有一个由近 20000 个点组成的点云。我们考虑点云中的一个点。我想确定在预定义半径内的每个点周围的球形空间内的点集。在下图中有一个非常清楚的说明我的意思, [一个周围有球形空间的点 [Gross et al. (2007)][1]]1

我已经编写了使用两个循环来查找每组点的最简单方法。这是函数,

void FindPointsInsideSphere(std::vector<Point>& points, double radius)
{
    for (int i = 0; i < points.size(); i++)
    {
        for (int j = 0; j < points.size(); j++)
        {
            if (i != j && Distance(points[i], points[j]) < radius)
            {
                points[i].Sphere.push_back(points[j]);
            }
        }
    }
}

这里的问题是所提出的算法非常耗时。我想知道是否有任何建议可以加快这个过程。

【问题讨论】:

  • 您可以使用Distance(points[i], points[j]) &lt; radius iff Distance(points[j], points[i]) &lt; radius 将使用的时间减半。然后你的第二个循环变量将从i+1开始。
  • @Albjenow 我必须精确更改代码的哪一部分?
  • @Albjenow 我改变了这样的代码, for (int i = 0; i
  • 也许你误会了我。不需要再检查另一个方向的距离。如果点 X 在 Y 的范围内,那么(并且只有这样)Y 在 X 的范围内,对吧?所以你可以在最里面的if子句中做2个push_backs
  • 将空间划分为 size=radius/2 的立方体并将粒子放入立方体,然后将每个立方体的粒子仅与相邻的立方体检查,因为其他立方体不在范围内。

标签: c++ multithreading optimization point-clouds


【解决方案1】:

stackexchange上有一个类似的问题:https://cstheory.stackexchange.com/questions/17971/search-for-all-nearest-neighbors-within-a-certain-radius-of-a-point-in-3d

在与@AMA 讨论和谷歌搜索后,我意识到 KDTree 和统一网格都可以提高蛮力的时间复杂度。


网格

半径搜索复杂度:

O(log(n) + k)

其中 k 是球体内的近似邻居数。

我从未亲自尝试过这种方法,但正如@AMA 指出的那样,它比 kdtree 查询具有更好的时间复杂度。

在谷歌快速搜索后,我找到了this implementation on github


KD树

半径搜索复杂度:

O(sqrt(n) + k)

其中 k 是球体内的近似邻居数。

KDTree 搜索FLANN 的最佳开源实现,支持多种语言。

看看the manual部分:3.1.4 flann::Index::radiusSearch

如果您想自己实现此功能,可以查看source code in github 以获得灵感。

【讨论】:

    【解决方案2】:

    我想知道是否有任何建议可以加速 过程。

    一种众所周知的方法是使用长列表中的任何space-partitioning data structures。 最容易实现(可以说)是simple 3D grid

    【讨论】:

    • 我认为指出他使用空间分区数据结构是一个好点。然而,即使 3D 网格是实现起来最简单的结构,它也不是围绕每个点执行 raius 搜索的正确结构,这正是他要问的。
    • @DaviddelaIglesia 为什么不呢?第一个找到与球体相交的单元格,然后针对这些单元格中的所有点进行测试。
    • 在我看来,这比使用专门设计用于执行此类搜索操作的数据结构(如 KDTree 或 BallTree)效率低得多。我并不是说你不能使用 3D 网格来达到同样的效果,我只是说半径搜索有更好的数据结构。
    • @DaviddelaIglesia 对于任何一棵树,还需要找到与球体相交的叶子。原理是完全一样的。
    • @DaviddelaIglesia 在不了解点云结构的情况下,我们不能对这种效率说太多。例如,k-d-trees 可能会误入歧途。然而,AMA 声明 3D 网格很容易实现,这显然是一个正确的说法。拥有一个有效且易于实施的解决方案可能比在某些情况下可以减少纳秒的解决方案更受欢迎。无论如何,使用 3D 网格显然比问题中的幼稚解决方案要好得多,因此答案是有效的。
    猜你喜欢
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    相关资源
    最近更新 更多