Open3D KdTree建立、3种近邻搜索及结果可视化

1. 点云索引

Open3D KdTree,可以快速的在无序的点云中建立空间拓扑结构,使得能迅速的进行近邻搜索;

2. 近邻方法分类:

Open3D这边支持的近邻搜索方法由VTK实现;

  • K近邻搜索(K Nearest Neighbors Search)
  • 半径近邻搜索(Radius Nearest Neighbors Search)
  • 混合近邻搜索( RKNN Radius K Nearest Neighbors Search)

3. 索引应用

  • 点云下采样
  • 点云的高效无损压缩 15%
  • 基于邻域关系的快速查找

4. 效果图

原始点云
在这里插入图片描述
近邻搜索结果

k近邻中心点红色,K近邻绿色
半径近邻中心点红色,半径近邻蓝色
混合近邻中心点黄色,混合近邻点青色
在这里插入图片描述

# <Open3D使用FLANN来构建KDTree,以便快速检索最近的邻居。>
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
import open3d as o3d
import os

def search_knn_vector_3d(pcd, pcd_tree, k, j):
    # search_knn_vector_3d K近邻查询
    pcd.colors[20 * j] = [1, 0, 0]  # 给定查询点并渲染为红色
    [k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[20 * j], k)
    o3d.np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]  # K邻域的点,渲染为绿色
    print(idx[1])
    print(pcd.points[idx[2]])

def search_radius_vector_3d(pcd, pcd_tree, k, j, dis):
    # search_radius_vector_3d 半径近邻搜索
    pcd.colors[150 * j] = [1, 0, 0]  # 给定查询点并渲染为红色
    [k1, idx1, _] = pcd_tree.search_radius_vector_3d(pcd.points[150 * j], 2 * dis)
    o3d.np.asarray(pcd.colors)[idx1[1:], :] = [0, 0, 1]  # 半径搜索结果并渲染为蓝色

def search_hybrid_vector_3d(pcd, pcd_tree, k, j, dis):
    # 混合搜索(RKNN),它最多返回K个和查询点距离小于给定半径的最邻近点
    pcd.colors[200 * j] = [1, 1, 0]  # 给定查询点并渲染为黄色
    [k2, idx2, _] = pcd_tree.search_hybrid_vector_3d(pcd.points[200 * j], 2 * dis, k)
    o3d.np.asarray(pcd.colors)[idx2[1:], :] = [0, 1, 0.8]  # 半径搜索结果并渲染为青色


path = os.path.abspath(os.path.join(os.getcwd(), "../"))
path = path + "/pcds/bunny.pcd"
# k:ksearch数量
# j:第多少个点*基数当作寻找的点
# dis:半径search的半径值基数
k = 50
j = 1
dis = 0.01
# path = path + "/pcds/1001140020191217_las2pcd_g.pcd"
# j = 150
# k = 20000
# dis = 1
print(path)

pcd = o3d.io.read_point_cloud(path)
pcd.paint_uniform_color([0.5, 0.5, 0.5])  # 把所有点渲染为灰色(灰兔子)
print(pcd)
o3d.visualization.draw_geometries([pcd], window_name='Open3D KdTree Origin', width=800, height=600, left=50, top=50,
                                  point_show_normal=False, mesh_show_wireframe=False,
                                  mesh_show_back_face=False)

# 建立KD树索引
pcd_tree = o3d.geometry.KDTreeFlann(pcd)

search_knn_vector_3d(pcd, pcd_tree, k, j)
search_radius_vector_3d(pcd, pcd_tree, k, j, dis)
search_hybrid_vector_3d(pcd, pcd_tree, k, j, dis)

# 可视化
o3d.visualization.draw_geometries([pcd], window_name='Open3D KdTree', width=800, height=600, left=50, top=50,
                                  point_show_normal=False, mesh_show_wireframe=False,
                                  mesh_show_back_face=False)

猜你喜欢

转载自blog.csdn.net/qq_40985985/article/details/108715952
今日推荐