这里两点云的交集指既属于点云1又属于点云2的点集。
基于kd-tree搜索的方法较快速,当然也可以暴力搜索。思路如下:
step1 在点云2建立kd-tree,设置容忍误差(搜索半径)
step2 遍历点云1中的点,记录下到点云2中的点的距离小于搜索半径的点的索引
step3 将点云1中不在索引中的点保存下来作为结果点云3
两点云求交集
红色和蓝色为cloud1和cloud2,黄色为交集部分,使用的KD树搜索半径范围内的点,设置为0.0001。
图一 点云一
图二 点云二
图三 求交集后
import open3d as o3d
import numpy as np
def intersection(cloud1,cloud2):
"""
点云数据求交集
len(cloud1)<len(cloud2)
:param cloud1: point cloud
:param cloud2: point cloud
:return: intersection point cloud
"""
# 构件KD树
kdtree = o3d.geometry.KDTreeFlann(cloud2)
# 半径搜索
radius = 0.0001
# 用于存储在cloud2中找到的与cloud1中每个点的最近邻索引
indices = []
# 遍历cloud1中的每个点
for i in range(len(cloud1.points)):
# 使用 KD 树搜索在半径radius内的最近邻点索引
[_, idx, _] = kdtree.search_radius_vector_3d(cloud1.points[i], radius)
idx = np.asarray(idx, dtype=int) # 将索引转换为整数类型
if len(idx) > 0:
indices.append(i)
# 提取点数据
cloud3_points = [cloud1.points[i] for i in indices if i < len(cloud1.points)]
cloud3 = o3d.geometry.PointCloud()
cloud3.points = o3d.utility.Vector3dVector(cloud3_points)
# Print Point Cloud Sizes
print(f"cloud1 has {len(cloud1.points)} points")
print(f"cloud2 has {len(cloud2.points)} points")
print(f"cloud3 has {len(cloud3.points)} points")
# Save Point Cloud
o3d.visualization.draw_geometries([cloud3])
return cloud3
参考文章
给算法爸爸上香. 两点云求差集和交集