激光雷达点云数据的读取与显示

前言

激光雷达(LiDAR, Light Detection and Ranging)技术近年来在林业、生态、测绘等多个领域中展现出强大的数据获取能力。它能够快速、精确、非接触地获取目标地物的三维空间结构,特别适用于森林这种具有复杂垂直结构的生态系统。

通过激光雷达点云数据,可以提取出诸如单木高度、胸径估测、树冠宽度、林冠层结构、地形起伏、植被间隙率等重要参数,这些数据为森林资源调查、经营规划、生态监测等工作提供了坚实的数据支撑。

因此,作为林业工作者,**掌握激光雷达点云的基本结构与处理流程还是蛮重要的。本文将从.las格式文件的结构入手,介绍其基本组成和关键字段,并展示如何使用Python进行点云数据的读取与显示。

.las格式点云数据

.las 是激光雷达点云最通用的数据交换格式,由 ASPRS(美国摄影测量与遥感学会)制定,旨在为激光雷达行业提供一种标准化的、高效的数据格式。.las 文件采用二进制格式,具备结构清晰、体积小、读取高效等特点,已成为点云数据处理工作中的行业标准格式。

LAS 文件主要由两部分组成:

  • 文件头(Header):记录整体数据的基本信息,如点数、坐标范围、版本号、点格式编号等。

    • 头文件信息中需要注意的就是scale(缩放)和offset(平移),在las文件中,为了压缩数据体积和提高效率,每个点的 XYZ 坐标都不是以浮点数直接存储,而是以整数存储,再结合头文件中提供的scale和offset来计算出点的真实地理坐标。不过 laspy 已经在自动应用了转换,所以你通常直接用las.x就是转换后的结果。如下代码的两种形式打印出来的是相同的结果:
x_real5 = las.X[5] * las.header.x_scale + las.header.x_offset
print("point5:",x_real5)
print(las.x[5]) 
  • 点数据记录(Point Records):记录每一个点的三维坐标和属性信息,如强度、分类、回波信息、颜色等。

点数据记录的主要字段说明:

字段名称 含义 数据类型 长度
X 点的 X 坐标(需缩放/平移) long 4 bytes
Y 点的 Y 坐标(需缩放/平移) long 4 bytes
Z 点的 Z 坐标(需缩放/平移) long 4 bytes
intensity 激光回波的强度值 unsigned short 2 bytes
return_number 当前点是该激光脉冲的第几次回波 3 bits 3位
number_of_returns 该激光脉冲总共检测到几次回波 3 bits 3位
classification 点的类别(如地面、植被、建筑等) unsigned char 1 byt
red 红色通道值(颜色信息) unsigned short 2 bytes
green 绿色通道值(颜色信息) unsigned short 2 bytes
blue 蓝色通道值(颜色信息) unsigned short 2 bytes

说明:不同的 LAS 点格式(如 Format 0, 1, 2, 3...)包含的字段有所不同。颜色信息(RGB)一般从 Format 2 开始支持。

点云数据读取与显示

  1. 调用laspy对点云数据进行读取,先查看其头文件信息
'''
@微信公众号:生态遥感学习记录
'''

import laspy
import pyvista as pv
import numpy as np

# 1.读取文件
las = laspy.read(r"C:\Users\YSYmc\Desktop\近期内容\lidar_data\test.las")

# 2.打印基本属性信息
print("点云总点数:", las.header.point_count)
print("LAS版本:", las.header.version)
print("点格式:", las.header.point_format)
print("x_offset:",las.header.x_offset)
print("x_scale:",las.header.x_scale)
print("点云范围:")
print(f"  X: {las.x.min():.2f} - {las.x.max():.2f}")
print(f"  Y: {las.y.min():.2f} - {las.y.max():.2f}")
print(f"  Z: {las.z.min():.2f} - {las.z.max():.2f}")
print("包含的属性字段",list(las.point_format.dimension_names))
  1. 查看点数据属性信息:
#3.打印点的属性信息(前五个点)
print("\n前 5 个点的详细属性:")
for i in range(5):
 info = f"Point {i+1}: x={las.x[i]:.2f}, y={las.y[i]:.2f}, z={las.z[i]:.2f}"
 if "intensity" in las.point_format.dimension_names:
 info += f", intensity={las.intensity[i]}"
 if "return_number" in las.point_format.dimension_names:
 info += f", return_num={las.return_number[i]}"
 if "number_of_returns" in las.point_format.dimension_names:
 info += f", num_returns={las.number_of_returns[i]}"
 if "classification" in las.point_format.dimension_names:
 info += f", class={las.classification[i]}"
 print(info)
  1. 按属性字段显示点云数据,为了流畅查看我对点云数据进行了抽稀
#4.随机抽稀点云(保留70%),这是为了不卡顿,方便挪动查看
    keep_ratio = 0.7
    total = len(las.x)
    indices = np.random.choice(total, int(total * keep_ratio), replace=False)
    #重构点云数据将其转为每一行为每一个点的x、y、z数据
    points = np.vstack((las.x[indices], las.y[indices], las.z[indices])).T
    cloud = pv.PolyData(points)
    
    cloud["Elevation"]=las.z[indices]
    color_field = "Elevation"  # 你可以改成其他字段
    #5.可视化点云
    cloud.plot(
     scalars=color_field         #基于该属性字段进行着色
     ,cmap="viridis"              # 其他的色带:'viridis', 'plasma', 'terrain', 'coolwarm'
     ,point_size=2                #控制点的显示大小
     ,show_scalar_bar=True #显示colorbar
     ,render_points_as_spheres=True)#该参数用于控制点云在渲染时是否以球体的形式显示,是的话显示效果更好

4.按RGB显示点云数据,该点云数据已经使用了照片进行了点云附色

r = las.red[indices]
g = las.green[indices]
b = las.blue[indices]
rgb = np.column_stack((r, g, b))  # shape = (N, 3)

# 5. 按RGB显示点云
cloud.point_data['RGB'] = rgb
cloud.plot(rgb=True, point_size=2, render_points_as_spheres=True)
#rgb=True,表示使用RGB附点云颜色
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容