【小白深度教程 1.27】手把手教你使用 Open3D(10)点云地面拟合与地面分割(Python 代码)

【小白深度教程 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

文章知识点与官方知识档案匹配,可进一步学习相关知识

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他