python:常见读写点云pcd文件的方法总结

python读点云pcd的方法

  • 点云数据的常见存储格式
  • 读写pcd
    • read/readlines
    • pclpy
    • open3d
    • numpy
    • pickle
    • python-pcl
    • pypcd

点云数据的常见存储格式

激光点云是一些空间点的集合,常见于XYZI的 ( N ∗ 4 ) (N*4) N4数组。
对于这些点云数据的存储无非就那么些方式(二进制、ASCII码、序列化及其他我也不清楚的方式),如果按后缀名来说 . p c d 、 . b i n 、 . n p y 、 . p k l .pcd、.bin、.npy、.pkl .pcd.bin.npy.pkl等等。
最常见的还是二进制格式跟ASCII码,也主要是介绍这两种存储方式的pcd点云的读取,比较推荐二进制的方式,读写速度快。

读写pcd

read/readlines

# 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

pclpy

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)

open3d

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

numpy

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)

pickle

# 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格式数据

python-pcl

# # 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] 

pypcd

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

其他比较详细的链接

你可能感兴趣的:(PCL及ROS在实践中的应用,python,python,numpy)