我正在尝试将 .e57 点云转换为 .las 点云,但我遇到了似乎是由准确性引起的问题。下图展示了 CloudCompare 中的原始 .e57 与同样在 CloudCompare 中转换的 .las 文件。为了比较差异,点大小显着增大。
如您所见,这些点在 LAS 文件中以某种网格图案定位。检查 Potree 中的 LAS 文件会在很大程度上暴露出该问题。请参见下图。
我将 E57 转换为 LAS 的代码发布在下面。如果有人对为什么会发生这种情况以及为什么这些点似乎是网格对齐有任何见解,那么我很乐意听到更多信息。
import numpy as np
import pye57
import laspy
e57 = pye57.E57("in.e57")
# read scan at index 0
data = e57.read_scan(index=0, ignore_missing_fields=True, colors=True, intensity=True)
# 'data' is a dictionary with the point types as keys
assert isinstance(data["cartesianX"], np.ndarray)
assert isinstance(data["cartesianY"], np.ndarray)
assert isinstance(data["cartesianZ"], np.ndarray)
# other attributes can be read using:
# data = e57.read_scan(0, intensity=True, colors=True, row_column=True)
assert isinstance(data["cartesianX"], np.ndarray)
assert isinstance(data["cartesianY"], np.ndarray)
assert isinstance(data["cartesianZ"], np.ndarray)
assert isinstance(data["intensity"], np.ndarray)
assert isinstance(data["colorRed"], np.ndarray)
assert isinstance(data["colorGreen"], np.ndarray)
assert isinstance(data["colorBlue"], np.ndarray)
# the ScanHeader object wraps most of the scan information:
header = e57.get_header(0)
print(header.point_count)
print(header.rotation_matrix)
print(header.translation)
# all the header information can be printed using:
for line in header.pretty_print():
print(line)
# Create a new LAS file
las_out = laspy.create(point_format=3, file_version='1.2')
# Populate the LAS file with point cloud data
print(data["cartesianX"])
las_out.x = data["cartesianX"]
las_out.y = data["cartesianY"]
las_out.z = data["cartesianZ"]
las_out.intensity = data["intensity"]
las_out.red = data["colorRed"]
las_out.green = data["colorGreen"]
las_out.blue = data["colorBlue"]
# Close the LAS file
las_out.write("output/out.las")
看来我在 LAS 标头中的缩放完全关闭了。根据 LAS 标准,浮点数四舍五入为整数,小数位数决定精度。
我通过添加比例和偏移标题解决了这个问题
xmin = np.floor(np.min(data["cartesianX"]))
ymin = np.floor(np.min(data["cartesianY"]))
zmin = np.floor(np.min(data["cartesianZ"]))
las_out.header.offset = [xmin, ymin, zmin]
las_out.header.scale = [0.001, 0.001, 0.001]