激光点云是一些空间点的集合,常见于XYZI的 ( N ∗ 4 ) (N*4) (N∗4)数组。
对于这些点云数据的存储无非就那么些方式(二进制、ASCII码、序列化及其他我也不清楚的方式),如果按后缀名来说 . p c d 、 . b i n 、 . n p y 、 . p k l .pcd、.bin、.npy、.pkl .pcd、.bin、.npy、.pkl等等。
最常见的还是二进制格式跟ASCII码,也主要是介绍这两种存储方式的pcd点云的读取,比较推荐二进制的方式,读写速度快。
# bin
def read_bin(self, pcd_file):
## struct read binary
import struct
list = []
with open(pcd_file, 'rb') as f:
data = f.read()
pc_iter = struct.iter_unpack('ffff', data)
for i, point in enumerate(pc_iter):
list.append(point)
return np.array(list)
# ASCII
def read_pcd(self, pcd_file):
data = []
with open(pcd_file, 'r') as f:
lines = f.readlines()[11:]
for line in lines:
line = list(line.strip('\n').split(' '))
# line = np.array(line.strip('\n').split(' '), dtype=np.float32)
x = float(line[0])
y = float(line[1])
z = float(line[2])
i = float(line[3])
r = math.sqrt(x**2 + y**2 + z**2) * i
data.append(np.array([x,y,z,i,r]))
# points = list(map(lambda line: list(map(lambda x: float(x), line.split(' '))), lines))
points = np.array(data)
return points
def pclpy_read_pcd(self, pcd_file):
## pclpy read pcd
import pclpy
from pclpy import pcl
cloud = pcl.PointCloud.PointXYZI()
# reader = pcl.io.PCDReader()
# reader.read(pcd_file, cloud)
pcl.io.loadPCDFile(pcd_file, cloud)
cloud = np.asarray(cloud.points)
def o3d_read_pcd(self, pcd_file):
## open3d read pcd
pcd = o3d.io.read_point_cloud(pcd_file)
points = np.asarray(pcd.points) # x, y, z
import numpy as np
data = np.array()
np.save('***.npy', data) #保存
# np保存为bin文件
data.tofile('data.bin')
load_data = np.load(npy_path, allow_pickle=True)
## np.fromfile read pcd
# 必须是二进制格式的pcd
cloud = np.fromfile(str(pcd_file), dtype=np.float32, count=-1)
# points = np.fromfile(lidar_path, dtype=np.float32).reshape(-1, 4)
# 去除Nan值
isnan = np.isnan(points[:,:3])
points = np.delete(points, np.where(isnan)[0], axis=0)
# read
with open(pkl_file, 'rb') as f:
data = pickle.load(f, encoding='latin1')
# write
with open(pkl_file, 'wb') as f:
pickle.dump(tensors, f, pickle.HIGHEST_PROTOCOL) # 写入tensor格式数据
# # pip3 install python-pcl
import pcl
pcd_ndarray = pcl.load(args.pcd_path).to_array()[:, :3] #不要intensity
# pcd_ndarray = pcl.load_XYZI(args.pcd_path).to_array()[:, :4]
point_num = pcd_ndarray.shape[0]
from pypcd import pypcd
import numpy as np
def read_pcd(pcd_path):
pcd = pypcd.PointCloud.from_path(pcd_path)
pcd_np_points = np.zeros((pcd.points, 4), dtype=np.float32)
pcd_np_points[:, 0] = np.transpose(pcd.pc_data['x'])
pcd_np_points[:, 1] = np.transpose(pcd.pc_data['y'])
pcd_np_points[:, 2] = np.transpose(pcd.pc_data['z'])
pcd_np_points[:, 3] = np.transpose(pcd.pc_data['intensity'])
del_index = np.where(np.isnan(pcd_np_points))[0]
pcd_np_points = np.delete(pcd_np_points, del_index, axis=0)
return pcd_np_points
其他比较详细的链接