Simple-BEV几何工具库utils/geom详解:坐标系变换约定与4x4矩阵运算新手完全指南
2026/8/22 14:31:35 网站建设 项目流程

Simple-BEV几何工具库utils/geom详解:坐标系变换约定与4x4矩阵运算新手完全指南

【免费下载链接】simple_bevA Simple Baseline for BEV Perception项目地址: https://gitcode.com/gh_mirrors/si/simple_bev

Simple-BEV 是一个知名的多传感器 BEV(鸟瞰图)感知基线项目,其 utils/geom.py 几何工具库用不到 300 行代码,集中实现了自动驾驶感知中最核心的坐标系变换约定与 4x4 矩阵运算。读完本文,你将轻松掌握a_T_b变换命名约定、齐次矩阵求逆、点云批量变换和相机内外参操作,再也不怕读不懂 BEV 感知代码里的几何部分。

🧭 先搞懂坐标系变换约定:a_T_b到底怎么读?

Simple-BEV 全项目统一使用一套简洁的几何命名约定,这是读懂 utils/geom.py 一切函数的前提。项目文档(README 中的Geometry conventions一节)定义了两条规则:

记号含义
p_ap,位于坐标系a
a_T_b把点从坐标系b变换到坐标系a的 4x4 矩阵

于是变换关系写成:

p_a = a_T_b * p_b

链条式变换也因此变得直观,例如把激光雷达下的点变换到某个相机:

xyz_cam0 = cam0_T_cam1 * cam1_T_velodyne * xyz_velodyne

新手记忆口诀:读法从右往左,下标指向"出发坐标系"。

此外,项目采用固定轴向约定:Z 轴向前(深度方向)、Y 轴向下、X 轴向右。因此图像左上角是 "0,0",坐标向右、向下递增。这个约定贯穿了所有张量的轴顺序B,S,C,Z,Y,X

📐 4x4 齐次矩阵:旋转 + 平移一步到位

BEV 感知里几乎所有位姿都用 4x4 齐次矩阵表示:左上 3x3 是旋转R,右列 3x1 是平移t,最后一行固定为[0,0,0,1]utils/geom.py提供了配套的"拆"与"装"工具:

函数作用典型形状
eye_4x4(B)生成 B 个单位 4x4 矩阵B x 4 x 4
split_rt(rt)从 4x4 拆出旋转r和平移t输入B x 4 x 4
merge_rt(r, t)由旋转和平移合成 4x4输出B x 4 x 4
merge_rtlist(rlist, tlist)批量版本,处理多相机场景输入B x N x 3 x 3

在 nuscenesdataset.py 中,数据集加载时正是这样组装外参的:先用merge_rt(rots, trans)得到velo_T_cam(相机到激光雷达),紧接着求逆得到cam_T_velo——这就是a_T_b约定在真实代码中的最小使用闭环。

⚡ safe_inverse:不花算力求矩阵逆的巧思

常规 4x4 求逆开销不小,而刚体变换矩阵有一个数学特性:旋转部分的逆就是转置(旋转矩阵是正交矩阵)。所以 utils/geom.py 中的safe_inverse只用两步就完成求逆:

  1. 旋转部分:直接转置,R⁻¹ = Rᵀ
  2. 平移部分:按公式t⁻¹ = -Rᵀ * t计算。

这样避开了通用求逆的除法与高斯消元,速度快且数值稳定。项目中两种规模都有覆盖:

  • safe_inverse(a):批量版,处理B x 4 x 4,是训练推理热路径的主力;
  • safe_inverse_single(a):单矩阵版,内部复用split_rt_single拆开旋转与平移再重组。

在 eval_nuscenes.py 评估脚本里,你能看到最典型的组合拳:

velo_T_cams = merge_rtlist(rots, trans)cams_T_velo = safe_inverse(velo_T_cams)

拿到cams_T_velo后,所有激光雷达点、雷达点、目标框都可以一次性搬到任意相机坐标系下。

🚀 apply_4x4:把点云批量送入任意坐标系

utils/geom.py 的apply_4x4(RT, xyz)是出现频率最高的函数之一,它做三件事:

  1. B x N x 3的点云追加一行 1,补齐为齐次坐标;
  2. 转置后与B x 4 x 4矩阵做批量矩阵乘法(B x 4 x 4B x 4 x N);
  3. 取回前 3 维,输出变换后的点云。

