三维点云学习(2)下-Octree
Octree(八叉树)的基本结构
思想:立体空间的分割

二维平面的展示

Octree(八叉树)的构建
#extent:立方体中心点到面的距离
#Center of the cube 立方体的中心

1.判断每一个点里面都有怎么样的主节点
2.计算子节点的中心在哪,子节点的边长,再把属于这个子节点的数据放进去

Octant构建完成之后,进行kNN的搜寻
这里展现了Octree比kd-tree的优越在于当红色框被S2包围时,可以马上结束搜寻

1.如果octant是一个末尾叶子节点,直接把数据扔进去KNN搜寻
2.如果不是末尾节点,进行寻找最有可能的子节点
3.如果查找成功,直接退出返回True,不成功,再搜寻其他子节点
4.overlaps() 用于判断,子节点与球是否有交际,没有就跳过(空间结构思想)
5.inside() ,如果球面被某一个Octant包围,可直接退出

inside的实现
#红色代表worst——dist
#正方形代表一个octant
只需要判断 extent > radius +diff 就可认为球在正方体里面

overlaps的实现
#case1:判断是否有接触
如果 diff > extent + radius 可认为球面与octant没接触

#case2:判断球体和某一个面是否接触
假设case1 成立,当有球体的中心点有两个轴位于正方体的相应轴内部时,也同样可判断为有交集

#case3.1:判断球体有没有跟正方体某个角点接触
当 diff < radius 可判断为和角点有接触

#case3.2:判断球体有没有跟正方体某个棱是否接触
注意:用max(,0)解决球体中某个点会陷在正方体的某个轴上,而出现的负数影响

oerlaps回顾:

Better one:
如果有一个球体完全包围一个正方体,那只需要对相应的octant进行kNN search就行

图示:
如果:
图示绿色线 < radius 可认为被包裹

复杂度

完整代码
#运行结果
Radius search normal:
Search takes 45438.469ms
Radius search fast:
Search takes 20330.457ms
import random
import math
import numpy as np
import time
from result_set import KNNResultSet, RadiusNNResultSet
class Octant:
def __init__(self, children, center, extent, point_indices, is_leaf):
self.children = children
self.center = center
self.extent = extent
self.point_indices = point_indices
self.is_leaf = is_leaf
def __str__(self):
output = ''
output += 'center: [%.2f, %.2f, %.2f], ' % (self.center[0], self.center[1], self.center[2])
output += 'extent: %.2f, ' % self.extent
output += 'is_leaf: %d, ' % self.is_leaf
output += 'children: ' + str([x is not None for x in self.children]) + ", "
output += 'point_indices: ' + str(self.point_indices)
return output
def traverse_octree(root: Octant, depth, max_depth):
depth[0] += 1
if max_depth[0] < depth[0]:
max_depth[0] = depth[0]
if root is None:
pass
elif root.is_leaf:
print(root)
else:
for child in root.children:
traverse_octree(child, depth, max_depth)
depth[0] -= 1
def octree_recursive_build(root, db, center, extent, point_indices, leaf_size, min_extent):
if len(point_indices) == 0:
return None
if root is None:
root = Octant([None for i in range(8)], center, extent, point_indices, is_leaf=True)
# determine whether to split this octant
if len(point_indices

本文深入探讨了八叉树(Octree)在三维点云数据中的构建与应用,特别是如何利用八叉树进行高效的K近邻(KNN)搜索和半径搜索。通过对比kd-tree,展示了八叉树在特定场景下的优势,并提供了完整的代码实现。
最低0.47元/天 解锁文章
1128





