Невозможно добавить пользовательские атрибуты в файл LAS.Python

Программы на Python
Ответить
Anonymous
 Невозможно добавить пользовательские атрибуты в файл LAS.

Сообщение Anonymous »

Я пытаюсь преобразовать облако точек формата txt в las, чтобы иметь возможность просмотреть его в Potree. Я использую следующий скрипт Python:
import laspy
import numpy as np

def read_points3D(file_path):
points = []
with open(file_path, 'r') as file:
for line in file:
if line.startswith('#') or line.strip() == "":
continue
parts = line.strip().split()
point_id = int(parts[0]) # Read the 3D point identifier
x, y, z = map(float, parts[1:4])
r, g, b = map(int, parts[4:7])
error = float(parts[7]) # Read `error`
building_id = int(parts[8]) # Extract `building_id`
points.append((point_id, x, y, z, r, g, b, error, building_id))
return np.array(points)

def write_las(output_path, points):
# Set up header with format 3 (supports RGB) and version 1.2
header = laspy.LasHeader(point_format=3, version="1.2")
header.x_scale = header.y_scale = header.z_scale = 0.01
header.x_offset = header.y_offset = header.z_offset = 0.0

las = laspy.LasData(header)
las.x = points[:, 1] # x coordinates
las.y = points[:, 2] # y coordinates
las.z = points[:, 3] # z coordinates
las.red = points[:, 4] # red color
las.green = points[:, 5] # green color
las.blue = points[:, 6] # blue color

# Add 'point_id', 'error', and 'building_id' as extra dimensions
las.add_extra_dim(laspy.ExtraBytesParams(name="point_id", type="int32"))
las.add_extra_dim(laspy.ExtraBytesParams(name="error", type="float32"))
las.add_extra_dim(laspy.ExtraBytesParams(name="building_id", type="int32"))

# Assign values to extra dimensions
las['point_id'] = points[:, 0]
las['error'] = points[:, 7]
las['building_id'] = points[:, 8]

# Debug: Verify the values of 'point_id', 'error', and 'building_id'
print("Point IDs:", las['point_id'][:10]) # Print first 10 values for verification
print("Error values:", las['error'][:10]) # Print first 10 values for verification
print("Building IDs:", las['building_id'][:10]) # Print first 10 values for verification

las.write(output_path)
print(f'LAS file created at {output_path}')

# Replace with the paths to your COLMAP points3D.txt file and output LAS file
input_txt_path = 'frames_8dir_turn/sparse/points3D_modified.txt'
output_las_path = 'frames_8dir_turn/sparse/points3D_modified.las'

points3D = read_points3D(input_txt_path)
write_las(output_las_path, points3D)

Как бы я ни изменял назначение, я не могу добиться, чтобы пользовательские атрибуты отображались в файле LAS при его анализе с помощью pdal, и, конечно же, могу не просматриваю эти свойства в potree.
Я также пробовал присваивать значения с помощью setattr(), вот так:
# Define extra dimensions with setattr
extra_dimensions = {
'point_id': points[:, 0],
'error': points[:, 7],
'building_id': points[:, 8]
}

for name, data in extra_dimensions.items():
# Add each extra dimension as a new attribute to `las`
las.add_extra_dim(laspy.ExtraBytesParams(name=name, type="int32" if name != 'error' else "float32"))
setattr(las, name, data)

