首先要了解las数据格式的基本构成,其次利用开源库计算,laspy提供了两种方式
读取las文件
import laspy
import numpy as np
#参考链接:
# 用Matlab处理LAS点云(1)——LAS文件概述--知乎
# https://pythonhosted.org/laspy/tut_part_1.html
# https://laspy.readthedocs.io/en/latest/examples.html
# 按间距中的绿色按钮以运行脚本。
"""
Laspy can actually scale the x, y, and z dimensions for you.
Upper case dimensions (las_file.X, las_file.Y, las_file.Z) give the raw integer dimensions,
while lower case dimensions (las_file.x, las_file.y, las_file.z) give the scaled value.
Both methods support assignment as well,
although due to rounding error assignment using the scaled dimensions is not recommended.
利用laspy读取点云数据有两种方式:
1利用公式:实际坐标 = 采集值×比例因子+偏移值
每个las文件只有一个比例因子和一个偏移值,位于文件头中,每个点都对应一个采集值,位于点云数据块中
其中las.X,las.Y,las.Z,为采集值(整数),las.header.scales为xyz的比例因子(double),
las.header.offsets为xyz的偏移量(double),
真实坐标=las.XYZ*las.header.scales+las.header.offsets
2直接利用las.x(小写x),las.y,las.z,其分别储存实际的点云xyz坐标,均为一维数组,
再利用np.vstack((las.x, las.y, las.z)).transpose(),转为三维矩阵
综上:las.xyz=真实坐标=las.XYZ*las.header.scales+las.header.offsets
"""
if __name__ == '__main__':
las = laspy.read('D:/265079.00-265112.00.las')
print(las.header.point_count)
#方法1
# 获取第100点的采集坐标
x_dimension = las.X[99]
y_dimension = las.Y[99]
z_dimension = las.Z[99]
scale = las.header.scales
offset = las.header.offsets
# 计算真实xyz坐标
scaled_xyz = [0, 0, 0]
scaled_xyz[0] = (x_dimension * scale[0]) + offset[0]
scaled_xyz[1] = (y_dimension * scale[1]) + offset[1]
scaled_xyz[2] = (z_dimension * scale[2]) + offset[2]
# 方法2
coords = np.vstack((las.x, las.y, las.z)).transpose()
one_hundred_point = coords[99, :]
# 打印两种方法的点
print(one_hundred_point.tolist())
print(scaled_xyz)
结果:
写文件:
import laspy
import numpy as np
# 0. Creating some dummy data
my_data_xx, my_data_yy = np.meshgrid(np.linspace(-20, 20, 15), np.linspace(-20, 20, 15))
my_data_zz = my_data_xx ** 2 + 0.25 * my_data_yy ** 2
my_data = np.hstack((my_data_xx.reshape((-1, 1)), my_data_yy.reshape((-1, 1)), my_data_zz.reshape((-1, 1))))
# 1. Create a new header
header = laspy.LasHeader(point_format=3, version="1.2")
header.add_extra_dim(laspy.ExtraBytesParams(name="random", type=np.int32))
header.offsets = np.min(my_data, axis=0)
header.scales = np.array([0.1, 0.1, 0.1])
# 2. Create a Las
las = laspy.LasData(header)
las.x = my_data[:, 0]
las.y = my_data[:, 1]
las.z = my_data[:, 2]
las.random = np.random.randint(-1503, 6546, len(las.points), np.int32)
las.write("new_file.las")