项目地址:https://github.com/ADLab-AutoDrive/BEVHeight#
项目文件结构

BEVHeight-main/
├── assets/ # 资源文件目录
│ └── teaser_intro.jpg # 项目介绍图片
├── data/ # 数据目录
│ ├── rope3d/ # Rope3D数据集
│ ├── rope3d-kitti/ # 转换后的KITTI格式数据
│ └── single-infrastructure-split-data.json # 单基础设施数据划分
Rope3D数据集 是一个专门用于 路侧单目3D物体检测 的大规模数据集,专门针对路侧摄像头视角的3D物体检测,支持100-140米范围内的车辆和行人检测
KITTI格式 是自动驾驶领域最常用的 标准化3D检测数据格式,好处是可以标准化评估和代码复用
single-infrastructure-split-data.json # 单基础设施数据划分
定义了训练集、验证集和测试集的数据划分,确保每次实验使用相同的数据分配
JSON格式便于程序读取和人工查看,支持复杂数据结构。
├── dataset/
│ └── nusc_mv_det_dataset.py # 数据集处理 - NuScenes多视角检测数据集
│ ├── NuscMVDetDataset类 (1-767行) # 数据集加载和预处理
│ ├── 数据增强函数 (100-300行) # 图像变换、BEV变换等数据增强
│ ├── 相机参数处理 (300-500行) # 相机内外参转换
│ └── 数据加载逻辑 (500-767行) # 批量数据加载和转换
NuScenes数据集是自动驾驶领域的大规模多传感器数据集,包含1000个驾驶场景,每个场景有6个摄像头、激光雷达、雷达等传感器数据,提供3D物体检测、跟踪等任务标注。
├── docs/ # 文档目录
│ ├── install.md # 安装指南:Docker镜像、PyTorch安装、依赖配置(1-27行)
│ ├── prepare_dataset.md # 数据集准备:DAIR-V2X-I/Rope3D下载、格式转换、可视化(1-63
│ └── run_and_eval.md # 运行评估:训练测试命令、GPU配置(1-11行)
Docker镜像是一个轻量级的、可执行的软件包,包含运行应用所需的一切:代码、运行时环境、系统工具、库和设置。它让应用在任何环境下都能以相同方式运行。
Docker镜像是Docker技术的核心组件。Docker是一个容器化平台,而镜像就是用来创建容器的模板。
依赖配置 就是指项目运行所需要的第三方库和软件包。
这两个数据集是BEVHeight项目专门针对 路侧单目3D检测 的核心数据集:
DAIR-V2X-I :车路协同数据集,包含路侧摄像头数据,用于验证模型在真实路侧场景的性能。
Rope3D :专门的路侧3D检测数据集,提供远距离检测挑战,是评估路侧BEV感知能力的关键基准。
一个侧重车路协同,一个专注路侧检测
车路协同:指车辆和路侧设备(如摄像头)协同工作,DAIR-V2X-I包含车端和路侧数据,研究两者如何配合提升感知能力。
路侧检测:仅使用路侧摄像头进行检测,Rope3D专注路侧单视角,研究路侧设备独立完成检测任务的能力。
简单说:一个研究"车+路"配合,一个研究"路"单独工作。
├── evaluators/
│ ├── det_evaluators.py # 检测评估器 - 模型性能评估
│ │ ├── RoadSideEvaluator类 (1-237行) # 路侧场景评估器
│ │ ├── 结果格式转换 (50-150行) # 将检测结果转换为KITTI格式
│ │ └── 评估指标计算 (150-237行) # 计算3D检测指标
│ ├── kitti_utils/ # KITTI格式评估工具
│ │ ├── eval.py # KITTI评估主程序
│ │ ├── kitti_common.py # KITTI数据格式处理
│ │ └── rotate_iou.py # 旋转IOU计算
│ └── result2kitti.py # 结果转KITTI格式
evaluators文件夹是模型评估器。
主要功能包括:
- 计算3D检测精度指标(如mAP)
- 将模型预测结果转换为标准格式
- 生成评估报告和可视化结果
RoadSideEvaluator类是专门用于路侧场景的评估器。
需要这个类的原因:
- 路侧检测与车端检测不同,需要专门的评估标准
- 路侧视角有独特的挑战,如远距离检测、遮挡问题
- 需要针对路侧数据集(如Rope3D、DAIR-V2X-I)设计专门的评估指标
- 确保模型在路侧场景下的性能评估准确可靠
转换为KITTI格式是为了使用标准评估工具进行性能比较。
3D检测指标主要包括mAP(平均精度)、AP(各类别精度)、AOS(方向相似度)等。
mAP是平均精度,衡量整体检测准确率。AP是各类别精度,如车辆、行人等。AOS评估方向预测准确性。AOS是评估检测框方向预测准确性的指标。它衡量预测的车辆朝向与真实朝向的相似度,对自动驾驶很重要,因为车辆行驶方向影响决策。
这个kitti_utils文件夹包含项目自定义的KITTI格式处理工具。虽然KITTI有官方评估工具,但项目需要适配自己的数据结构和需求,所以开发了专门的工具来处理格式转换和评估。
rotate_iou.py是计算旋转IOU的工具。它专门用于计算带方向的3D检测框之间的重叠度,比普通IOU更准确,因为考虑了车辆朝向。
IOU是检测框重叠度,衡量位置准确性。AOS是方向相似度,衡量方向准确性。IOU看"位置对不对",AOS看"方向对不对",两者互补评估3D检测性能。
IOU衡量的是预测框和真实框在空间上的重叠程度。具体来说,它计算两个框相交面积与并集面积的比值,数值在0-1之间。1表示完全重合,0表示完全不重合。这反映了模型定位物体的准确程度。
├── exps/
│ ├── dair-v2x/ # DAIR-V2X数据集实验配置
│ │ ├── bev_height_lss_r50_864_1536_128x128_102.py # R50骨干网络,102米检测范围
│ │ ├── bev_height_lss_r50_864_1536_128x128_140.py # R50骨干网络,140米检测范围
│ │ ├── bev_height_lss_r101_864_1536_256x256_102.py # R101骨干网络,102米检测范围
│ │ └── bev_height_lss_r101_864_1536_256x256_140.py # R101骨干网络,140米检测范围
│ └── rope3d/ # Rope3D数据集实验配置
│ ├── bev_height_lss_r50_864_1536_128x128_102.py # R50骨干网络配置
│ ├── bev_height_lss_r50_864_1536_128x128_140.py # R50骨干网络配置
│ ├── bev_height_lss_r101_864_1536_256x256_102.py # R101骨干网络配置
│ └── bev_height_lss_r101_864_1536_256x256_140.py # R101骨干网络配置
骨干网络是深度学习模型的基础特征提取器。R50和R101是ResNet的不同深度版本,数字越大网络越深,特征提取能力越强但计算量也越大。项目配置不同骨干网络是为了比较不同复杂度模型在路侧检测任务上的性能差异。
骨干网络从输入图像中提取视觉特征。它通过多层卷积操作处理图像像素,逐步提取从边缘、纹理等低级特征到物体部件、整体形状等高级特征。这些特征以多维张量形式表示,包含空间位置信息和语义信息,用于后续的3D检测任务。
每个卷积核就像一个特征模板。不同的卷积核专门检测不同特征:有的检测边缘,有的检测纹理,有的检测特定形状。通过多层卷积组合,网络能逐步提取从简单到复杂的视觉特征。
四个配置组合是为了:
1 比较不同网络深度对检测性能的影响
2 测试不同检测范围下的模型表现
骨干网络是可复用的通用组件。R50就是ResNet-50,这是一个非常成熟和广泛使用的特征提取网络。
项目配置R50和R101就是为了利用这些成熟的网络架构,专注于解决路侧3D检测这个特定问题。
这种双数据集设计是为了:
1 比较车路协同与纯路侧检测的性能差异
2 验证模型在不同应用场景下的通用性
├── layers/
│ ├── backbones/
│ │ └── lss_fpn.py # 骨干网络 - LSS+FPN特征提取,包含高度预测机制(核心创新)
│ │ ├── LSSFPN类 (1-535行) # 骨干网络主类,实现2D到3D特征转换
│ │ ├── HeightNet类 (200-300行) # 高度预测网络,核心创新点
│ │ ├── ASPP模块 (30-100行) # 空洞空间金字塔池化,增强特征提取
│ │ └── 体素池化调用 # 调用ops/voxel_pooling/voxel_pooling.py
│ └── heads/
│ └── bev_height_head.py # 检测头 - 在BEV空间进行3D物体检测
│ ├── BEVHeightHead类 (1-311行) # 检测头主类,继承自CenterHead
│ ├── 热图生成机制 (100-200行) # 生成3D检测热图
│ ├── 损失计算 (200-250行) # 计算分类和回归损失
│ └── 边界框解码 (250-311行) # 从热图解码3D边界框
layers文件夹 :包含模型的基础组件
models文件夹 :包含完整的模型架构
layers文件夹把模型的各个部分分开写,这样逻辑更清晰。models文件夹负责把这些部分组装起来。
LSS(Lift, Splat, Shoot) :将2D图像特征提升到3D空间的方法 FPN(特征金字塔网络) :多尺度特征提取,处理不同大小的物体
为什么有骨干网络 :
1 LSS+FPN组合构成了项目的核心特征提取器
2 这个骨干网络专门针对路侧单目3D检测任务设计
3 包含高度预测机制,是项目的核心创新点
1 LSS如何将2D特征提升到3D LSS通过预测每个像素的深度分布,将2D图像特征投影到3D空间,形成鸟瞰图特征。
LSS的投影原理:
- 深度预测的本质 :LSS不是直接预测绝对深度值,而是预测每个像素的深度分布概率。在
lss_fpn.py中, HeightNet 模块负责预测每个像素在不同深度层上的概率分布。- 视锥体构建 :在 create_frustum 方法中,LSS构建了一个3D视锥体,将图像平面上的每个像素沿着深度方向扩展成多个3D点。这就像从相机位置向外发射射线,每个射线对应图像中的一个像素。
- 2D到3D的转换 :通过预测的深度分布,LSS知道每个像素在3D空间中的可能位置。在 get_geometry 方法中,使用相机内参矩阵和变换矩阵,将2D图像坐标转换为3D世界坐标。
2 为什么叫特征金字塔结构 FPN通过不同分辨率的多层特征融合,形成金字塔状结构,可以同时检测大物体和小物体。
1 为什么叫金字塔结构? FPN通过不同分辨率的特征层构建了一个金字塔形状的特征层次:
- 底层特征 :高分辨率(如1/4原图大小),包含丰富的细节信息
- 中层特征 :中等分辨率(如1/8原图大小),平衡细节和语义
- 高层特征 :低分辨率(如1/16原图大小),包含强语义信息
3 为什么有两个骨干网络
1 ResNet是通用图像特征提取器
2 LSS+FPN是专门针对3D检测的骨干网络,负责2D到3D的转换
什么是体素(Voxel)?
体素是3D空间中的像素 :
- 像素(Pixel) :二维图像中的最小单位,有(x,y)坐标
- 体素(Voxel) :三维空间中的最小单位,有(x,y,z)坐标
体素的特点 :
- 将3D空间划分为规则的立方体网格
- 每个体素包含位置信息和特征信息
- 类似于2D图像中的像素,但多了深度维度
体素池化 3D空间中的体素进行下采样操作
BEV(Bird’s Eye View)空间 就是 鸟瞰图空间 ,也就是从正上方俯视的视角。
检测头(Detection Head) 是深度学习模型中的一个标准术语,指的是:
模型架构的一部分 :在骨干网络(Backbone)提取特征后,检测头负责具体的检测任务
BEV空间将3D深度信息编码在特征图通道中,在统一坐标系下直接检测,避免了多视角融合的复杂性。
深度信息被编码在特征图的通道维度中,每个通道存储不同高度的特征,2D平面只保留空间位置。
特征图是4维的:(批次, 通道, 高度, 宽度)
通道维度:每个通道对应不同高度的特征,就像彩色图像的RGB三通道分别存储红、绿、蓝信息一样,BEV特征图的多个通道分别存储不同高度的3D信息。
2D平面 (高度×宽度)处理空间位置 通道维度 存储不同高度的深度信息
这样虽然处理的是2D图像,但通过通道保留了3D深度信息。
热图(Heatmap)是用来预测物体中心位置的。在BEVHeight中,热图的作用是:
功能:在BEV空间的每个位置预测该处存在物体的概率
作用:高亮显示物体可能存在的区域,帮助模型快速定位3D物体中心点
简单说:热图就是一张"概率地图",告诉模型"这里可能有车"。
这里的"分类和回归损失"是3D物体检测任务中的核心损失函数:
分类损失:判断每个位置是否有物体,以及是什么类别的物体(如车辆、行人等)
回归损失:预测物体的具体位置、尺寸、朝向等3D属性(如x,y,z坐标,长宽高,旋转角度)
简单说就是:分类损失告诉模型"这是什么",回归损失告诉模型"它在哪里、有多大"。两者结合才能完成完整的3D检测任务。
热图预测的是物体中心点的概率,而3D边界框是完整的物体描述。
边界框解码的作用:将热图中的概率峰值(物体中心点)转换为完整的3D边界框,包含:
- 位置(x,y,z坐标)
- 尺寸(长宽高)
- 朝向(旋转角度)
简单说:热图告诉你"物体中心可能在哪儿",边界框解码告诉你"这个物体有多大、朝向哪里",两者结合才能得到完整的3D检测结果。
├── models/
│ └── bev_height.py # 主模型架构 - 整合骨干网络、检测头和体素池化,实现完整前向传播
│ ├── BEVHeight类 (1-110行) # 主模型类,包含forward()、get_targets()、loss()、
前向传播就是模型从输入到输出的完整计算过程。在BEVHeight模型中,前向传播具体包括:图像特征提取、体素池化将2D特征投影到3D空间、BEV特征处理、热图生成和边界框解码,最终输出3D检测结果。
forward()函数负责前向传播计算,从图像输入到3D检测结果的完整流程都在这里实现;get_targets()函数为训练准备标签数据,将真实3D边界框转换为热图和回归目标;loss()函数计算模型预测与真实值之间的误差,包括分类损失和回归损失;get_bboxes()函数在推理时从热图中解码出最终的3D边界框结果。
├── ops/
│ └── voxel_pooling/
│ ├── voxel_pooling.py # 体素池化 - 核心创新技术,实现2D到3D特征转换
│ │ ├── VoxelPooling类 (1-72行) # 体素池化前向和反向传播
│ │ ├── 几何坐标转换 (20-40行) # 将2D特征映射到3D体素空间
│ │ └── 特征聚合机制 (40-60行) # 在体素空间聚合特征
│ └── src/ # C++/CUDA加速实现
体素池化需要前向和反向传播是因为它参与模型的训练过程。前向传播负责将2D图像特征投影到3D体素空间生成BEV特征图,反向传播则计算梯度并更新模型参数,让模型学会如何正确地进行空间投影和特征聚合。
几何坐标转换是通过相机投影几何实现的。具体方法包括:使用相机内参将2D像素坐标反投影到3D空间,结合预测的高度信息确定每个像素的3D位置,然后将这些3D坐标映射到体素网格中,实现从2D图像空间到3D体素空间的转换。
高度信息是通过专门的高度预测网络来预测的,这个网络会为每个像素预测一个高度值。热图是用来预测物体中心位置的,而高度预测是单独的一个分支,两者是不同的任务。
深度信息是保留的,但高度信息是预测的 ,这两者并不矛盾:
- 深度信息保留 :指的是在2D到3D的转换过程中,原本在2D图像中的空间关系(远近关系)通过几何坐标转换被保留到了3D体素空间中。
- 高度信息预测 :指的是在单目视觉中,我们无法直接从2D图像知道物体的真实高度(z坐标),所以需要通过神经网络来预测这个高度值。(实际上二维空间转换到三维空间时保留的深度信息就是我们预测的高度值)
在体素空间聚合特征是因为:
为什么要聚合 :当2D图像特征通过几何坐标转换映射到3D体素空间时,同一个体素单元(3D空间中的小立方体)可能会接收到来自多个不同2D像素的特征。这些特征需要被聚合起来,形成一个统一的体素特征。
CUDA是NVIDIA开发的并行计算平台和编程模型,专门用于GPU加速计算。在BEVHeight中使用CUDA加速实现是因为:
为什么需要加速 :体素池化操作涉及大量的3D坐标转换和特征聚合计算,这些计算在CPU上执行非常耗时。
CUDA的作用 :通过CUDA可以利用GPU的并行计算能力,将体素池化操作在GPU上并行执行,大幅提高计算速度。
CUDA不是模型,而是一个 编程平台和工具集 。它提供了一套API和编译器,让开发者能够编写在GPU上运行的并行计算程序。
NVIDIA(英伟达)是一家美国跨国科技公司,专门从事图形处理器(GPU)和人工智能计算技术
NVIDIA开发了CUDA平台,让GPU能够进行通用计算
├── scripts/
│ ├── data_converter/ # 数据转换脚本
│ │ ├── rope2kitti.py # Rope3D转KITTI格式 (1-215行)
│ │ ├── dair2kitti.py # DAIR-V2X转KITTI格式
│ │ └── visual_tools.py # 可视化工具
│ ├── gen_info_dair.py # 生成DAIR数据集信息
│ └── gen_info_rope3d.py # 生成Rope3D数据集信息
因为原始的DAIR数据集格式可能与BEVHeight模型要求的输入格式不一致,这个脚本起到了 数据适配器 的作用,确保模型能够正确读取和使用DAIR数据集进行训练和评估。
数据集的元数据(metadata)指的是 描述数据的数据
├── utils/
│ ├── backup_files.py # 代码备份工具
│ └── torch_dist.py # 分布式训练工具
代码中 backup_codebase(backup_folder) 函数接收一个参数 backup_folder ,说明备份位置是 用户指定的目录
orch_dist.py 是BEVHeight项目的多GPU训练协调器,它负责管理多个GPU之间的协同工作:识别每个GPU的身份和数量,确保所有GPU同步完成计算步骤,并汇总各GPU的计算结果
CUDA是硬件层面的并行计算平台 ,它提供了GPU并行计算的基础能力,但 不直接管理多GPU训练过程 。
torch_dist.py是软件层面的训练协调器 ,它基于PyTorch的分布式框架,专门解决多GPU训练中的 逻辑协调问题 :
├── setup.py # 项目安装配置
setup.py就是BEVHeight的"安装向导" ,负责把C++/CUDA高性能代码编译成Python可调用的模块
编译CUDA代码 → 变成Python可调用模块
项目打包 → 方便安装使用
├── train_script.sh # 训练脚本
train_script.sh 是BEVHeight项目的训练脚本, .sh是Shell脚本文件后缀 。
# 设置PyTorch缓存目录到当前目录
export TORCH_HOME=./$TORCH_HOME
# 训练命令:使用ResNet101,输入864×1536,输出256×256,训练140个epoch
# 使用8个GPU,每个GPU batch size为2,启用混合精度训练
python exps/dair-v2x/bev_height_lss_r101_864_1536_256x256_140.py --amp_backend native -b 2 --gpus 8
# 评估命令:加载训练好的模型进行测试
# -e参数表示评估模式,使用预训练权重文件
python exps/dair-v2x/bev_height_lss_r101_864_1536_256x256_140.py --ckpt outputs/bev_height_lss_r50_864_1536_128x128/checkpoints/ -e -b 2 --gpus 8
# 输入864×1536:图像分辨率(宽×高)
# 输出256×256:BEV鸟瞰图分辨率(网格大小)
python exps/dair-v2x/bev_height_lss_r101_864_1536_256x256_140.py
混合精度 :同时使用FP32(高精度)和FP16(低精度)
评估模式作用 :
- 测试训练好的模型在验证集上的表现
- 计算准确率、召回率等指标
- 不更新模型权重,只进行推理
- FP16负责计算 :前向传播、反向传播中的大规模矩阵运算
- FP32负责存储 :模型权重、梯度等关键参数的存储和更新>各自负责的部分不同

被折叠的 条评论
为什么被折叠?



