☰
MMDetection3D LiDAR 3D 目标检测实战:以 PointPillars + KITTI 为例的数据准备、训练、评估与可视化
2026/10/8 8:16:34 网站建设 项目流程
  • 人工智能
  • 计算机视觉
  • 深度学习
  • 自动驾驶

【免费下载链接】mmdetection3d

OpenMMLab's next-generation platform for general 3D object detection.

项目地址:https://gitcode.com/gh_mirrors/mm/mmdetection3d
点击查看免费下载

本文是 MMDetection3D 中 LiDAR-based 3D 检测(点云 3D 目标检测)任务的完整实战指南。我们将以 PointPillars 模型在 KITTI 数据集上的标准流程为主线,逐步讲解数据准备、分布式训练、定量评估、在线测试提交与可视化验证的完整链路。读完本文,你将能够独立完成一个点云 3D 检测模型的从数据到部署评估的全流程,并理解背后各环节的源码实现原理。

LiDAR 3D 检测任务概述

LiDAR-based 3D detection 是 MMDetection3D 支持的最基础任务之一。该任务要求模型以激光雷达采集的任意数量点云(每个点通常携带 x、y、z 坐标与反射强度等特征)作为输入,为每个感兴趣目标预测 3D 边界框(位置、尺寸、朝向)与类别标签。

从仓库代码结构看,该任务的核心实现覆盖了 检测器(detectors)、点云骨干网络(backbones)、3D 密集检测头(dense_heads) 与 3D 边界框数据结构(structures/bbox_3d) 等多个模块。PointPillars 是最具代表性的入门模型之一,其配置位于 PointPillars 配置目录,对应的 KITTI 三类别(Pedestrian / Cyclist / Car)完整配置为 pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py,下文所有实操均以该配置为例展开。

数据准备:从原始 KITTI 数据到标准目录与信息文件

第一步:下载原始数据并组织目录

首先需要下载 KITTI 3D 检测原始数据(包括velodyne点云、calib标定文件、image_2图像与label_2标注),并按 数据准备文档 中给出的标准方式重组目录。注意:KITTI 数据集还需要额外的.txt分割文件(ImageSets),用于划分 train / val / test 子集。

数据分割文件的准备方式如下(详见 数据准备文档):

mkdir ./data/kitti/ && mkdir ./data/kitti/ImageSets # 下载 4 个分割文件(test / train / val / trainval) wget -c ... -O ./data/kitti/ImageSets/test.txt wget -c ... -O ./data/kitti/ImageSets/train.txt wget -c ... -O ./data/kitti/ImageSets/val.txt wget -c ... -O ./data/kitti/ImageSets/trainval.txt

此外,也可以使用mim download mmdet3d --dataset kitti一键下载并预处理数据(需要先安装 OpenDataLab CLI 并登录)。

第二步:用 create_data.py 生成数据信息文件

由于不同数据集的原始数据组织方式差异较大,MMDetection3D 通常需要用一个.pkl文件统一收集有用的数据信息。原始数据就绪后,需要运行 tools/create_data.py 中对应数据集的脚本生成 data infos。对 KITTI 而言,命令为:

python tools/create_data.py kitti --root-path ./data/kitti --out-dir ./data/kitti --extra-tag kitti

从 tools/create_data.py 的源码可以看到,kitti_data_prep内部依次完成四件事:

  1. 调用kitti.create_kitti_info_file依据 ImageSets 分割生成 train / val / trainval / test 四份 infos pkl;
  2. 调用kitti.create_reduced_point_cloud生成velodyne_reduced(采样降密后的点云,KITTI 官方评估仅使用降密点云的前 100 行左右的点);
  3. 调用update_pkl_infos将 infos 升级为 v2 格式(兼容 MMDetection3D 新版数据结构);
  4. 调用create_groundtruth_database构建 GT 数据库(用于训练期的ObjectSample数据增强)。

命令中三个参数的含义为:--root-path指定原始数据根目录,--out-dir指定 pkl 输出目录,--extra-tag指定 infos 文件名的前缀(此处为kitti)。若环境使用 slurm 调度,可改用sh tools/create_data.sh <partition> kitti。

第三步:核对生成后的目录结构

命令执行完毕后,data/kitti下应包含如下结构(与 数据准备文档 描述一致):

