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) )
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] )