NSDT工具推荐Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割

使用 3D 点云数据具有挑战性。 一张激光雷达图像中的点集合通常很广泛,根据图像大小可能达到数百万个点。 处理高度维度还带来了其他复杂性。

点云是空间中的一组数据点。 这些点可以表示 3D 形状或对象。 每个点位置都有其一组笛卡尔坐标(X、Y、Z)。

但是,我们拥有不同的工具,可以比以往更直接地处理激光雷达数据。 这篇博文将教你一种在 Python 中读取、操作和可视化激光雷达数据的简单方法。

1、读取和访问激光雷达数据

在本教程中,我们使用 Laspy(一个用于激光雷达 LAS/LAZ IO 的 Python 库)来摄取点云数据。 稍后,我们将使用用于 3D 数据处理的现代库 open3D 来可视化 3D 激光雷达数据。 所以让我们先导入这些库。

import laspy
import open3d as o3d
import numpy as np

让我们用 Laspy 读取激光雷达数据。 读取是使用 laspy.read() 函数完成的。 如果你只想要元数据而不想要点,也可以使用 laspy.open() 。

las = laspy.read(“data/lidar.las”)
las

一旦我们使用 laspy.read() 进行读取,就会获得元数据和点云数据。 我们的激光雷达数据的 las 标头如下所示。

<LasData(1.1, point fmt: <PointFormat(1, 0 bytes of extra dims)>, 277573 points, 1 vlrs)>

它包含 las 头、点格式、点计数和 vlrs。 我们也可以像这样单独调用它们以获得每个单独的输出。

las.header
las.header.point_format
las.header.point_count
las.vlrs

摄取的文件还包含点数据。 首先,让我们检查一下我们已阅读的激光雷达文件的可用功能。

list(las.point_format.dimension_names)

在这种情况下,我们可以使用以下功能。 请注意,这取决于 LAS 版本。

['X',
 'Y',
 'Z',
 'intensity',
 'return_number',
 'number_of_returns',
 'scan_direction_flag',
 'edge_of_flight_line',
 'classification',
 'synthetic',
 'key_point',
 'withheld',
 'scan_angle_rank',
 'user_data',
 'point_source_id',
 'gps_time']

对于点数据,我们有 X、Y 、 Z、强度、分类、GPS 时间和其他一些基本维度。 例如,让我们看看其中的一些维度。

las.X
las.intensity
las.gps_time

输出是代表 X、强度和 GPS 时间的数字数组。

# X
array([27799997, 27799997, 27799952, ..., 27775004, 27775002, 27775001])
#Intensity
array([10, 15, 12, ..., 30, 41, 35], dtype=uint16)
# gps_time
array([5880.963028, 5880.963032, 5880.978038, ..., 5886.739728,
       5886.739733, 5886.739738])

分类是另一个基本维度,你可以使用 las.classification 调用,它将提供一个数字数组。 但是,如果想从激光雷达数据中获取唯一的分类代码编号,则可以调用以下代码。

set(list(las.classification))

在我们的例子中,只有四个类。

1 = Unassigned
2 = Ground
5 = High Vegetation
6 = Building

LiDAR数据的分类方案不仅仅是我们拥有的类别。 有关类和相应 LAS 格式的完整详细信息,请参阅 ArcGIS 文档页面。

2、创建、过滤和写入点云数据

要创建 3D 点云数据,我们可以像这样使用 Numpy 将 X、Y 和 Z 维度堆叠在一起。

point_data = np.stack([las.X, las.Y, las.Z], axis=0).transpose((1, 0))
point_data

输出是一个 3 维数组,如下所示。

array([[ 68506260, 390272760,     31571],
       [ 68506057, 390272764,     31572],
       [ 68505659, 390272774,     31599],
       ...,
       [ 68747636, 389918893,     31996],
       [ 68747762, 389918889,     32296],
       [ 68747965, 389918898,     32223]])

我们知道数据的分类代码,因此可以过滤掉我们想要的任何类别。 例如,我们可以运行以下代码来仅过滤掉建筑类。

buildings = laspy.create(point_format=las.header.point_format, file_version=las.header.version)
buildings.points = las.points[las.classification == 6]

也可以像这样用.write()函数将我们筛选出来的建筑类点快速写入.las文件。

buildings.write(‘buildings.las’)

现在我们有一个新的激光雷达图像,其中只保存了建筑物数据。 让我们继续点云数据可视化。

3、3D 点云可视化

Laspy 没有可视化方法,因此我们将使用 open3d 库。 我们首先创建 open3D 几何图形并传递我们之前创建的点数据。 最后,我们使用 open3d 可视化来绘制几何图形。

geom = o3d.geometry.PointCloud()
geom.points = o3d.utility.Vector3dVector(point_data)
o3d.visualization.draw_geometries([geom])

这样做的好处是它也适用于 Jupyter Notebook。 它可以在单独的输出窗口中呈现 3D 可视化。 这是使用 Open3D 的数据的 3D 可视化。


原文链接:An Easy Way to Work and Visualize Lidar Data in Python

BimAnt翻译整理,转载请标明出处