.ply转Velodyne .bin方法及PointPillars直接读取.ply方案咨询
解决PointPillars兼容PLY点云的两种方案
方案一:将PLY格式转换为Velodyne .bin格式
KITTI的Velodyne .bin文件本质是**每个点存储为4个32位浮点数(x, y, z, intensity)**的二进制文件,你可以用Python工具快速转换,以下是两种常用实现:
方法1:用Open3D库转换
Open3D是点云处理常用库,代码简洁:
import open3d as o3d import numpy as np def ply_to_kitti_bin(ply_path, bin_path): # 读取PLY点云 pcd = o3d.io.read_point_cloud(ply_path) points = np.asarray(pcd.points) # 如果PLY包含强度信息则提取,没有则补0 if 'intensity' in pcd.point: intensities = np.expand_dims(np.asarray(pcd.point['intensity']), axis=1) else: intensities = np.zeros((points.shape[0], 1), dtype=np.float32) # 拼接x,y,z,intensity并转成float32格式 kitti_points = np.hstack((points, intensities)).astype(np.float32) # 写入bin文件 kitti_points.tofile(bin_path) # 调用示例 ply_to_kitti_bin("your_pointcloud.ply", "converted_pointcloud.bin")
方法2:用plyfile轻量转换
如果不想安装Open3D,用plyfile库更轻量(先执行pip install plyfile安装):
from plyfile import PlyData, PlyElement import numpy as np def ply_to_kitti_bin(ply_path, bin_path): ply_data = PlyData.read(ply_path) # 提取x,y,z坐标 x = ply_data['vertex']['x'] y = ply_data['vertex']['y'] z = ply_data['vertex']['z'] # 处理强度信息,无则补0 intensity = ply_data['vertex']['intensity'] if 'intensity' in ply_data['vertex'] else np.zeros_like(x, dtype=np.float32) # 组合成KITTI格式数组 kitti_points = np.column_stack((x, y, z, intensity)).astype(np.float32) # 写入二进制文件 kitti_points.tofile(bin_path) # 调用示例 ply_to_kitti_bin("your_pointcloud.ply", "converted_pointcloud.bin")
方案二:修改PointPillars代码直接读取PLY文件
如果不想批量转换,可以修改PointPillars的数据集加载逻辑,让它直接读取PLY:
- 定位数据加载核心代码:通常在项目的
dataset目录下(比如kitti_dataset.py),找到加载点云的函数(比如load_point_cloud)。 - 替换原.bin读取逻辑:把原来读取二进制文件的代码,替换成读取PLY的代码,示例如下:
import numpy as np import open3d as o3d def load_point_cloud(self, idx): # 原逻辑:读取bin文件 # point_path = self.root_path / "velodyne" / f"{idx:06d}.bin" # points = np.fromfile(point_path, dtype=np.float32).reshape(-1, 4) # 修改后的逻辑:读取PLY文件 point_path = self.root_path / "velodyne" / f"{idx:06d}.ply" pcd = o3d.io.read_point_cloud(str(point_path)) points = np.asarray(pcd.points) # 补充强度信息,无则补0 if 'intensity' in pcd.point: intensities = np.expand_dims(np.asarray(pcd.point['intensity']), axis=1) else: intensities = np.zeros((points.shape[0], 1), dtype=np.float32) points = np.hstack((points, intensities)).astype(np.float32) return points
- 修改数据集配置:在项目的配置文件(比如
configs/pointpillars.yaml)里,把点云文件的后缀从.bin改成.ply,确保代码能正确定位文件。
注意:如果你的PLY点云没有强度信息,补0不会影响PointPillars运行——算法会正常使用x,y,z坐标进行pillar编码。
内容的提问来源于stack exchange,提问作者Deepak Phaneendra
相关产品推荐
相关产品推荐

