Преобразовать 32-байтовый двоичный файл big endian (лидарные данные) в список или массив python

#python #lidar #open3d #lidar-data

#python #лидар #open3d #лидарные данные

Вопрос:

У меня есть набор данных LiDAR, который имеет 32-байтовый двоичный формат big endian, и мне нужно преобразовать его в список python или массив, а затем преобразовать его в файл PCD. В настоящее время я использую следующий код, но он рассчитан только на 16 байт.

Какую модификацию я должен внести, чтобы код работал для 32-байтового файла big endian? Это ссылка на файл, с которым я работаю.

 import open3d as o3d
import numpy as np
import os
import sys
import struct

size_float = 4
list_pcd = []
with open ("C:\Users\wilso\python\datasets\DOTX182013031901004142612.log", "rb") as f:
    byte = f.read(size_float*4)
    while byte:
        x,y,z,intensity = struct.unpack("ffff", byte)
        list_pcd.append([x, y, z])
        byte = f.read(size_float*4)
np_pcd = np.asarray(list_pcd)
pcd = o3d.geometry.PointCloud()
v3d = o3d.utility.Vector3dVector
pcd.points = v3d(np_pcd)
o3d.io.write_point_cloud("copy_of_fragment.pcd", pcd)
  

Ответ №1:

На основе загруженной копии файла, на который вы ссылались, кажется, что ваш код уже настроен на правильную длину данных. (Более подробную информацию об этом смотрите ниже.) Проблема в том, что вы не указываете ему использовать big-endian. Для этого можно использовать struct.unpack , > — см. Порядок байтов. размер и выравнивание.

Если вы измените свой "ffff" на ">ffff" в своей программе, тогда это сработает.

Тогда вместо получения чисел типа:

 1.5583606204912748e-38 -112.75440216064453 8.758058715979973e 18
5.859210099898786e-23 7344.03173828125 44007040221184.0
2.734360572280704e 35 2.1044305180549755e 30 6.728572770953178e-05
862.4961547851562 -1167176.125 -9.643602918084717e 20
  

вы увидите такие числа, как:

 -22.08251953125 16.360233306884766 -2.3429789543151855
-21.318897247314453 16.111948013305664 -2.3769736289978027
-20.665271759033203 15.926865577697754 -2.4304943084716797
-19.91761016845703 15.659859657287598 -2.442497730255127
  

Я думаю, что некоторая путаница заключается в том, что вы (неправильно) понимаете, что ffff означает 16 бит, как если бы каждый f представлял 4-битную шестнадцатеричную цифру. Это не означает, что это. Каждое из них f обозначает «float», что означает 32-разрядное число с плавающей запятой, и таких чисел четыре ( x,y,z,intensity ), так что есть четыре f с. Например, если бы было три 64-разрядных (т. Е. с двойной точностью) числа, то это было бы ddd . Смотрите: список символов формата