mmdetection3d ├── mmdet3d ├── tools ├── configs ├── data │ ├── kitti │ │ ├── ImageSets │ │ ├── testing │ │ │ ├── calib │ │ │ ├── image_2 │ │ │ ├── velodyne │ │ │ ├── velodyne_reduced │ │ ├── training │ │ │ ├── calib │ │ │ ├── image_2 │ │ │ ├── label_2 │ │ │ ├── velodyne │ │ │ ├── velodyne_reduced │ │ ├── kitti_gt_database │ │ ├── kitti_infos_train.pkl │ │ ├── kitti_infos_trainval.pkl │ │ ├── kitti_infos_val.pkl │ │ ├── kitti_infos_test.pkl │ │ ├── kitti_dbinfos_train.pkl

其中kitti_infos_*.pkl记录每帧数据的点云路径、标定参数、图像信息与 3D/2D 标注,训练时由 KittiDataset 加载;kitti_gt_database与kitti_dbinfos_train.pkl则用于训练期的 GT 采样增强(对应配置中的db_sampler)。如果你不需要重新生成、也可以直接下载仓库提供的现成标注文件放置到data/kitti/;但若要使用ObjectSample增强,仍需额外执行--only-gt-database模式生成 GT 数据库:

python tools/create_data.py kitti --root-path ./data/kitti --out-dir ./data/kitti --extra-tag kitti --only-gt-database

训练:以 PointPillars 配置启动分布式训练

单机多卡启动命令

数据就绪后,即可用仓库提供的配置训练 PointPillars。不同 GPU 规模的训练方式可参考 训练与测试教程。假设我们在单机 8 卡上进行分布式训练:

./tools/dist_train.sh configs/pointpillars/pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py 8

dist_train.sh 内部通过python -m torch.distributed.launch启动 tools/train.py,支持通过环境变量NNODES、NODE_RANK、PORT、MASTER_ADDR扩展多机训练。

理解配置:8xb6、学习率与自动缩放

配置名中的8xb6表示训练使用8 张 GPU、每张 GPU 上 6 个样本(batch size = 6)。如果你的自定义设置与此不同,通常需要相应调整学习率——基本经验规则可参考论文《Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour》(arXiv:1706.02677)。MMDetection3D 已支持--auto-scale-lr参数自动缩放学习率:从 tools/train.py 的源码可以看到,该参数会读取配置中的auto_scale_lr.enable与auto_scale_lr.base_batch_size字段并据此自动推算新的学习率。

以当前配置 pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py 为例,其关键训练设置包括:

  • 学习率与调度:lr = 0.001,epoch_num = 80,采用两段式CosineAnnealingLR(前 40% epoch 以eta_min = lr * 10退火,后 60% 退火到lr * 1e-4),并配套CosineAnnealingMomentum;
  • epoch 数:虽然train_cfg = dict(by_epoch=True, max_epochs=80),但训练数据加载器外层套了RepeatDataset(times=2),因此实际训练 160 epochs(这正是配置名中160e的来源);
  • 验证间隔:train_cfg = dict(by_epoch=True, max_epochs=epoch_num, val_interval=2),即每 2 个 epoch 在验证集上评估一次;
  • 梯度裁剪:optim_wrapper = dict(optimizer=dict(lr=lr), clip_grad=dict(max_norm=35, norm_type=2)),注释说明对 PointPillars 而言max_norm=35略优于 10;
  • 类别与点云范围:class_names = ['Pedestrian', 'Cyclist', 'Car'],point_cloud_range = [0, -39.68, -3, 69.12, 39.68, 1](x/y/z 的前后边界)。

数据增强管线(train_pipeline)

训练管线定义在同一配置中,依次执行:

  • LoadPointsFromFile:加载 LiDAR 点云,load_dim=4, use_dim=4(x, y, z, intensity);
  • LoadAnnotations3D:加载 3D 框与标签;
  • ObjectSample:基于db_sampler从kitti_dbinfos_train.pkl中采样 GT 点云做增强,其中sample_groups=dict(Car=15, Pedestrian=15, Cyclist=15)表示每个类别的采样目标数量(注意:PointPillars 的 KITTI 配置在基类 kitti-3d-3class.py 基础上调整了各类别的采样策略);
  • RandomFlip3D:BEV 水平翻转概率 0.5;
  • GlobalRotScaleTrans:全局旋转 ±45°、缩放 0.95~1.05;
  • PointsRangeFilter/ObjectRangeFilter:过滤超出point_cloud_range的点与框;
  • PointShuffle:打乱点序;
  • Pack3DDetInputs:打包为模型输入。