Но это все равно не работает. Один обходной путь, который я пробовал использовать, — это назначение данных другим существующим полям формата laspy, и это работает в некоторой степени, но potree ожидал использования этих полей, что действительно раздражает, и я знаю, что он должен поддерживать пользовательские атрибуты (которые именно поэтому я использую его в первую очередь).
Для справки, pdal infopoints3d_modify.las --all возвращает:
{
"boundary":
{
"area": 28561.51668,
"avg_pt_per_sq_unit": 2.009703593,
"avg_pt_spacing": 0.5283232902,
"boundary": "POLYGON ((72.412391 -117.52643,105.56859 54.758215,6.1 112.18643,-126.52478 -2.67,72.412391 -117.52643))",
"boundary_json": { "type": "Polygon", "coordinates": [ [ [ 72.412390669999994, -117.52642985 ], [ 105.568586010000004, 54.75821492 ], [ 6.1, 112.186429849999996 ], [ -126.524781349999998, -2.67 ], [ 72.412390669999994, -117.52642985 ] ] ] },
"density": 3.582617868,
"edge_length": 0,
"estimated_edge": 114.8564298,
"hex_offsets": "MULTIPOINT (0 0, -33.1562 57.4282, 0 114.856, 66.3124 114.856, 99.4686 57.4282, 66.3124 0)",
"sample_size": 5000,
"threshold": 15
},
"file_size": 4707807,
"filename": "points3D_modified.las",
"metadata":
{
"comp_spatialreference": "",
"compressed": false,
"copc": false,
"count": 102325,
"creation_doy": 313,
"creation_year": 2024,
"dataformat_id": 3,
"dataoffset": 857,
"filesource_id": 0,
"global_encoding": 0,
"global_encoding_base64": "AAA=",
"header_size": 227,
"major_version": 1,
"maxx": 129.58,
"maxy": 9.13,
"maxz": 152.34,
"minor_version": 2,
"minx": -138.28,
"miny": -41.56,
"minz": -148.58,
"offset_x": 0,
"offset_y": 0,
"offset_z": 0,
"point_length": 46,
"project_id": "00000000-0000-0000-0000-000000000000",
"scale_x": 0.01,
"scale_y": 0.01,
"scale_z": 0.01,
"software_id": "laspy 2.5.4",
"spatialreference": "",
"srs":
{
"compoundwkt": "",
"horizontal": "",
"isgeocentric": false,
"isgeographic": false,
"json":
{
},
"prettycompoundwkt": "",
"prettywkt": "",
"proj4": "",
"units":
{
"horizontal": "unknown",
"vertical": ""
},
"vertical": "",
"wkt": ""
},
"system_id": "OTHER",
"vlr_0":
{
"data": "AAAGAHBvaW50X2lkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAGVycm9yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAGJ1aWxkaW5nX2lkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"description": "Extra Bytes Record",
"record_id": 4,
"user_id": "LASF_Spec"
}
},
"now": "2024-11-08T18:02:34+0900",
"pdal_version": "2.8.1 (git-version: Release)",
"reader": "readers.las",
"schema":
{
"dimensions":
[
{
"name": "X",
"size": 8,
"type": "floating"
},
{
"name": "Y",
"size": 8,
"type": "floating"
},
{
"name": "Z",
"size": 8,
"type": "floating"
},
{
"name": "Intensity",
"size": 2,
"type": "unsigned"
},
{
"name": "ReturnNumber",
"size": 1,
"type": "unsigned"
},
{
"name": "NumberOfReturns",
"size": 1,
"type": "unsigned"
},
{
"name": "ScanDirectionFlag",
"size": 1,
"type": "unsigned"
},
{
"name": "EdgeOfFlightLine",
"size": 1,
"type": "unsigned"
},
{
"name": "Classification",
"size": 1,
"type": "unsigned"
},
{
"name": "Synthetic",
"size": 1,
"type": "unsigned"
},
{
"name": "KeyPoint",
"size": 1,
"type": "unsigned"
},
{
"name": "Withheld",
"size": 1,
"type": "unsigned"
},
{
"name": "Overlap",
"size": 1,
"type": "unsigned"
},
{
"name": "ScanAngleRank",
"size": 4,
"type": "floating"
},
{
"name": "UserData",
"size": 1,
"type": "unsigned"
},
{
"name": "PointSourceId",
"size": 2,
"type": "unsigned"
},
{
"name": "GpsTime",
"size": 8,
"type": "floating"
},
{
"name": "Red",
"size": 2,
"type": "unsigned"
},
{
"name": "Green",
"size": 2,
"type": "unsigned"
},
{
"name": "Blue",
"size": 2,
"type": "unsigned"
}
]
},
"stac":
{
"message": "Failed to create STAC Feature with missing key. 'EPSG:4326'",
"status": "error"
},
"stats":
{
"bbox":
{
"native":
{
"bbox":
{
"maxx": 129.58,
"maxy": 9.13,
"maxz": 152.34,
"minx": -138.28,
"miny": -41.56,
"minz": -148.58
},
"boundary": { "type": "Polygon", "coordinates": [ [ [ -138.28, -41.56, -148.58 ], [ -138.28, 9.13, -148.58 ], [ 129.58, 9.13, 152.34 ], [ 129.58, -41.56, 152.34 ], [ -138.28, -41.56, -148.58 ] ] ] }
}
},
"statistic":
[
{
"average": 0.9007860249,
"count": 102325,
"maximum": 129.58,
"minimum": -138.28,
"name": "X",
"position": 0,
"stddev": 8.111961245,
"variance": 65.80391524
},
{
"average": -1.400667677,
"count": 102325,
"maximum": 9.13,
"minimum": -41.56,
"name": "Y",
"position": 1,
"stddev": 2.239800826,
"variance": 5.016707742
},
{
"average": 0.6305325189,
"count": 102325,
"maximum": 152.34,
"minimum": -148.58,
"name": "Z",
"position": 2,
"stddev": 8.202147334,
"variance": 67.27522088
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "Intensity",
"position": 3,
"stddev": 0,
"variance": 0
},
{
"average": 1,
"count": 102325,
"maximum": 1,
"minimum": 1,
"name": "ReturnNumber",
"position": 4,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "NumberOfReturns",
"position": 5,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "ScanDirectionFlag",
"position": 6,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "EdgeOfFlightLine",
"position": 7,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "Classification",
"position": 8,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "ScanAngleRank",
"position": 9,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "UserData",
"position": 10,
"stddev": 0,
"variance": 0
},
{
"average": 48818.02142,
"count": 102325,
"maximum": 65535,
"minimum": 1,
"name": "PointSourceId",
"position": 11,
"stddev": 21073.40222,
"variance": 444088281.2
},
{
"average": 87.2854923,
"count": 102325,
"maximum": 255,
"minimum": 0,
"name": "Red",
"position": 12,
"stddev": 61.9076842,
"variance": 3832.561363
},
{
"average": 95.50267286,
"count": 102325,
"maximum": 255,
"minimum": 0,
"name": "Green",
"position": 13,
"stddev": 61.30552525,
"variance": 3758.367426
},
{
"average": 89.79526997,
"count": 102325,
"maximum": 255,
"minimum": 0,
"name": "Blue",
"position": 14,
"stddev": 62.65696759,
"variance": 3925.895588
},
{
"average": 0.5833813223,
"count": 102325,
"maximum": 3.87784185,
"minimum": 4.444691769e-05,
"name": "GpsTime",
"position": 15,
"stddev": 0.5300718622,
"variance": 0.2809761791
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "Synthetic",
"position": 16,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "KeyPoint",
"position": 17,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "Withheld",
"position": 18,
"stddev": 0,
"variance": 0
},
{
"average": 0,
"count": 102325,
"maximum": 0,
"minimum": 0,
"name": "Overlap",
"position": 19,
"stddev": 0,
"variance": 0
}
]
}
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... o-las-file
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»