Radar Camera BEV融合技术对比:从投影对齐到查询驱动的范式演进 1. 项目概述为什么“Radar Camera BEV 技术对比”不是一张参数表而是一场感知范式的迁移你打开一篇标题叫《Radar Camera BEV 技术对比》的文章心里想的可能是“快给我列个表格RaCFormer、RCBEVDet、BEVFusion 各自 mAP 多少NDS 差多少谁快谁慢”——这很合理。但如果你真只看到一张表格那你就错过了过去三年自动驾驶感知领域最剧烈的一次底层重构。这不是在比谁的模型调参更细而是在回答一个根本问题当激光雷达LiDAR因成本和可靠性瓶颈难以成为标配时我们能否用毫米波雷达Radar和摄像头Camera这对“经济组合”在鸟瞰图BEV空间里重建出不输 LiDAR 的三维世界理解能力答案正在从“勉强可用”走向“可靠主力”而这场迁移的核心战场就藏在“Radar Camera BEV”这六个字的每一个技术断点里。Radar 和 Camera 是天性迥异的传感器。Camera 捕捉的是高分辨率、富含语义纹理的二维图像但它天生是“近视眼”——没有深度信息夜间、雨雾中性能断崖式下跌Radar 则是“远视夜视透视”三合一它能穿透雨雾、精确测量速度靠多普勒效应、在完全黑暗中工作但它输出的是稀疏、低分辨率、缺乏纹理的点云连一辆车是轿车还是SUV都很难分辨。过去的做法是把它们当成两个独立的“盲人”各自摸索世界再在某个中间层比如检测结果框上做简单投票或加权融合。这种“后融合”就像让两个只会说方言的人先各自写完报告再找翻译逐句对齐——效率低、错误多、关键信息早已丢失。BEVBird’s Eye View鸟瞰图的出现相当于给这两个盲人建了一张统一的、俯视的、坐标系对齐的“地图”。所有传感器数据无论原始形态如何都被强制“投影”到这张以自车为中心的二维平面地图上。图像特征通过“Lift-Splat-Shoot”这类方法把像素点沿着估计的深度“抬升”到3D空间再“泼洒”splat到BEV网格上雷达点云则直接按其(x,y)坐标“落点”到BEV网格。这样融合就从“报告对齐”变成了“地图共建”——大家在同一张纸上画逻辑上干净利落。但问题立刻浮现Camera 的 BEV 特征质量极度依赖深度估计的准确性。一个像素点该抬升到2米还是20米估错了它在BEV地图上的位置就偏了5米跟雷达点云对不上融合就是“牛头不对马嘴”。而 Radar 的 BEV 特征又太稀疏像一张只有几个墨点的草图无法支撑精细的物体识别。这就是当前所有 Radar-Camera BEV 融合方案的“阿喀琉斯之踵”。所以“Radar Camera BEV 技术对比”的本质不是比谁的网络更深、参数更多而是比谁更聪明地绕开了这个死结。RCBEVDet 提出 RadarBEVNet试图用专用网络“硬提”雷达特征让稀疏的点云也能表达出更多结构信息BEVFusionICRA 2023则走另一条路它不强求单模态特征完美而是设计了一个强大的、统一的 BEV 特征空间让 Camera 和 Radar 的特征在这个空间里“自然对齐”哪怕初始位置有偏差也能在后续的跨模态注意力中被动态修正。而 RaCFormer则彻底跳出了“先投影、再融合”的框架它引入了“查询Query”作为中介——这些 Query 就像一群训练有素的“侦察兵”它们不被动等待特征送上门而是主动出击一部分 Query 去 Camera 的原始图像里“挖”语义细节避开深度失真另一部分 Query 去 Radar 的 BEV 特征里“抓”运动线索利用多普勒还有一部分 Query 直接在 BEV 空间里“巡逻”寻找目标。整个过程是“跨视角、跨模态”的实时协同而非单向的投影与拼接。因此这篇对比我不会给你一张干巴巴的参数表。我会带你钻进这三套主流方案的“引擎舱”看它们如何设计各自的“动力总成”核心架构、如何解决最关键的“变速箱匹配”深度估计与特征对齐、如何应对真实世界的“复杂路况”雨雾、黑夜、遮挡。你会明白RaCFormer 的 64.9% mAP 不是靠堆算力得来的而是因为它把雷达的“远视夜视”能力精准地“嫁接”到了相机的“高清语义”之上让两者真正成为了彼此的“眼睛”和“耳朵”。这已经不是技术选型的问题而是定义下一代低成本、高鲁棒性自动驾驶感知系统的范式之争。2. 核心技术路线拆解从“投影对齐”到“查询驱动”的范式跃迁要真正理解 Radar-Camera BEV 融合的演进逻辑必须抛开“谁更好”的简单结论深入到每一套方案的“心脏”——它的核心架构设计哲学。这决定了它如何看待传感器、如何定义融合、以及最终能走多远。我们将以 RCBEVDet、BEVFusionICRA 2023和 RaCFormer 为锚点进行一场由表及里的解剖。2.1 RCBEVDet夯实雷达根基用“专用引擎”驱动稀疏点云RCBEVDet 的核心思想非常务实既然雷达 BEV 特征天生稀疏、信息量少那我们就别指望它能像图像那样“自带丰富语义”而是要为它打造一个专属的、高效的“特征提取引擎”。这个引擎的名字叫RadarBEVNet。它的设计逻辑是“扬长避短”。雷达最大的优势是什么是它对速度的精确测量多普勒效应和对距离的稳定感知。RCBEVDet 并没有试图去“无中生有”地生成雷达的纹理而是将雷达原始点云的 (x, y, z, velocity_x, velocity_y, RCS) 这些物理属性作为最核心的输入。它首先将雷达点云“柱状化”Pillarization即把 BEV 平面划分成一个个小方格Pillar每个 Pillar 内的所有雷达点被聚合处理。接着一个轻量级的 Pillar Feature NetworkPFN开始工作它不追求复杂的非线性变换而是专注于高效地编码每个 Pillar 内点的统计信息——比如平均速度、最大 RCS、点数密度等。最后通过简单的 max-pooling将这些 Pillar 特征“铺”成一张 BEV 特征图。提示RCBEVDet 的“融合”发生在 BEV 特征图层面。它将 Camera 经过 Lift-Splat-Shoot 得到的 BEV 特征图与 RadarBEVNet 输出的 BEV 特征图在通道维度上进行拼接Concatenation然后送入一个共享的 BEV 主干网络如 ResNet进行后续的检测头处理。这是一种典型的“早期融合”Early Fusion策略其成败高度依赖于两幅 BEV 图在空间上的严格对齐。这种设计的优势在于极致的简洁与高效。它没有引入任何复杂的跨模态交互模块计算开销小部署友好。在 nuScenes 数据集上它仅用 12 个 epoch 就能收敛证明了其工程落地的强大潜力。然而它的短板也源于此它对 Camera 的深度估计误差“零容忍”。如果 Lift-Splat-Shoot 过程中某个车道线的像素被错误地抬升到了 50 米外那么它在 BEV 图上就会与真实的雷达点云相距甚远拼接后的特征图上这两者的信息就是割裂的、无法被后续网络有效利用的。它本质上是在“加固雷达的短板”但并未触及“如何让相机和雷达真正‘看见’同一个东西”这个根本问题。2.2 BEVFusionICRA 2023构建统一“语言”让异构数据在BEV空间“自然对话”如果说 RCBEVDet 是在“修车”那么 BEVFusion 就是在“造路”。它的核心贡献是提出并实践了一种统一的、可学习的 BEV 表征空间。它不预设 Camera 和 Radar 的特征必须完美对齐而是设计了一个强大的“翻译官”——一个跨模态的 Transformer 解码器让两种异构数据在这个共同的空间里能够“自然对话”。BEVFusion 的流程可以概括为“双轨并行一核统御”Camera 轨道沿用成熟的 BEVDepth 或 BEVFormer 流程先用一个深度预测网络Depth Head为每个图像像素生成一个深度概率分布再通过 Lift-Splat-Shoot 将图像特征映射到 BEV。Radar 轨道同样将雷达点云柱状化并用一个 Pillar Encoder 提取 BEV 特征。但这里的关键一步是BEVFusion 并没有直接使用原始的雷达 BEV 特征而是将其与 Camera 的深度预测结果进行联合优化。具体来说它会利用 Camera 预测的深度来“筛选”和“加权”雷达点云——那些在 Camera 深度分布峰值附近的雷达点会被赋予更高的权重反之那些落在深度分布尾部的点则被抑制。这相当于用 Camera 的“语义直觉”来引导雷达的“物理测量”让雷达的稀疏点云也能带上一些“应该在哪里”的先验。注意BEVFusion 的“融合”发生在 BEV 特征的“语义层面”而非简单的通道拼接。它将 Camera BEV 特征和经过 Camera 引导的 Radar BEV 特征一同输入到一个共享的、基于 Deformable Attention 的 BEV 主干网络中。这个网络的注意力机制会自动学习哪些区域的 Camera 特征更可靠如白天的清晰道路哪些区域的 Radar 特征更关键如雨夜中的移动车辆从而实现一种“软性”的、数据驱动的融合。这极大地缓解了单模态投影失真的问题因为网络本身就在学习如何“信任”和“校正”不同来源的信息。BEVFusion 的强大之处在于其鲁棒性与泛化性。它在 nuScenes 上的实验表明即使在 Camera 深度预测存在较大误差的情况下Radar 的引入依然能显著提升对运动物体尤其是高速车辆的检测精度和跟踪稳定性。它没有试图消灭误差而是学会了与误差共处并利用另一种模态的优势来弥补。这是一种更高级、更接近人类感知的融合哲学。2.3 RaCFormer颠覆范式用“查询”作为主动的“融合指挥官”RaCFormer 的出现标志着 Radar-Camera BEV 融合进入了第三个阶段从“被动对齐”到“主动采样”。它彻底抛弃了“先投影、再融合”的旧范式转而采用一种以“查询Query”为核心的、全新的融合架构。在这里Query 不再是检测头的终点而是整个融合过程的起点和指挥官。RaCFormer 的整体框架可以用“一核三翼”来概括一核Transformer 解码器。这是整个系统的“大脑”它不直接处理原始传感器数据而是接收并不断精炼一组“对象查询”Object Queries。三翼分别对应三种不同的特征采样路径。第一翼Camera-transformed BEV Feature Generation相机转换的BEV特征。这一翼的关键创新是Radar-aware Depth Prediction雷达感知的深度预测。它没有让雷达点云去“适应”相机的深度预测而是反过来用雷达点云去“修正”相机的深度预测。具体操作是将雷达点云的 (x, y) 坐标通过相机内参矩阵反向投影到图像平面上得到其在图像上的 (u, v) 坐标。由于雷达在垂直方向z轴精度差它会将所有雷达点的 z 坐标统一设为一个默认值如1米以确保它们能尽可能多地落在图像的有效区域内。然后它将这些投影点的深度值即雷达测得的距离和雷达截面积RCS作为额外的通道与图像特征图进行拼接输入到一个深度预测网络中。这个网络输出的是一个被雷达信息“校准过”的、更准确的深度概率分布 D。这个 D 再被用于 Lift-Splat-Shoot生成高质量的 Camera BEV 特征。第二翼Radar-encoded BEV Feature Generation雷达编码的BEV特征。这一翼不仅提取静态的雷达 BEV 特征更关键的是引入了Implicit Dynamic Catcher隐式动态捕获器。它利用雷达固有的多普勒效应将多帧雷达 BEV 特征序列输入一个 ConvGRU卷积门控循环单元网络。ConvGRU 能够学习并记忆物体的运动轨迹从而在 BEV 特征图上显式地编码出“速度场”和“运动趋势”。这使得 RaCFormer 对运动物体的检测和预测能力远超前两者。第三翼Query Initialization and Ray Sampling查询初始化与光线采样。这是 RaCFormer 最具革命性的部分。它摒弃了传统的网格状或径向的 Query 初始化方式提出了Linearly Increasing Circular Distribution线性递增的环形分布。它将所有 Query 按照距离自车的远近均匀地分布在 k 个同心圆上且越靠近外圈远处的圆其上的 Query 数量越多按 α 因子线性增长。这完美契合了自动驾驶的感知需求近处需要高密度覆盖以保证精度远处需要广域扫描以保证召回率。更重要的是每个 Query 在解码过程中都会执行Ray Sampling光线采样它会沿着一条从自车中心出发、穿过该 Query 位置的“光线”在多个深度层上采样。对于每个采样点它会同时从 Camera 的原始图像特征避开深度失真和 Radar 的 BEV 特征利用运动信息中提取最相关的特征。最终这些来自不同视角、不同模态的特征被 Adaptive Mixer 模块动态加权融合用于精炼 Query。RaCFormer 的范式颠覆性在于它让融合过程从“静态的、全局的”变成了“动态的、局部的、任务驱动的”。每一个 Query 都是一个独立的、有目的的“侦察员”它知道自己要去哪里初始化位置、要找什么任务导向、以及该向谁求助跨模态采样。这从根本上规避了“全局投影失真”的问题因为它的采样是局部的、自适应的。这也是它能在 nuScenes 和 VoD 数据集上取得 SOTAState-of-the-Art成绩的根本原因——它不是在修补漏洞而是在重新定义游戏规则。3. 关键技术点深度解析深度估计、动态建模与查询设计的实战密码在 Radar-Camera BEV 融合的战场上有三个技术制高点决定了整套系统的上限与下限深度估计的鲁棒性、动态建模的准确性、以及查询设计的合理性。它们不是论文里抽象的公式而是工程师在调试模型、分析失败案例时每天都要面对的“硬骨头”。下面我将结合实际项目经验为你拆解这三个核心环节的底层逻辑与实操密码。3.1 深度估计从“单模态猜谜”到“多模态校准”的质变深度估计是 Camera BEV 转换的“命门”。一个像素点该抬升到多高这个问题的答案直接决定了它在 BEV 地图上的坐标。传统方法如 BEVDet依赖一个纯视觉的深度预测网络它只能从图像的纹理、遮挡、透视关系中“猜”深度。这种“猜”在晴朗白天尚可一旦遇到雨雾、逆光、或者一片单调的白墙误差就会急剧放大。RaCFormer 的Radar-aware Depth Prediction提供了一种“用物理定律校准视觉直觉”的新思路。它的核心在于“预处理”——如何让雷达点云这个“物理信标”能真正为图像服务。实操步骤与参数选择雷达点云预处理原始雷达点云的 z 坐标高度误差极大直接投影会导致大量点落在图像之外。RaCFormer 的做法是将所有雷达点的 z 坐标强制设为z_r 1。这个值并非随意选取而是基于一个经验事实在城市道路场景中绝大多数障碍物车辆、行人的底部高度都在 0.5-1.5 米之间。设为 1 米是一个兼顾了覆盖率和精度的“黄金中位数”。反向投影与粗略深度图生成使用相机内参矩阵M包含焦距f_x,f_y和主点c_x,c_y将(x_r, y_r, 1)投影到图像平面得到(u, v)。然后将该点的雷达测距值d即sqrt(x_r^2 y_r^2 1^2)赋给图像上(u, v)位置的像素。为了覆盖整个图像它会将(u, v)的v坐标扩展到图像的全高度H形成一条垂直的“深度线”。这一步生成的是一张极其稀疏、但物理意义明确的“粗略雷达深度图”。深度离散化与特征融合将粗略深度图中的深度值按照[0, D]例如 0-70 米的范围用一种“间距递增”的策略进行离散化Discretization。这是因为对于自动驾驶而言近处0-10米的深度精度要求极高关乎紧急制动而远处50-70米的精度要求相对较低主要用于提前预警。这种策略能更高效地利用有限的深度通道数。最后将离散化后的深度图、RCS 图反映目标反射强度是区分金属车体和塑料路牌的关键、以及下采样后的图像特征图如 C4 层在通道维度上拼接输入深度预测网络。实操心得我在复现这个模块时发现一个关键细节——RCS 的归一化。原始 RCS 值范围极大-30dB 到 30dB如果不做归一化它会完全淹没图像特征。我的做法是将 RCS 值通过一个tanh函数压缩到 [-1, 1] 区间效果远好于简单的 Min-Max 归一化。另外z_r 1这个参数在高速场景下可能需要微调为z_r 0.5以更好地捕捉低矮的锥桶或路面异物。3.2 动态建模用 ConvGRU 捕捉“时间之流”让BEV拥有“记忆”静态的 BEV 图就像一张凝固的照片。它能告诉你“此刻”有什么但无法告诉你“下一秒”会发生什么。而 Radar 的多普勒效应恰恰是感知“时间之流”的天然传感器。RaCFormer 的Implicit Dynamic Catcher就是将雷达的这种时间感知能力注入 BEV 特征的“血液”之中。核心原理与实现这个模块的本质是一个作用于 BEV 特征图序列上的 ConvGRU。ConvGRU 是 GRU门控循环单元的变种它将 GRU 中的全连接层替换为卷积层使其能够处理具有空间结构的 2D/3D 数据。其核心是两个“门”更新门Update Gate和重置门Reset Gate。更新门z_t决定上一时刻的隐藏状态h_{t-1}有多少信息需要被保留下来。它由当前帧的 BEV 特征x_t和h_{t-1}共同计算得出。重置门r_t决定h_{t-1}有多少信息需要被“遗忘”以便为新的信息腾出空间。候选隐藏状态h_t由r_t * h_{t-1}和x_t共同计算代表了当前帧想要“记住”的新内容。最终隐藏状态h_t由z_t * h_{t-1} (1 - z_t) * h_t计算得出是新旧信息的加权混合。这个过程可以形象地理解为h_{t-1}是 BEV 地图的“短期记忆”它记录了上一帧中各个位置的运动状态如某辆车的速度矢量。x_t是当前帧的“新鲜感官输入”。z_t和r_t就是“记忆编辑器”它根据当前输入决定是强化、弱化还是修改这份记忆。最终输出的h_t就是一个融合了历史运动信息和当前观测的、富含“时间语义”的 BEV 特征。实操心得ConvGRU 的初始化至关重要。很多初学者会将h_0设为全零这会导致模型在序列开头几帧的性能极差。我的经验是h_0应该初始化为一个“运动先验”例如一个与 BEV 网格大小一致的、表示“静止”的速度场全零但其方差要略大于零以提供一定的探索性。另外h_t和x_t的融合方式原文用了Conv2D(h_t ⊕ x_t)其中⊕是拼接。我实测发现将h_t和x_t相加h_t x_t的效果反而更稳定收敛更快因为避免了通道数翻倍带来的过拟合风险。3.3 查询设计线性递增环形分布让“侦察兵”在BEV地图上科学布防Query 的初始化看似只是一个网络的前置步骤实则决定了整个检测任务的“搜索策略”是否合理。一个糟糕的初始化会让模型在训练初期就陷入局部最优永远无法发现远处的小目标。RaCFormer 的Linearly Increasing Circular Distribution是对自动驾驶场景需求的深刻洞察。它认为BEV 地图不是一个均匀的棋盘而是一个以自车为中心的、辐射状的“感知疆域”。近处是“核心区”需要密集的侦察远处是“警戒区”需要广域的扫描。数学推导与工程实现假设我们要在半径为 R 的圆形 BEV 区域内放置 N 个 Query。传统径向分布Radial Distribution是从中心发出 M 条射线每条射线上放置 K 个 Query总数N M * K。但问题在于离中心越远相邻射线间的夹角所对应的弧长就越长导致远处 Query 的空间密度急剧下降。RaCFormer 的环形分布则不同。它将 Query 分布在 k 个同心圆上。第 i 个圆i 从 1 开始计数上有n_i个 Query且n_i n * α^(i-1)其中n是最内圈的 Query 数α是增长因子。总 Query 数N这是一个等比数列求和N n * (1 α α^2 ... α^(k-1))。当α ≠ 1时N n * (α^k - 1) / (α - 1)。如何确定k,n,α这是一个工程权衡问题。k决定了 BEV 区域被划分的“层数”k6对应 65 米半径是一个常用值。n决定了近处的探测密度n80意味着在 0-10 米范围内有 80 个 Query 均匀分布足以保证对近距离障碍物的高精度识别。α则是关键的“平衡杠杆”。α1时所有圆上 Query 数相同等同于径向分布α1时外圈 Query 更多。RaCFormer 选用α≈1.25这是一个经过大量 ablation study消融实验验证的“甜点”。它既保证了远处有足够的 Query 进行粗粒度扫描避免漏检又不会让远处 Query 过于密集而浪费计算资源因为远处的单个 Query 本身就覆盖更大的物理面积。实操心得在代码实现中切记不要用浮点数直接计算α^(i-1)尤其是在k较大时容易产生数值不稳定。我的做法是预先计算好一个长度为k的整数数组circle_counts其元素为n, round(n*α), round(n*α^2), ...然后对每个圆用torch.linspace(0, 2π, circle_counts[i])生成均匀的角度再结合该圆的半径即可得到所有 Query 的 (x, y) 坐标。这个过程就是将一个抽象的数学公式转化为了可执行、可复现的工程代码。4. 实操过程与核心环节实现从环境搭建到模型训练的全流程手把手指南理论终须落地。下面我将以一个完整的、可复现的项目流程带你从零开始亲手搭建一个 Radar-Camera BEV 融合的最小可行系统MVP。我们以 RaCFormer 的核心思想为蓝本但会进行必要的工程简化以降低入门门槛同时保留其最精华的设计理念。整个过程我将严格遵循“动手即所得”的原则每一步都附带可运行的命令和关键配置说明。4.1 环境准备与数据集获取站在巨人的肩膀上一切始于一个干净、可控的环境。我们推荐使用 Conda 创建一个独立的 Python 环境以避免依赖冲突。# 创建名为 racformer-env 的 conda 环境Python 版本为 3.8 conda create -n racformer-env python3.8 conda activate racformer-env # 安装 PyTorch以 CUDA 11.3 为例请根据你的 GPU 驱动版本选择 pip install torch1.12.1cu113 torchvision0.13.1cu113 torchaudio0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113 # 安装其他核心依赖 pip install numpy opencv-python tqdm pyyaml tensorboard scikit-image数据集是王冠上的宝石。对于 Radar-Camera BEV 融合目前最权威、最开放的数据集是nuScenes和View-of-Delft (VoD)。nuScenes 是行业标准但其雷达数据是 32 层的机械式雷达点云较密VoD 则使用了更贴近量产车的 31D 毫米波雷达点云更稀疏挑战性更大也更“真实”。nuScenes访问官网 https://www.nuscenes.org/nuscenes注册后下载v1.0-mini用于快速验证和v1.0-trainval用于正式训练数据集。你需要下载maps,samples,sweeps,annotations等所有 zip 文件并解压到同一目录下例如~/datasets/nuscenes。View-of-Delft (VoD)访问 GitHub 仓库 https://github.com/roboflow-ai/view-of-delft按照 README 下载vod_training.zip和vod_validation.zip。解压后你会得到radar,camera,lidar,labels等文件夹。提示数据集的路径配置是所有后续工作的基石。请务必在你的项目根目录下创建一个config.py文件并在里面定义好所有数据路径。例如# config.py import os # nuScenes 数据集路径 NUSCENES_ROOT os.path.expanduser(~/datasets/nuscenes) # VoD 数据集路径 VOD_ROOT os.path.expanduser(~/datasets/vod) # 模型检查点保存路径 CHECKPOINT_DIR os.path.expanduser(~/checkpoints/racformer)4.2 核心模块代码实现手写“雷达感知深度头”与“隐式动态捕获器”现在让我们进入最激动人心的部分——亲手编写核心模块。我们将跳过庞大的主干网络如 ResNet聚焦于 RaCFormer 的两大创新点RadarAwareDepthHead和ImplicitDynamicCatcher。第一步实现RadarAwareDepthHead这个模块的输入是图像特征图img_featshape: [B, C, H, W]、雷达点云radar_pointsshape: [N, 4][x, y, z, rcs]、以及相机内参cam_intrinsicshape: [3, 3]。输出是一个深度概率分布depth_probshape: [B, D, H, W]。import torch import torch.nn as nn import torch.nn.functional as F class RadarAwareDepthHead(nn.Module): def __init__(self, in_channels128, num_depth_bins64, max_depth64.0): super().__init__() self.num_depth_bins num_depth_bins self.max_depth max_depth # 雷达深度图的“编码器”一个简单的卷积网络 self.radar_encoder nn.Sequential( nn.Conv2d(2, 32, kernel_size3, padding1), # 输入深度图 RCS图 nn.ReLU(inplaceTrue), nn.Conv2d(32, 64, kernel_size3, padding1), nn.ReLU(inplaceTrue), ) # 图像特征与雷达特征的“融合器” self.fusion_conv nn.Conv2d(in_channels 64, in_channels, kernel_size1) # 最终的深度预测头 self.depth_head nn.Sequential( nn.Conv2d(in_channels, 128, kernel_size3, padding1), nn.ReLU(inplaceTrue), nn.Conv2d(128, num_depth_bins, kernel_size1), ) def forward(self, img_feat, radar_points, cam_intrinsic, img_shape): B, C, H, W img_feat.shape device img_feat.device # 1. 预处理雷达点云设 z1 radar_points_processed radar_points.clone() radar_points_processed[:, 2] 1.0 # z 坐标设为 1 # 2. 反向投影到图像平面 # 将雷达点云 (x, y, 1) 乘以内参矩阵得到 (u, v, d) # 这里简化处理使用一个近似公式 u (radar_points_processed[:, 0] * cam_intrinsic[0, 0] / radar_points_processed[:, 2]) cam_intrinsic[0, 2] v (radar_points_processed[:, 1] * cam_intrinsic[1, 1] / radar_points_processed[:, 2]) cam_intrinsic[1, 2] d torch.norm(radar_points_processed[:, :3], dim1) # 计算雷达测距 # 3. 生成粗略雷达深度图和 RCS 图 radar_depth_map torch.zeros(B, H, W, dtypetorch.float32, devicedevice) radar_rcs_map torch.zeros(B, H, W, dtypetorch.float32, devicedevice) # 将每个雷达点的深度和 RCS “泼洒”到图像上 # 此处为简化版实际应使用双线性插值或更复杂的 splatting for b in range(B): valid_mask (u 0) (u W) (v 0) (v H) u_int u[valid_mask].long() v_int v[valid_mask].long() d_valid d[valid_mask] rcs_valid radar_points_processed[valid_mask, 3] # 使用 scatter_add 实现“泼洒” idx v_int * W u_int radar_depth_map[b].view(-1).scatter_add_(0, idx, d_valid) radar_rcs_map[b].view(-1).scatter_add_(0, idx, rcs_valid) # 4. 编码雷达图 radar_feat torch.stack([radar_depth_map, radar_rcs_map], dim1) # [B, 2, H, W] radar_feat self.radar_encoder(radar_feat) # [B, 64, H, W] # 5. 融合图像特征与雷达特征 fused_feat torch.cat([img_feat, radar_feat], dim1) # [B, C64, H, W] fused_feat self.fusion_conv(fused_feat) # [B, C, H, W] # 6. 预测深度分布 depth_logits self.depth_head(fused_feat) # [B, D, H, W] depth_prob F.softmax(depth_logits, dim1) # [B, D, H, W] return depth_prob第二步实现ImplicitDynamicCatcher这个模块的输入是一个 BEV 特征图序列bev_featsshape: [B, T, C, H, W]其中T是时间步长如 4 帧。输出是一个融合了时间信息的 BEV 特征图bev_feats_outshape