模型结构速览

PointPillars 的模型定义见 pointpillars_hv_secfpn_kitti.py,主干为VoxelNet架构:

  • 体素化:voxel_size = [0.16, 0.16, 4](x/y 方向 0.16m、z 方向 4m),max_points_per_voxel=32,max_voxels=(16000, 40000)(训练/测试上限);
  • 体素编码器:PillarFeatureNet(pillar 特征提取,输入 4 通道,输出 64 维特征);
  • 中间编码器:PointPillarsScatter,将 pillar 特征散射回伪图像,输出尺寸[496, 432];
  • 骨干网络:SECOND(3 层下采样,通道 64→128→256);
  • 颈部:SECONDFPN(上采样融合,输出 128 维);
  • 检测头:Anchor3DHead,使用三类 anchor(Pedestrian 尺寸[0.8, 0.6, 1.73]、Cyclist[1.76, 0.6, 1.73]、Car[3.9, 1.6, 1.56],旋转角 0 与 1.57),并针对每个类别配置不同的Max3DIoUAssigner正负样本阈值(Car 的pos_iou_thr=0.6,Pedestrian/Cyclist 为 0.5);测试阶段使用use_rotate_nms=True、nms_thr=0.01、score_thr=0.1、max_num=50。

定量评估:理解 KITTI 官方评估协议

训练期间的定期评估

训练过程中,模型检查点会根据配置中的train_cfg = dict(val_interval=xxx)定期在验证集上评估。MMDetection3D 对不同的数据集支持各自的官方评估协议。对 KITTI 而言,评估协议为:对 3 个类别分别计算 mAP(mean Average Precision),IoU 阈值分别为 0.5 / 0.7,且按 easy / moderate / hard 三档难度分别报告。

评估核心由 KittiMetric 实现,它注册为type='KittiMetric',其关键构造参数包括:

  • ann_file:验证/测试集标注 pkl 路径;
  • metric:评估指标,默认'bbox',允许取值为bbox、img_bbox、mAP、LET_mAP;
  • pcd_limit_range:点云范围过滤阈值,用于剔除无效预测框,默认[0, -40, -3, 70.4, 40, 0.0];
  • pklfile_prefix:结果 pkl 的保存前缀;
  • format_only:仅格式化结果不计算指标(用于提交);
  • submission_prefix:提交文件的保存目录前缀;
  • default_cam_key:默认相机(KITTI 为'CAM2'),用于 LiDAR 到相机的坐标转换与 2D 框投影。

在kitti_evaluate中,对 3D 预测默认计算bbox / bev / 3d三类 AP(2D 框、BEV 鸟瞰框、3D 框),评估结果会打印在命令行,形如:

Car AP@0.70, 0.70, 0.70: bbox AP:98.1839, 89.7606, 88.7837 bev AP:89.6905, 87.4570, 85.4865 3d AP:87.4561, 76.7569, 74.1302 aos AP:97.70, 88.73, 87.34 Car AP@0.70, 0.50, 0.50: bbox AP:98.1839, 89.7606, 88.7837 bev AP:98.4400, 90.1218, 89.6270 3d AP:98.3329, 90.0209, 89.4035 aos AP:97.70, 88.73, 87.34

其中AP@0.70, 0.70, 0.70行对应 easy / moderate / hard 三档难度在 IoU 0.7 下的 Car AP,第二行AP@0.70, 0.50, 0.50对应 BEV / 3D 评估放宽到 IoU 0.5 的 Car 指标;aos为朝向相似度指标。

训练完成后的独立评估

训练结束后,也可以单独评估某个检查点,直接运行:

./tools/dist_test.sh configs/pointpillars/pointpillars_hv_secfpn_8xb6-160e_kitti-3d-3class.py work_dirs/pointpillars/latest.pth 8

dist_test.sh的用法为dist_test.sh <config> <checkpoint> <gpus>,其内部同样基于torch.distributed.launch启动 tools/test.py。注意默认配置中验证集与测试集都指向kitti_infos_val.pkl(见 kitti-3d-3class.py),因此上述命令评估的是验证集指标。

测试与在线提交:生成 KITTI 官方格式的预测结果

