2. 坐标系与传感器标定:车辆坐标系、相机坐标系、激光雷达坐标系、坐标变换基础、联合标定原理
各位同学,欢迎来到第二讲。
上一章我们聊了BEV感知的整体框架,说白了就是让车学会“上帝视角”。但你想过没有,车上的摄像头、激光雷达,它们各自看到的都是“局部世界”。怎么把这些碎片拼成一张完整的俯视图?
答案就是——坐标系与标定。
我个人习惯把这一章称为“感知系统的地基”。地基没打好,后面的模型再花哨也是空中楼阁。我在项目里见过太多因为标定误差导致感知结果“差之毫厘,谬以千里”的案例。嗯,咱们今天就把这块硬骨头啃下来。
2.1 四大核心坐标系
先搞清楚我们到底在跟谁打交道。自动驾驶里,有四个绕不开的坐标系:
- 车辆坐标系:以车为中心的世界。通常原点在后轴中心,X轴朝前,Y轴朝左,Z轴朝上。这是所有传感器的“最终归宿”。
- 相机坐标系:以相机光心为原点。Z轴沿着光轴方向,X、Y轴平行于成像平面。说白了,相机看到的是“透视世界”。
- 激光雷达坐标系:以激光雷达的旋转中心为原点。X轴朝前,Y轴朝左,Z轴朝上。它输出的是三维点云,每个点都有精确的(x, y, z)。
- 像素坐标系:图像上的二维坐标。原点在左上角,u轴向右,v轴向下。这是最终我们看到的“图片”。
你想想看,这四个坐标系之间是什么关系?
其实就是一个“翻译”过程。激光雷达说“我看到了一个点,在(10, 2, -1.5)”,相机说“我看到了一个像素,在(u, v)”。我们需要一个“翻译官”,把它们的语言统一到车辆坐标系下。
核心原则:所有传感器数据,最终都要变换到车辆坐标系下,才能进行融合与感知。
2.2 坐标变换基础
坐标变换,说白了就是“旋转+平移”。
我记得刚入行时,总觉得这玩意儿太简单,不就是矩阵乘法吗?直到有一次,我把旋转矩阵的顺序搞反了,结果点云全部飞到了天上……嗯,从那以后我再也不敢轻视它了。
2.2.1 旋转矩阵
三维空间里的旋转,可以用一个3x3的矩阵表示。绕X轴、Y轴、Z轴的旋转矩阵分别是:
// 绕X轴旋转θ角
Rx(θ) = [[1, 0, 0],
[0, cosθ, -sinθ],
[0, sinθ, cosθ]]
// 绕Y轴旋转θ角
Ry(θ) = [[cosθ, 0, sinθ],
[0, 1, 0],
[-sinθ, 0, cosθ]]
// 绕Z轴旋转θ角
Rz(θ) = [[cosθ, -sinθ, 0],
[sinθ, cosθ, 0],
[0, 0, 1]]
这里有个坑:旋转顺序很重要!先绕X轴再绕Y轴,和先绕Y轴再绕X轴,结果完全不同。我建议你统一使用“Z-Y-X”顺序,这是自动驾驶行业的主流做法。
2.2.2 平移向量
平移就简单多了,就是一个3x1的向量t = [tx, ty, tz]^T。表示从原坐标系原点,移动到新坐标系原点的偏移量。
2.2.3 齐次坐标与变换矩阵
为了把旋转和平移统一起来,我们引入齐次坐标。把三维点(x, y, z)变成四维(x, y, z, 1)。
变换矩阵T就是一个4x4的矩阵:
T = [[R, t],
[0, 1]]
其中R是3x3旋转矩阵,t是3x1平移向量。这样,一个点从坐标系A变换到坐标系B,只需要一次矩阵乘法:
P_b = T_ab * P_a
说白了,就是“左乘变换矩阵”。
我的小技巧:写代码时,我习惯用齐次坐标。虽然多了一个维度,但代码更简洁,也不容易出错。你可以试试看。
2.3 传感器标定原理
标定,就是求变换矩阵T的过程。我们需要知道每个传感器相对于车辆坐标系的精确位置和姿态。
2.3.1 相机内参标定
相机内参,描述的是“三维世界到二维图像”的映射关系。包括焦距(fx, fy)、主点(cx, cy)和畸变参数。
内参矩阵K:
K = [[fx, 0, cx],
[0, fy, cy],
[0, 0, 1]]
标定方法:用棋盘格拍多张照片,通过角点检测和优化算法,解算出K和畸变参数。
我曾经遇到过一个案例:标定板没放平,导致畸变参数偏差很大。结果车道线检测总是弯的。后来重新标定,问题就解决了。所以,标定过程一定要规范。
2.3.2 激光雷达到相机的外参标定
这是最关键的联合标定。我们需要求出一个4x4的变换矩阵T_lidar_to_camera,把激光雷达的点云投影到图像上。
原理很简单:
- 在场景中放置标定物(比如棋盘格或特定形状的标定板)。
- 激光雷达扫描到标定物的点云。
- 相机拍到标定物的图像。
- 通过点云和图像上的对应特征点,解算变换矩阵。
数学上,这是一个PnP(Perspective-n-Point)问题。给定3D点云和对应的2D像素点,求解相机位姿。
// 投影公式
// 点云坐标 P_lidar = [x, y, z, 1]^T
// 变换到相机坐标系 P_camera = T_lidar_to_camera * P_lidar
// 投影到像素坐标 p_pixel = K * P_camera (前两维除以第三维)
避坑指南:我曾经在标定时,激光雷达和相机的时间戳没对齐。结果点云和图像总是对不上。后来加了硬件同步,问题才解决。记住:标定前,先确保时间同步!
2.3.3 车辆坐标系与传感器坐标系的标定
每个传感器安装到车上后,都需要标定其相对于车辆坐标系的外参。
通常的做法是:
- 把车停在平整的地面上,用全站仪或高精度RTK测量传感器的精确位置。
- 或者,通过车辆运动(直线行驶、转弯)来在线标定。
我个人更推荐第二种方法。因为车辆在实际行驶中,传感器会有微小的形变,离线标定无法覆盖这些情况。
2.4 联合标定的工程实践
好了,理论说完了。咱们聊聊实际怎么做。
一个典型的联合标定流程是这样的:
| 步骤 | 操作 | 注意事项 |
|---|---|---|
| 1 | 准备标定场地 | 地面平整,标定板摆放合理 |
| 2 | 采集数据 | 确保所有传感器同时触发 |
| 3 | 特征提取 | 点云和图像上的特征点要一一对应 |
| 4 | 求解变换矩阵 | 使用优化算法(如Levenberg-Marquardt) |
| 5 | 验证标定结果 | 投影点云到图像,检查对齐精度 |
我记得有一次,标定结果总是有1-2个像素的误差。排查了很久,发现是标定板的角点检测算法有bug。换成亚像素级别的检测后,误差降到了0.5像素以内。
关键指标:好的标定结果,点云投影到图像上的误差应该在1-2个像素以内。如果超过5个像素,说明标定有问题,需要重新来。
2.5 总结与思考
这一章的内容,说白了就是一句话:坐标系是感知的骨架,标定是感知的肌肉。
没有准确的标定,BEV感知模型看到的“上帝视角”就是扭曲的。你想想看,如果激光雷达和相机的数据对不齐,模型怎么学得会融合?
下一章,我们会进入BEV感知的核心——特征提取与视角变换。但在那之前,我建议你把标定的代码亲手跑一遍。纸上得来终觉浅,绝知此事要躬行。
课后练习:找一个公开数据集(比如KITTI或nuScenes),读取其中的标定文件,手动实现一个点云到图像的投影函数。看看投影结果是否与数据集提供的可视化一致。
好了,今天就到这里。有问题随时交流。