新闻  |   论坛  |   博客  |   在线研讨会
如何理解自动驾驶,SLAM,BEV,训练数据源常见术语?(1)
计算机视觉工坊 | 2023-08-15 21:48:50    阅读:135   发布文章

Birds-Eyes-View(BEV):鸟瞰图,这个词本身没什么特别意义,但在自动驾驶(Autonomous Driving,简称AD)领域逐渐普及后变成了这个行业内的一种术语。

Simultaneous Localization and Mapping(SLAM):并发定位与地图测绘,相对于BEV的另外一种感知技术。Perception:感知,SLAM和BEV在AD领域里都是协助控制系统了解车辆周围状况的感知技术:知道自己在哪,有哪些障碍物,障碍物在自己的什么方位,距离多远,哪些障碍物是静态的那些是移动的,等等相关信息,便于随后做出驾驶决策。SLAM VS BEV:SLAM主要通过各种传感器扫描周围空间的物体结构,以3维数据来描述这些信息。BEV同样通过传感器扫描获知周边状况,主要以2维数据来描述这些信息。从应用范围来讲,目前SLAM更为广阔,在AD火起来之前主要应用在VR/AR等领域,BEV主要集中在AD行业里。从技术实现来看,SLAM偏向于传统数学工具,包括各种几何/概率论/图论/群论相关的软件包,而BEV基本上清一色的基于深度神经网络DNN。两者最好不要对立着看,很多情况下可以互补。以下将侧重于BEV的基础介绍。SLAM和BEV最基础和核心的传感器就是相机(Camera),所以两者在计算过程中有大量的算力都被消耗在了图像中信息提取/识别和变换计算。SLAM倾向于识别图像中的特征(Feature)点,属于特征信息里的低级信息,通过计算这些特征点在不同图像帧上的位置来获取场景结构以及相机自身的位姿(Position and Pose)。而BEV倾向于识别车辆/道路/行人/障碍物等等高级特征信息,这些是卷积网CNN和Transformer擅长的。相机有两个最基础的数据:内参(Instrinsics)和外参(Extrinsics),内参主要描述的是相机的CCD/CMOS感光片尺寸/分辨率以及光学镜头的系数,外参主要描述的是相机在世界坐标系下的摆放位置和朝向角度。其中内参的常见矩阵是:00001]

图片

其中fx和fy分别表示光学镜头的横向/纵向焦距长度(Focus),正常情况下焦距是不分横纵向的,但因为CCD/CMOS感光片上的像素单元不够正,如果这个像素是绝对的正方形,那么fx = fy,实际上很难做到,有微小的差异,导致光线经过镜头投射到感光片上后,横纵坐标在单位距离上出现不等距的问题,所以相机模块的厂家会测量这个差异并给出fx和fy来,当然开发者也可以利用标定(calibration)过程来测量这两个值。

图片

图1

图片

图2另外,在传统的光学领域里,fx和fy的默认单位是毫米:mm,但在这个领域默认单位是像素:Pixel,导致很多有摄影经验的人看到fx和fy的值都挺纳闷,特别大,动不动就是大几千,这数值都远超业余天文望远镜了。为什么这里用像素?我们试着通过内参计算一下相机的FOV(Field of View,视场大小,通常以角度为单位)就明白了:

图片

图3

图片

这里fy是纵向焦距,h是照片高度。因为h的单位是像素,所以fy也必须是像素,这样才好便于计算机处理,所以fx和fy的单位就统一成了像素。其实都不用到计算机这步,CCD/CMOS感光片一般是要集成另外一块芯片ISP(Image Signal Processor)的,这块芯片内部就要把感光数据转成数字化的图片,这里就可以用像素单位了。内参除了这个矩阵外还有一套畸变(Distortion)系数K,这个东西不详细说了,正常的镜头成像后都是居中位置的变形小,四周变形大,一般通过标定(Calibration)获得这个参数后,对照片做反畸变处理,恢复出一个相对“正常”的照片。SLAM算法里很强调这个反畸变的重要性,因为特征点在照片上的绝对位置直接关系到了定位和建图的准确性,而大部分的BEV代码里看不到这个反畸变处理,一方面是BEV注重物体级别的高级特征,像素级别的轻微偏移影响不大,另一方面是很多BEV项目都是为了写论文,采用了类似nuScenes/Argoverse这类训练数据,这些数据的畸变比较小而已,一旦你在自己的项目里用了奇怪的镜头还是老老实实得做反畸变预处理。

图片

图4外参就简单多了,一个偏移(Transform)系数加一个旋转(Rotation)系数。

图片

