【小白深度教程 1.27】手把手教你使用 Open3D (10)点云地面拟合与地面分割(Python 代码)
在这篇文章中,我们将学习如何使用 Open3D 对 自动驾驶 中获取的激光雷达数据(点云),进行地面拟合与分割。
该代码主要用于从 .bin 文件加载点云数据,进行地面分割,并对结果进行可视化处理。主要步骤包括:加载点云数据、计算法向量、基于主成分分析 (PCA) 进行地面分割、并可视化处理结果。
可视化效果:
点云地面分割结果:
Python 源码:
#!/usr/bin/env python3
import numpy as np
import open3d as o3d
import copy
def pcd_ground_seg_pca(scan, th=0.80, z_offset=-1.1):
""" Perform PCA over PointCloud to segment ground. """
pcd = copy.deepcopy(scan)
_, covariance = pcd.compute_mean_and_covariance()
eigen_vectors = np.linalg.eig(covariance)[1]
k = eigen_vectors.T[2]
# magnitude of projecting each face normal to the z axis
normals = np.asarray(scan.normals)
points = np.asarray(scan.points)
mag = np.linalg.norm(np.dot(normals, k).reshape(-1, 1), axis=1)
ground = pcd.select_by_index(np.where((mag >= th) & (points[:, 2] < z_offset))[0])
rest = pcd.select_by_index(np.where((mag >= th) & (points[:, 2] < z_offset))[0], invert=True)
# Also remove the faces that are looking downwards
up_normals = np.asarray(ground.normals)
orientation = np.dot(up_normals, k)
ground = ground.select_by_index(np.where(orientation > 0.0)[0])
ground.paint_uniform_color([1.0, 0.0, 0.0])
rest.paint_uniform_color([0.0, 0.0, 1.0])
return ground, rest
def load_bin_file(file_path):
""" Load a .bin point cloud file. """
# Load the point cloud data assuming each point is [x, y, z] format
point_cloud = np.fromfile(file_path, dtype=np.float32).reshape(-1, 4)[:, :3] # Assuming (x, y, z, intensity)
return point_cloud
def main():
# Load the .bin file
file_path = '0000000000.bin' # Replace with your .bin file path
points = load_bin_file(file_path)
# Create an Open3D point cloud object
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
# Estimate normals (required for PCA)
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=1.0, max_nn=30))
pcd.orient_normals_consistent_tangent_plane(100)
# Visualize the original point cloud
o3d.visualization.draw_geometries([pcd], window_name='Original Point Cloud')
# Apply ground segmentation
ground, rest = pcd_ground_seg_pca(pcd)
# Visualize the segmented results
o3d.visualization.draw_geometries([ground, rest], window_name='Segmented Point Cloud')
if __name__ == "__main__":
main()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
分割前后对比:
原始点云,其中颜色用来标识高度:
分割结果:
示例文件下载:
通过网盘分享的文件:exp127
链接: https://pan.baidu.com/s/1OwUVyV4MMGtV4tCs4ikxmA 提取码: set8
文章知识点与官方知识档案匹配,可进一步学习相关知识
OpenCV技能树
OpenCV中的深度学习
图像分类
29597
人正在系统学习中