1、主要参考资料
(1)kd树原理
数组索引的kdtree建立及简明快速的k近邻搜索方法
(2)open3d
爆肝5万字 Open3D 点云数据处理基础(Python版))-技术圈
(3)视频参考
【Python+Open3D处理点云数据】2.KD树近邻搜索_哔哩哔哩_bilibili
(4)其它大佬
Python软件设计基础 第九节-Open3D模型处理_惊蛰鼬神的博客-CSDN博客_python打开3d模型
2、kd树原理
(1)主要应用
kd树(k-dimensional树的简称),是一种分割k维数据空间的数据结构,主要应用于多维空间关键数据的搜索,如范围搜索和最近邻搜索。
3、三种搜索算法
3.1K近邻搜索
(1)函数
Search_knn_vector_3d,返回查询点的K个最近邻索引列表,并将这些相邻的点存储在一个数组中
(2)参数说明
- 给的参数例子:(pcd.points[100],100), 第一个参数为开始索引的点,第二个参数是索引的个数
- 返回值[k, idx, _] ,其中k为索引的个数,idx为返回的点的索引
(3)代码例子
import open3d as o3d
import numpy as np
#(1)读取模型文件
pcd = o3d.io.read_point_cloud(r"D:/RGBD_CAMERA/python_3d_process/bunny.ply")
#(2)给模型一个统一的初始颜色
pcd.paint_uniform_color([0.5, 0.5, 0.5])
#(3)创建KD树
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
#(4)将接下来要初始索引的点(第100个点)颜色设置位红色,RGB
pcd.colors[100] = [1, 0, 0]
#(5)开始索引
#其中k为索引的个数,idx为返回的点的索引
#(pcd.points[100],100), 第一个参数为开始索引的点,第二个参数是索引的个数
[k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[100],100)
#(6)索引的结果给他们赋颜色,绿色,RGB
np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]
#(7)最后显示一下
o3d.visualization.draw_geometries([pcd],width=1200,height=1000)
(4)效果图
3.2半径领域搜索
(1)函数
Search_radius_vector_3d,查询所有和查询点距离小于给定半径的点。
(2)参数
- 输入参数例子(pcd.points[1000],0.02),第一个参数为开始索引的点,第二个参数是索引的半径大小
- 返回值[k, idx, _] ,其中k为索引的个数,idx为返回的点的索引
(3)代码测试
import open3d as o3d
import numpy as np
#(1)读取模型文件
pcd = o3d.io.read_point_cloud(r"D:/RGBD_CAMERA/python_3d_process/bunny.ply")
#(2)给模型一个统一的初始颜色
pcd.paint_uniform_color([0.5, 0.5, 0.5])
# #-------------------------------------------------------------
# #(一)近邻搜索
# #-------------------------------------------------------------
# #(1)创建KD树
# pcd_tree = o3d.geometry.KDTreeFlann(pcd)
# #(2)将接下来要初始索引的点(第100个点)颜色设置位红色,RGB
# pcd.colors[100] = [1, 0, 0]
# #(3)开始索引
# #其中k为索引的个数,idx为返回的点的索引
# #(pcd.points[100],100), 第一个参数为开始索引的点,第二个参数是索引的个数
# [k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[100],100)
# #(4)索引的结果给他们赋颜色,绿色,RGB
# np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]
# #(5)最后显示一下
# o3d.visualization.draw_geometries([pcd],width=1200,height=1000)
#-------------------------------------------------------------
#(二)半径搜索
#-------------------------------------------------------------
#(1)创建KD树
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
#(2)将接下来要初始索引的点(第100个点)颜色设置位红色,RGB
pcd.colors[1000] = [1, 0, 0]
#(3)开始索引
#其中k为索引的个数,idx为返回的点的索引
#(pcd.points[1000],0.02), 第一个参数为开始索引的点,第二个参数是索引的半径大小
[k, idx, _] = pcd_tree.search_radius_vector_3d(pcd.points[1000],0.02)
#(4)索引的结果给他们赋颜色,绿色,RGB
np.asarray(pcd.colors)[idx[1:], :] = [0, 0, 1]
#(5)最后显示一下
o3d.visualization.draw_geometries([pcd],width=1200,height=1000)
(4)效果图
3.3混合搜索
(1)函数
Search_hybrid_vector_3d,最多返回k个和被查询点距离小于给定半径的最近邻点。
(2)参数
- 输入参数例子(pcd.points[8000],0.03, 200),第一个参数为开始索引的点,第二个参数是索引的半径大小,第三个参数是返回最多多少个值
- 返回值[k, idx, _] ,其中k为索引的个数,idx为返回的点的索引
(3)代码
import open3d as o3d
import numpy as np
#(1)读取模型文件
pcd = o3d.io.read_point_cloud(r"D:/RGBD_CAMERA/python_3d_process/bunny.ply")
#(2)给模型一个统一的初始颜色
pcd.paint_uniform_color([0.5, 0.5, 0.5])
#-------------------------------------------------------------
#(一)近邻搜索
#-------------------------------------------------------------
#(1)创建KD树
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
#(2)将接下来要初始索引的点(第100个点)颜色设置位红色,RGB
pcd.colors[100] = [1, 0, 0]
#(3)开始索引
#其中k为索引的个数,idx为返回的点的索引
#(pcd.points[100],100), 第一个参数为开始索引的点,第二个参数是索引的个数
[k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[100],100)
#(4)索引的结果给他们赋颜色,绿色,RGB
np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]
#(5)最后显示一下
# o3d.visualization.draw_geometries([pcd],width=1200,height=1000)
#-------------------------------------------------------------
#(二)半径搜索
#-------------------------------------------------------------
#(1)创建KD树
# pcd_tree = o3d.geometry.KDTreeFlann(pcd)
#(2)将接下来要初始索引的点(第100个点)颜色设置位红色,RGB
pcd.colors[1000] = [1, 0, 0]
#(3)开始索引
#其中k为索引的个数,idx为返回的点的索引
#(pcd.points[1000],0.02), 第一个参数为开始索引的点,第二个参数是索引的半径大小
[k, idx, _] = pcd_tree.search_radius_vector_3d(pcd.points[1000],0.02)
#(4)索引的结果给他们赋颜色,绿色,RGB
np.asarray(pcd.colors)[idx[1:], :] = [0, 0, 1]
#(5)最后显示一下
# o3d.visualization.draw_geometries([pcd],width=1200,height=1000)
#-------------------------------------------------------------
#(三)混合搜索
#-------------------------------------------------------------
#(1)创建KD树
# pcd_tree = o3d.geometry.KDTreeFlann(pcd)
#(2)将接下来要初始索引的点(第100个点)颜色设置位红色,RGB
pcd.colors[8000] = [1, 0, 0]
#(3)开始索引
#其中k为索引的个数,idx为返回的点的索引
#(pcd.points[1000],0.02), 第一个参数为开始索引的点,第二个参数是索引的半径大小,第三个参数是返回最多多少个值
[k, idx, _] = pcd_tree.search_hybrid_vector_3d(pcd.points[8000],0.03, 200)
#(4)索引的结果给他们赋颜色,绿色,RGB
np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 1]
#(5)最后显示一下
o3d.visualization.draw_geometries([pcd],width=1200,height=1000)
(4)三个搜索综合显示