如果你只想做纯推理,或将模型性能提交到 KITTI 在线评估服务器(需要模型在测试集上预测),则需要为对应的评估器指定submission_prefix。例如在配置中加入:

test_evaluator = dict( type='KittiMetric', ann_file=data_root + 'kitti_infos_test.pkl', format_only=True, pklfile_prefix='results/kitti-3class/kitti_results', submission_prefix='results/kitti-3class/kitti_results')

配置要点:

  1. format_only=True:只格式化输出、不执行本地评估。从 kitti_metric.py 的源码可以看到,format_only=True时强制要求submission_prefix非空,否则结果会被保存到临时目录并在结束时被清理;
  2. ann_file必须指向测试集:请确保配置中的data_prefix与ann_file与测试集对应(参考 kitti-3d-3class.py 中test_dataloader的写法),即ann_file='kitti_infos_test.pkl'、data_prefix=dict(pts='testing/velodyne_reduced'),而不是验证集;
  3. 生成的文件格式:从 bbox2result_kitti 可以看到,每个测试样本会输出一个{sample_idx:06d}.txt文本文件,每行包含类别名、alpha、2D bbox、尺寸、位置、rotation_y与置信度,该格式与 KITTI 官方提交要求一致。

生成结果后,将结果文件夹压缩并上传到 KITTI 评估服务器即可获得官方打分。

定性验证:可视化检测结果与数据集

MMDetection3D 提供了丰富的可视化工具,便于直观感受训练模型的检测效果,共三条途径:

方式一:评估时在线可视化(--show)

在运行 tools/test.py 时添加--show选项,即可在评估过程中实时可视化预测结果。从 tools/test.py 的源码可以看到,--show会激活default_hooks中的VisualizationHook,并联动以下参数:

  • --show-dir:指定保存可视化结果的目录;
  • --task:可视化任务类型,LiDAR 3D 检测对应lidar_det;
  • --score-thr:框分数阈值(默认 0.1);
  • --wait-time:每帧显示间隔(默认 2 秒)。

方式二:离线可视化(visualize_results.py)

也可以先保存预测结果,再使用 tools/misc/visualize_results.py 做离线可视化:

python tools/misc/visualize_results.py <config> --result <结果.pkl> --show-dir <输出目录>

该脚本加载指定 pkl 结果,通过数据集的show方法逐帧绘制(--result必须是.pkl文件,且测试配置中需设置test_mode=True)。

方式三:无需推理的数据集浏览(browse_dataset.py)

仓库还提供了 tools/misc/browse_dataset.py 脚本,无需任何模型推理即可直接可视化数据集本身(点云、GT 框与标注),常用参数包括:

  • --output-dir:无显示界面时保存可视化结果;
  • --task:任务类型(如lidar_det);
  • --aug:可视化增强后的数据(走训练管线)而非原始数据;
  • --show-interval:显示间隔(秒)。

更完整的可视化用法可参考 可视化文档。

小结

本文以 PointPillars + KITTI 三类别检测为完整示例,走通了 LiDAR 3D 检测的标准工作流:数据准备(ImageSets 分割 +create_data.py生成 infos 与 GT 数据库)→ 分布式训练(dist_train.sh+ 8xb6 配置解读)→ 定量评估(KittiMetric 与 mAP/IoU 协议)→ 测试提交(format_only+submission_prefix生成官方格式结果)→ 定性验证(三类可视化工具)。

对读者而言,理解这套流程后可以轻松迁移到仓库中其他 LiDAR 检测模型(如 SECOND、CenterPoint、PartA2、PV-RCNN、SASSD 等,见 configs 目录),因为它们在数据准备、评估与可视化环节共享同一套基础设施;不同之处仅在于各自配置中的模型结构、数据增强管线与训练调度策略。更多数据集(nuScenes、Waymo、Lyft 等)的 LiDAR 检测配置也可在 configs/base/datasets 中找到对应基类,按本文流程举一反三即可。

  • 人工智能
  • 计算机视觉
  • 深度学习
  • 自动驾驶

【免费下载链接】mmdetection3d

OpenMMLab's next-generation platform for general 3D object detection.

项目地址:https://gitcode.com/gh_mirrors/mm/mmdetection3d
点击查看免费下载

相关推荐

上一篇:Podman 构建镜像的 `--disable-compression` 选项:默认不压缩的机制与实战用法
下一篇:uni-app 应用市场上架全指南:审核规则、资质准备与合规打包发布

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询