注意它没有做透视除法(第 39 行被注释掉了),因为该函数只用于刚体间(如相机↔雷达、相机↔相机)的位姿变换,分母恒为 1。而在 utils/vox.py 的体素化模块中,apply_4x4被用来在不同参考帧之间搬运记忆体素(memory voxel),是时序融合的几何基础。

📷 相机内参:把 4x4 当成内参的妙用

项目里内参矩阵pix_T_cam也统一成 4x4 形状(只是前 3x3 放内参),好处是内参和外参可以无缝串联矩阵乘法,完全遵守同一套a_T_b约定。配套函数有:

  • split_intrinsics(K):拆出焦距fx, fy与主点x0, y0
  • merge_intrinsics(fx, fy, x0, y0):反向组装回 4x4;
  • scale_intrinsics(K, sx, sy):图像缩放时同步缩放内参,训练时res_scale降采样就靠它(见 nuscenesdataset.py)。

📦 19维 lrtlist:目标框的"打包格式"

Simple-BEV 用一个B x N x 19张量同时存下目标框的全部信息,这是 nets/liftnet.py 等网络的核心输出格式:

维度内容
前 3 维尺寸l, r, t(长、宽、高)
后 16 维4x4 位姿矩阵(中心位置 + 朝向)

围绕它的工具链非常完整:

  • split_lrtlist/merge_lrtlist:19 维 ↔ 尺寸 + 4x4 互转;
  • apply_4x4_to_lrtlist:整个目标框列表变换坐标系,内部就是矩阵相乘rtlist_Y = Y_T_X * rtlist_X,尺寸保持不变(尺寸是各向同性长度,与位姿无关);
  • get_xyzlist_from_lrtlist:由尺寸生成 8 个角点,再变换到相机系——nuscenesdataset.py 用它计算 3D 框在图像中的投影;
  • get_clist_from_lrtlist:取出每个框的中心点。

🔄 像素 ↔ 相机 与角度回卷

utils/geom.py还覆盖了 BEV 管线中"2D 图像空间 ↔ 3D 相机空间"的转换:

函数方向用途
xyd2pointcloud像素+深度 → 3D 点云Lift-Splat 网络把深度图"抬升"为点云(nets/liftnet2.py 核心步骤)
pixels2camera像素坐标 → 相机坐标逐像素反投影,公式x_cam = z/fx * (x - x0)
camera2pixels相机坐标 → 像素坐标投影,nets/bevformernet.py 用它把 BEV 特征点投回各相机图像

另外,wrap2pi(rad_angle)通过atan2(sin(a), cos(a))把任意角度回卷到[-π, π],避免朝向角越界——nuscenesdataset.py 里解析 GT 朝向时就用到了它。

🗺️ 动手路线图:在哪里能实战这些工具?

建议按下面的路径在项目里追踪utils/geom的调用,把约定和函数串成完整记忆:

  1. nuscenesdataset.py —— 数据加载:内参缩放、外参组装与求逆、GT 框解析与投影,是约定入门的最佳样本;
  2. utils/vox.py —— 体素工具:apply_4x4在记忆体素坐标系间的搬运;
  3. nets/liftnet.py / nets/liftnet2.py —— 核心网络:深度反投影成点云、lrtlist的生成与变换;
  4. nets/bevformernet.py —— 查询投影:BEV 特征点投回各相机做可变形注意力;
  5. eval_nuscenes.py / eval_lyft.py —— 评估脚本:多传感器外参统一变换的完整示例。

总结utils/geom.py虽短,却是 Simple-BEV 全部几何逻辑的地基。抓住三个要点即可举一反三——a_T_b的"下标即出发点"读法、刚体矩阵"转置+公式"的快速求逆、以及内参外参统一的 4x4 齐次表示。掌握它们,你就能流畅阅读任何基于该约定的 BEV 感知项目了。

【免费下载链接】simple_bevA Simple Baseline for BEV Perception项目地址: https://gitcode.com/gh_mirrors/si/simple_bev

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

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

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

立即咨询