k-d树也是二叉树,是用于分割多维空间的数据结构,所以其每一个节点是一个多维坐标。在这里先不做过多解释,我们暂且可以把k-d树理解为,点云中的点按照一定空间关系排列,方便进行查找操作。
查询max_nn个指定点的近邻点
[k, idx, _] = pcd_tree.search_knn_vector_3d(point, max_nn)
查询所有距离指定点小于radius的点
[k, idx, _] = pcd_tree.search_radius_vector_3d(point, radius)
最后返回max_nn个距离指定点小于radius的点
[k, idx, _] = pcd_tree.search_hybrid_vector_3d(point, radius, max_nn)
k: 找到满足要求点的个数
idx:找到满足要求点的索引列表
_:找到满足要求点到指定点的距离列表
import open3d as o3d
import numpy as np
def radius_search():
print("Loading pointcloud ...")
sample_pcd_data = o3d.data.PCDPointCloud()
pcd = o3d.io.read_point_cloud(sample_pcd_data.path)
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
print(
"Find the neighbors of 50000th point with distance less than 0.2, and painting them green ..."
)
[k, idx, _] = pcd_tree.search_radius_vector_3d(pcd.points[50000], 0.2)
#idx[1:]除了指定点,因为距离它最近的是它自己
#[:,:]第一个冒号代表所有行,第二个冒号代表所有行,
np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]
print("Displaying the final point cloud ...\n")
o3d.visualization.draw([pcd])
def knn_search():
print("Loading pointcloud ...")
sample_pcd = o3d.data.PCDPointCloud()
pcd = o3d.io.read_point_cloud(sample_pcd.path)
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
print(
"Find the 2000 nearest neighbors of 50000th point, and painting them red ..."
)
[k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[50000], 2000)
np.asarray(pcd.colors)[idx[1:], :] = [1, 0, 0]
print("Displaying the final point cloud ...\n")
o3d.visualization.draw([pcd])
if __name__ == "__main__":
knn_search()
radius_search()
import numpy as np
import open3d as o3d
if __name__ == "__main__":
print("Load two aligned point clouds.")
demo_data = o3d.data.DemoFeatureMatchingPointClouds()
pcd0 = o3d.io.read_point_cloud(demo_data.point_cloud_paths[0])
pcd1 = o3d.io.read_point_cloud(demo_data.point_cloud_paths[1])
pcd0.paint_uniform_color([1, 0.706, 0])
pcd1.paint_uniform_color([0, 0.651, 0.929])
o3d.visualization.draw_geometries([pcd0, pcd1])
print("Load their FPFH feature and evaluate.")
print("Black : matching distance > 0.2")
print("White : matching distance = 0")
feature0 = o3d.io.read_feature(demo_data.fpfh_feature_paths[0])
feature1 = o3d.io.read_feature(demo_data.fpfh_feature_paths[1])
fpfh_tree = o3d.geometry.KDTreeFlann(feature1)
for i in range(len(pcd0.points)):
[_, idx, _] = fpfh_tree.search_knn_vector_xd(feature0.data[:, i], 1)
#查找满足要求的特征点,并计算最接近特征点pcd1.points[idx[0]]到指定点的距离pcd0.points[i]
dis = np.linalg.norm(pcd0.points[i] - pcd1.points[idx[0]])
c = (0.2 - np.fmin(dis, 0.2)) / 0.2
pcd0.colors[i] = [c, c, c]
o3d.visualization.draw_geometries([pcd0])
print("")
print("Load their L32D feature and evaluate.")
print("Black : matching distance > 0.2")
print("White : matching distance = 0")
feature0 = o3d.io.read_feature(demo_data.l32d_feature_paths[0])
feature1 = o3d.io.read_feature(demo_data.l32d_feature_paths[1])
fpfh_tree = o3d.geometry.KDTreeFlann(feature1)
for i in range(len(pcd0.points)):
[_, idx, _] = fpfh_tree.search_knn_vector_xd(feature0.data[:, i], 1)
dis = np.linalg.norm(pcd0.points[i] - pcd1.points[idx[0]])
c = (0.2 - np.fmin(dis, 0.2)) / 0.2
pcd0.colors[i] = [c, c, c]
o3d.visualization.draw_geometries([pcd0])
print("")