open3d最大平面检测,平面分割

1.点云读入

# 读取点云
pcd = o3d.io.read_point_cloud("point_cloud_00000.ply")
  • 配套点云颜色为白色,open3d的点云显示默认背景为白色,所以将点云颜色更改为黑色
pcd.colors = o3d.utility.Vector3dVector(np.zeros(np.array(pcd.colors).shape))
  • 显示点云
o3d.visualization.draw_geometries([pcd])

在这里插入图片描述

2.平面分割

  • RANSAC方法寻找最大平面(RANSAC方法可以在干扰点存在的情况下拟合数据,需要给定拟合方程,通过在数据中随机选取指定个数的点来求解方程参数,然后看所有数据中有多少数据满足所求解得到的方程,如果数量超过设定阈值,就完成拟合)
  • 注意,RANSAC方法随机选点,所以结果会具有一定的随机性,特别是干扰点较多的时候,两次运行可能会得到不一样的结果
plane_model, inliers = pcd.segment_plane(distance_threshold=1 * 1e-3,
                                         ransac_n=3,
                                         num_iterations=1000)
  • 关键参数
    • distance_threshold:点到平面的最小距离,越小结果越精准
    • ransac_n:求解平面方程所需的随机点个数
    • num_iterations:随机平面被采样和验证的次数(随机选取点的次数,越大越可能得到正确结果,但会越慢)
  • 返回参数
    • plane_model:平面标准方程参数(将平面返回为(a,b,c,d),使得对于平面上的每个点(x,y,z))
    • inliers:内点(满足平面方程的点)的索引列表
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")
Plane equation: 0.00x + -0.01y + 1.00z + -0.44 = 0

3.内点提取与可视化显示

  • 提取内点并涂色:
inlier_cloud = pcd.select_by_index(inliers)
inlier_cloud.paint_uniform_color([1.0, 0, 0])
  • 保留外点:(通过内点索引取反)
outlier_cloud = pcd.select_by_index(inliers, invert=True)
  • 内点外点同时可视化:
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud])

在这里插入图片描述

4.整体代码

import open3d as o3d
import numpy as np

pcd = o3d.io.read_point_cloud('duanmian/1/point_cloud_00000.ply')
points = np.array(pcd.points)
colors = np.zeros(np.array(pcd.points).shape[0])
pcd.colors = o3d.utility.Vector3dVector(np.zeros(np.array(pcd.colors).shape))
#o3d.visualization.draw_geometries([pcd])

plane_model, inliers = pcd.segment_plane(distance_threshold=1 * 1e-3,
                                         ransac_n=3,
                                         num_iterations=1000)
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")

inlier_cloud = pcd.select_by_index(inliers)
inlier_cloud.paint_uniform_color([1.0, 0, 0])
outlier_cloud = pcd.select_by_index(inliers, invert=True)
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud])

猜你喜欢

转载自blog.csdn.net/weixin_53610475/article/details/129204545