从KITTI到自定义:OpenPCDet在Windows 10下的实战数据适配与避坑指南

张开发
2026/4/11 18:18:12 15 分钟阅读

分享文章

从KITTI到自定义:OpenPCDet在Windows 10下的实战数据适配与避坑指南
1. OpenPCDet框架与KITTI数据集基础OpenPCDet作为当前点云3D目标检测领域的热门框架其模块化设计和简洁的代码结构让很多研究者选择它作为开发基础。我第一次接触这个框架时最吸引我的是它的数据-模型分离设计——这种设计让切换数据集和模型变得非常灵活。举个例子你完全可以用KITTI数据集训练PointPillar模型然后换成自定义数据集跑PV-RCNN只需要改几个配置文件就能实现。KITTI数据集的标准格式是入门必须掌握的。它的3D bounding box标注采用(cx, cy, cz, dx, dy, dz, heading)七参数表示法(cx, cy, cz)是物体3D框的几何中心坐标(dx, dy, dz)分别代表物体在heading角度为0时沿x/y/z轴方向的长度heading表示物体在俯视图下的朝向角x轴方向为0度逆时针旋转角度增加在Windows 10环境下配置OpenPCDet时我强烈建议使用Anaconda创建专属Python环境。这是我验证过的依赖组合conda create -n openpcdet python3.7 conda install pytorch1.10.0 torchvision0.11.0 torchaudio0.10.0 cudatoolkit11.3 -c pytorch pip install spconv-cu113 numpy1.19.5 numba scikit-learn2. KITTI数据集实战全流程2.1 数据目录结构搭建很多新手在摆放KITTI数据集目录时容易出错这里给出经过验证的标准结构OpenPCDet ├── data │ ├── kitti │ │ ├── ImageSets │ │ │ ├── test.txt │ │ │ ├── train.txt │ │ ├── testing │ │ │ ├── calib │ │ │ ├── image_2 │ │ │ ├── velodyne │ │ ├── training │ │ │ ├── calib │ │ │ ├── image_2 │ │ │ ├── label_2 │ │ │ ├── velodyne特别注意ImageSets下的txt文件只需包含文件名前缀如000001不要带后缀和路径。2.2 数据预处理关键步骤执行预处理命令时我建议先检查kitti_dataset.yaml中的路径配置DATA_PATH: ../data/kitti INFO_PATH: ../data/kitti/kitti_infos_ ... POINT_CLOUD_RANGE: [0, -40, -3, 70.4, 40, 1] # 需根据实际点云范围调整预处理命令运行后应该生成以下关键文件gt_database/ ├── Car_xxxx.bin ├── Pedestrian_xxxx.bin kitti_infos_train.pkl kitti_infos_val.pkl kitti_dbinfos_train.pkl2.3 训练与可视化技巧启动训练时Windows用户要特别注意worker数量设置python train.py --cfg_file cfgs/kitti_models/pointpillar.yaml --batch_size2 --epochs50 --workers0实测发现Windows下多worker容易引发共享内存错误设置workers0可避免。可视化预测结果时这个命令组合我经常用# 生成测试结果 python test.py --cfg_file cfgs/kitti_models/pointpillar.yaml --ckpt ../output/ckpt/checkpoint_epoch_50.pth # 可视化单个点云 python demo.py --cfg_file cfgs/kitti_models/pointpillar.yaml --data_path ../data/kitti/testing/velodyne/000123.bin --ckpt ../output/ckpt/checkpoint_epoch_50.pth3. 自定义数据集适配实战3.1 数据格式转换技巧处理自定义数据集时最常见的需求是将PLY/PCD转为KITTI标准的bin格式。这里分享我整理的Python转换代码import numpy as np from plyfile import PlyData def ply_to_bin(ply_path, bin_path): ply PlyData.read(ply_path) vertex ply[vertex] points np.vstack([vertex[x], vertex[y], vertex[z]]).T points.astype(np.float32).tofile(bin_path)对于标注数据需要特别注意坐标系的转换。假设原始标注是(x,y,z,l,w,h,θ)格式转换为KITTI格式时需要将长宽高顺序改为(h,w,l)将z坐标从几何中心调整到底面中心z z - h/2角度θ需要转换为KITTI的heading定义3.2 关键配置文件修改创建custom_dataset.yaml时这些参数必须仔细检查CLASS_NAMES: [Car, Pedestrian] # 必须与标注类别完全一致 POINT_CLOUD_RANGE: [0, -40, -3, 70.4, 40, 1] # 根据实际场景调整 DATA_SPLIT: {train: [], test: []} # 留空会自动划分模型配置文件如pointrcnn.yaml需要同步修改CLASS_NAMES: [Car, Pedestrian] NUM_POINT_FEATURES: 4 # xyzintensity3.3 自定义数据集类实现在pcdet/datasets/custom/下创建custom_dataset.py核心是重写三个方法def __len__(self): return len(self.sample_id_list) def __getitem__(self, index): # 加载点云和标注 points self.get_lidar(index) annos self.get_label(index) # 数据增强 data_dict self.prepare_data(points, annos) return data_dict def get_label(self, index): label_file os.path.join(self.root_path, label_2, f{index:06d}.txt) return kitti_utils.get_objects_from_label(label_file)4. 典型报错与解决方案4.1 road_plane相关错误处理遇到KeyError: road_plane时需要修改三处代码kitti_dataset.yaml中设置USE_ROAD_PLANE: false注释data_augmentor.py中所有road_plane相关代码在database_sampler.py中移除road_plane处理逻辑4.2 replaceFalse采样错误这个错误通常发生在点云采样阶段修改data_processor.py的采样逻辑# 原始代码 extra_choice np.random.choice(choice, num_points-len(points), replaceFalse) # 修改为 try: extra_choice np.random.choice(choice, num_points-len(points), replaceFalse) except ValueError: extra_choice np.random.choice(choice, num_points-len(points), replaceTrue)4.3 评估时的零除错误ZeroDivisionError往往源于数据路径不匹配检查custom_dataset.yaml中的INFO_PATH设置生成的pkl文件前缀是否与配置一致数据集划分文件是否为空5. 标注工具与格式转换使用point-cloud-annotation-tool标注时建议直接输出KITTI兼容格式。如果已有标注数据这个Python脚本可以完成格式转换def convert_annotation(label_path): with open(label_path) as f: lines [line.strip().split() for line in f] new_lines [] for line in lines: cls line[0] x,y,z map(float, line[1:4]) l,w,h map(float, line[4:7]) angle float(line[7]) # 转换为KITTI格式 new_line f{cls} 0 0 0 {h} {w} {l} {x} {y-0.5*h} {z} {angle} 0 0 0 0 0 0 0 new_lines.append(new_line) return \n.join(new_lines)在Windows环境下处理大量文件时建议用多进程加速from multiprocessing import Pool def batch_convert(paths): with Pool(4) as p: # 4进程并行 p.map(convert_annotation, paths)

更多文章