����������������01]3维空间里表述旋转的计算方式常见的有2种:矩阵(Matrix)和四元数(Quaternion),为了防止矩阵方式存在万向节死锁(Gimbal Lock)问题,通常采用四元数来计算旋转。但在AD领域里很少这么干,因为相机是固定在车子上,只有垂直于地面的轴(一般是Z轴)才会发生360度的旋转,根本无法引发万向节问题,总不至于用户坚持在翻车的阶段仍旧保持自动驾驶这个诡异的需求。所以BEV的代码里通常就是矩阵形式,SLAM因为还会用在AR和其它领域,相机不是相对固定的,所以会采用四元数。另外,AD领域里不考虑****现象,所以外参都是仿射矩阵(Affine Matrix),这点和CG领域的3维渲染是不同的。另外,一般文章里介绍内参时还会考虑旋转偏差,这是由于CCD/CMOS感光片在工厂里被机器给装歪了,但AD领域一般不会考虑它,误差太小,而相机安装在车辆上时本身外参就有很大的相对旋转,不如一并算了,最后交由DNN学习过滤掉,而AR领域里的SLAM更是要主动计算外参,这点毛毛雨就不考虑了。内外参了解之后,下一个基础的重点就是坐标系。AD的坐标系有好几个,不事先理清楚就直接看代码有点晕。1)世界坐标系(World Coordination),这个是真实世界空间里,车辆的位置和方位角,通常粗略的位置是由GNSS(Global Navigation Satellite System)卫星定位系统获取,GNSS包括了美国GPS/中国BDS/欧洲Galileo/毛子GLONASS/日本QZSS/印度IRNSS,各有千秋,定位精度一言难尽,一般标称的精度都是指:车辆在空旷地区,上面有好几颗定位卫星罩着你,车辆静止,定位设备天线粗壮,无其它信号源干扰的情况下的测试结果。如果你处在城市内,四周高楼林立,各种无线电干扰源,卫星相对你时隐时现,车速还不慢,这种情况下给你偏个几十米都是对的起你了。为此有两种常见解决方案:差分****纠偏和地图通行大数据纠偏。这能给你造成一种错觉:卫星定位还是蛮准的。不管怎么弄,最后得到的坐标位置是经纬度,但跟常规GIS(Geographic Information System)相比,AD的经纬度不是球面坐标系,而是展开成2维地图的坐标系,所以最终在系统内的坐标系也是有区别的,比如google会把WGS84的经纬度换算成它自家地图的矩形切片编码,Uber提出过一种六边形切片的H3坐标编码,百度则是在火星坐标的基础上叠加了一个BD09的矩形切片坐标,等等诸如此类。这些都是绝对坐标位置,而通过类似SLAM技术扫描的高精度地图还会在这个基础上引入一些相对坐标。不管怎么样,最后在代码里看到的只剩下XY了。但这些系统都不能获取车辆朝向(地理正北为0度,地理正东为90度,依此类推,这仍旧是在2维地图上表示方式),所以AD里的车辆角度都是指“轨迹朝向”,用当前位置坐标减去上一时刻的坐标获得一个指向性的矢量。当然在高精度地图的加持下,是可以通过SLAM技术算出车辆的瞬时方位角。在缺失GNSS定位的时候,比如过隧道,需要用车辆的IMU(Inertial Measurement Unit)这类芯片做惯性导航补充,它们提供的数值是一个相对的坐标偏移,但随着时间的推移累积误差大,所以长时间没有GNSS信号的时候,IMU表示也没办法。2)BEV训练数据集的世界坐标系(nuScenes World Coordination,其它训练集就不特别说明了),这个跟GNSS的绝对坐标系就不同了:

图片

图5这是一个nuScenes地图,它的世界坐标系是图片坐标系,原点在图片左下角,单位是米,因此在使用训练数据集时,是不用考虑经纬度的。数据集中会根据时间序列给出车辆的瞬时位置,也就是在这个图片上的XY。3) Ego坐标系(Ego Coordination),在BEV里,这个Ego是特指车辆本身,它是用来描述摄像机/激光雷达(Lidar,light detection and ranging)/毫米波雷达(一般代码里就简称为Radar)/IMU在车身上的安装位置(单位默认都是米)和朝向角度,坐标原点一般是车身中间,朝向如图:

图片

图6所以车头正放的相机默认都是Yaw(Z轴)为0度,外参(Extrinsics Matrix)主要就是描述这个坐标系的。4) 相机坐标系(Camera Coordination),切记,这个不是照片坐标系,坐标原点在CCD/CMOS感光片的中央,单位是像素,内参(Intrinsics Matrix)主要就是描述这个坐标系的。5) 照片坐标系(Image Coordination),坐标原点在图片的左上角,单位是像素,横纵坐标轴一般不写成XY,而是uv。

图片

图7左中右三套坐标系分别为:Ego Coordination, Camera Coordination, Image Coordination。所以,当在BEV中做LSS(Lift,Splat,Shoot)时,需要把照片中的像素位置转换到世界坐标系时,要经历:Image_to_Camera, Camera_to_Ego, Ego_to_World,用矩阵表示:Position_in_World = Inv_World_to_Ego * Inv_Ego_to_Camera * Inv_Camera_to_Image * (Position_in_Image)其中Inv_表示矩阵的逆。实际代码里,Camera_to_Image通常就是Intrinsics参数矩阵,Ego_to_Camera就是Extrinsics参数矩阵。这里要注意的一点是:fx,fy,它们实际上是这样计算得到的:

图片

�=��/����=��/��Fx和Fy分别是横向/纵向的镜头焦距,但单位是米,Dx和Dy分别是一个像素有几米宽几米高,得出fx和fy的单位就是像素。当使用(Ego_to_Camera * Camera_to_Image)矩阵乘上Ego空间的坐标,会以像素为单位投影到照片空间,当使用(Inv_Ego_to_Camera * Inv_Camera_to_Image)矩阵乘上照片空间的坐标,会以米为单位投影到Ego空间,不会有单位上的问题。大部分的BEV是多摄像头的,意味着要一次性把多组摄像头拍摄的照片像素换算到Ego或者世界坐标系:

图片

图8


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客