kd-tree 与八叉树用于 3d 半径搜索

问题描述 投票:0回答:4

我试图找出哪种结构更适合对点进行多个半径搜索,kd 树还是八叉树?在这个问题中已经提到过,但没有答案。在我看来,由于八叉树的叶子大小是固定的,因此已经可以计算出我需要访问的分支,而对于 kd 树,您必须迭代访问分支,直到覆盖半径。

search data-structures kdtree octree
4个回答
11
投票

我个人也正是为了这个目的才实现了投票给八叉树。我发现使用八叉树更容易获得更有效的结果。我说更容易,因为我认为有了这些微妙的区别,它实际上更多地与实现者有关,而不是与数据结构有关。但我认为对于大多数人来说,优化八叉树会更容易。

原因之一是因为 K-D 树本质上更深,是一次在一个维度上分裂的二叉树。如果您正在叶子上寻找精确的匹配元素,例如光线/三角形与树上单一、明确的路径的交点,那么这种更深层次的性质会很有帮助。当仔细分割的深层树与搜索质量的理念相匹配时,它会很有用。

如果您要在最大半径内搜索最近的点,而您最终花费大部分时间在树上上下移动,从叶子到父级再到兄弟级,那么拥有一棵深的、仔细分裂的树就没那么有帮助了祖父母、父母兄弟姐妹等等。如果您可以以缓存友好的方式访问所有内容,那么它会更平坦一些,并且您可以轻松地使八叉树缓存友好,例如连续存储所有 8 个子级,此时您可以这样做:

struct OctreeNode
{
    // Index of first child node. To get to the 4th node,
    // we just access nodes[first_child+3], e.g.
    int first_child;
    ...
};

所以无论如何,如果这是两个选择,我在这种情况下投票支持八叉树。此外,对于这种类型的邻近搜索,您不一定希望八叉树太深。即使我们必须使用较浅的树查看比最佳点更多的点,这也比在树上频繁上下移动要好。如果您存储在叶子中的点是连续的,它确实有帮助。完成树的构建后,您可以通过后处理来实现这一目标。

请注意,对于这两种解决方案,您都必须查看兄弟节点。距离某个点最近的点不一定是位于同一叶节点中的点。在某些情况下,根据数据的性质,仅使用 3 维网格实际上就可以达到此目的,因为使用 3D 网格,您甚至不必费心从子项到父项再到兄弟姐妹。 3D 网格在内存使用方面似乎呈爆炸性增长,但如果将网格单元的内存开销减少到仅 32 位索引,则不一定如此。在这种情况下,100x100x100 网格占用的空间不到 4 MB。


2
投票

对于 3D 和固定查询半径,八叉树是一个不错的选择。如果您需要在磁盘上工作,其他数据结构可能会更好,但 k-d-tree 在这里也不起作用。

为什么不尝试两者并看看哪种更适合您的数据?


2
投票

在我的项目中,我使用八叉树进行范围搜索,它工作高效且易于实现。但从未将它与 KD-Tree 进行比较。 据我所知,对于三维数据,kd 树中此操作的最坏情况时间复杂度是 O(n^(2/3)),而八叉树只能保证 O(n)。因此,如果您关心最坏时间复杂度,请选择 KD Tree。 (我不关心最坏的时间复杂度,如果我知道在我的数据集中这永远不会发生。)


0
投票

我之前对同样的问题很感兴趣,做了以下实验来对比。

  • 我们采用两个点云(.pcd 文件,来自 LiDAR 传感器)作为输入。目标云大小 = 65536,源云大小 = 3000。
  • 对于源云中的每个点,找到其在目标云中的邻居点。
  • 规模约为10-50米,处于结构化环境中。
  • 第 13 代 Intel i7 CPU 笔记本电脑上的单线程。
  • 两种数据结构的实现均取自 PCL,并且在 C++ 程序中进行基准测试。
Operation                K-D Tree       Octree
Build Tree                   7 ms        12 ms
K-NN Search (k=1)          124 ms       390 ms
K-NN Search (k=10)         124 ms       395 ms
K-NN Search (k=100)        134 ms       573 ms
Radius Search (r=0.01 m)  1789 ms       126 ms
Radius Search (r=0.1 m)   1799 ms       129 ms
Radius Search (r=1 m)     2011 ms       415 ms

此外,我还针对这个结果做了一些消融研究。

  • 树构建的时间消耗与目标云大小呈线性关系。
  • 每种搜索方法的时间消耗也与源云大小几乎呈线性关系。 (即 size = 30000 大约需要比 size = 3000 多 10 倍的时间)。
  • 源查询云的位置和形状对运行时间影响不大。
  • PCL 点类型(PointXYZ 与 PointXYZRGBNormal)对运行时间影响不大。
© www.soinside.com 2019 - 2024. All rights reserved.