最近一直在做BEV、Occupancy的项目,涉及到许多3D视觉的知识,不由感叹3D任务相比2D任务具有更大的挑战性,入门也相对比较难。 且由于很难找到比较系统的3D视觉算法学习路线,一路走来也绕了不少弯路,因此借着目前已经对3D算法比较熟悉后,对3D视觉知识体系做个总结。由于自己也是从小白走过来的,所以很多知识点会解释的比较详细,确保小白都可以理解,入门系列主要会梳理包含自动驾驶坐标系转换、BEV模型基础、主流的BEV模型架构、以及Occupancy任务入门等。
1. 坐标系定义
入门3D视觉,最重要的就是要搞清楚自动驾驶中的几种坐标系类型以及其之间的联系,这涉及到一切对数据的预处理方式以及模型的构造。搞清楚坐标系转换才可以理解BEV算法中的多相机融合、或者BEV4D的时序融合。
以nuscenes数据集为例,自动驾驶中主要涉及到五种坐标系:世界坐标系、车辆坐标系、雷达坐标系、相机坐标系、像素坐标系。
首先坐标系定义主要需要明确坐标原点与x轴、y轴、z轴的向量方向,以上图LIDAR传感器的坐标系为例,它的坐标原点即它此刻的安装位置,例如(1,0,2),y轴方向指向车头朝向、x轴方向指向车辆右侧、z轴方向指向天空。
1.1 世界坐标系
还记得初中物理的第一课——参考系,描述世界中任何有关位置、运动等状态,都需要定义一个参考系。譬如刚刚我们说LIDAR传感器的坐标原点是(1,0,2),那为啥可以说是这个,而不说是(-1,0,2)呢?其实关键就是首先需要确定参考系,那么在一个自动驾驶的时序场景中,往往定义第一帧的车辆位置作为参考系(这个第一帧可以通俗理解为车辆中IMU传感器开机后,接收消息的第一个时间戳)。那么这个参考系其实就是后面会经常看到的世界坐标系了。
1.2 车辆坐标系
车辆坐标系指代的其实就是车辆自身的位资,即相对于世界坐标的旋转角度和偏移量,旋转角可以简单理解为两个向量之间的夹角,由于自动驾驶场景基本属于地平面运动,所以往往只会考虑y轴方向的旋转角信息。而偏移量简单理解就是当前时刻车辆的位置和世界坐标原点的距离,举个例子:假设世界参考系原点设置为(1,0,2),在第t时刻车辆的位置处于(5,8,7),那么偏移量就是(4,8,5),分别指代了x轴、y轴和z轴的偏移量。
1.3 雷达坐标系
雷达坐标系的定义和车辆坐标系相似,指的是车辆中雷达传感器的安装位置,但在数据中往往会以传感器外参的描述方法存在,所以我们主要需要理解外参这个概念。外参其实指的是不同传感器之间的坐标系关系,当一个车上装了多个或多种传感器后,它们之间的坐标关系是需要确定的。这个工作可分成两部分:内参标定和外参标定,内参是决定传感器内部的映射关系,比如摄像头的焦距,偏心、像素横纵比以及畸变系数,而外参是决定传感器和外部某个坐标系的转换关系,比如姿态参数(旋转和偏移量)。
而雷达的外参往往给的是雷达传感器与车辆IMU传感单元的参数关系,其实也是旋转角与偏移量,通过外参就可以实现车辆坐标系和雷达坐标系的转换。需要注意的是不同的车辆或数据集可能雷达安装的坐标系不同,如果后面需要统一混合进行模型训练,需要对坐标系进行统一,否则会存在严重的隐患。
1.4 相机坐标系
一般的相机坐标系都是z轴朝前方,x轴朝右方,y轴朝下方,如果以后遇到实际项目中某辆车或某个数据集中的相机坐标系不是这样的标定方式,一定要格外注意!!比如waymo数据集的相机坐标系就是y朝左、x朝前、z朝上的。那么这样的标定方式会有什么问题呢?主要后面BEV模型会涉及到环视多相机融合,这其实需要将各个不同相机的坐标系转换到一个相同的坐标系下后,才能进行融合,而目前我们的RGB图像其实是处于像素坐标系下的,如果需要转换到相机坐标系,普遍是基于《张正友标定方法》来标定,而这样的前提是相机坐标系必须严格按照z轴朝前方,x轴朝右方,y轴朝下方的表达。关于这一点,前期确实碰到不少坑。。。
1.5 像素坐标系
我们经常使用的图片数据其实是处于像素坐标系下的,这在2D任务中是比较常见坐标系,常常称为(u、v)坐标系,即一般设定为图像左上角为原点,v轴朝下、u轴朝右。譬如2D检测任务中标定检测框时常用(x1、y1、x2、y2)表示,其实代表的是相对于像素原点的偏移量。
而相机坐标系和像素坐标系的关系其实涉及到相机传感器的成像原理,简单来说相机传感器会有焦距和像素等参数,像素其实就是拍摄图像的尺寸大小,相机通过小孔成像模型将三维世界中的光线映射到画布上(即像素),从而得到一张图像。由此也可以看到,像素坐标系与上面几种坐标系相比仅有2维的向量,缺少三维空间信息即深度信息,而深度信息是3D任务中最关键的一环,后续所有的3D 任务都是围绕着深度信息展开的,特斯拉推崇的纯视觉方案其实也是依靠如果获得更好的深度信息展开的。
2. 总结
以上就是自动驾驶任务中的几种重要坐标系定义,了解它们才是真正开始入门3D视觉任务。后面会详细介绍不同坐标系之间的转换流程以及代码,这是入门纯视觉BEV以及多传感器融合最重要的基础!!! 欢迎各位做BEV、Occupancy任务的老铁们多多交流~