发布作品

    自动驾驶——自动泊车之AVM环视系统算法框架

    AVM(Around View Monitor),中文:全景环视系统。在自动驾驶领域,AVM属于自动泊车系统的一部分,是一种实用性极高、可大幅提升用户体验和驾驶安全性的功能。AVM已经是一种较为成熟的技术,中高端车型均有部署,但详细讲述AVM系统算法的技术博文并不多。作者在工作中搭建了一套AVM算法框架,有一些效果还不错的demo。撰写本文,主要是想将AVM算法框架中每个算子讲述清楚,与大家共同进步。本博文的风格为理论与实践结合,含有部分代码,适合有一些计算机视觉基础的同学。

    关键词:相机联合标定、去畸变、投影变换、鸟瞰图、图像融合、光流、真实感3D模型、纹理映射。


    AVM系统概述

    AVM汽车环视影像系统如图所示,由安装在前保险杠、后备箱、后视镜上的四个外置鱼眼相机构成。该系统包含的算子按照先后顺序:去畸变、四路鱼眼相机联合标定、投影变换、鸟瞰图微调、拼接融合、3D模型纹理映射等。四路鱼眼捕捉到的图像信息通过上述算子,生成一个2D、3D的全景图。AVM算法又分为离线阶段和在线阶段两部分,在线阶段是对离线阶段的简化,更加适合于工程实现。下面我们来一一讲述。

    avm系统示意图


    离线阶段算法pipeline

    先来粗略浏览下AVM算法Pipeline包含那些算子:

    2D AVM

    2D AVM Pipeline


    3D AVM

    3D AVM Pipeline


    1 基于畸变表的鱼眼相机去畸变

    1.1鱼眼相机畸变模型

    我们知道普通相机和广角相机的投影方式一般为透视投影,即通过三角形相似原理,将相机坐标系下三维世界中的物体投影到平面上,这是基于理想的透视投影模型(无畸变)。但实际情况是我们得到的最终图像与理想的透视投影模型有一些区别,即径向畸变(桶形、枕型)、切向畸变。因此相机标定中都会对畸变做矫正。

    鱼眼相机的投影方式有很多种假设,例如等距投影、等立体角投影、正交投影、体视投影、线性投影。但是真实的鱼眼相机镜头并不完全遵循上述的这些模型假设。因此Kannala-Brandt提出了一种一般形式的估计,适用于不同类型的鱼眼相机:

    ,这个也是纳入opencv中的鱼眼相机畸变模型。对照下图:

    为光线入射角,

    为出射光线在相机归一化平面上或者在相机成像平面上与O之间的距离(在opencv中

    表示光线在相机归一化平面上的成像位置)。

    鱼眼相机模型

    相机去畸变通常使用张正友老师的棋盘格标定方法,首先通过矩阵推导得到一个比较好的初始解,然后通过非线性优化得到最优解,包括相机的内参、外参、畸变系数,然后对鱼眼图像做去畸变处理。内参即:

    相机内参矩阵

    然而,张正友标定法并不适用于我们的场景。


    1.2基于厂家畸变表的鱼眼图像去畸变

    由于张正友老师的棋盘格标定法是在图像的全局进行拟合得到一个全局的最优解,因此需要保证多次拍摄到的标定板的棋盘格可以覆盖整个图像区域。而我们假设的场景为要求汽车整车上流水线进行标定,即相机已经安装在车上。很显然,由于车身遮挡的原因,很难保证上述条件。另外,棋盘格标定法并不适用于批量生产。因此,我们选择了基于厂家提供的畸变表对鱼眼相机图像进行去畸变。相机厂家都有专业的光学工程师,大厂提供的畸变表通常情况下比较准确。

    当然,也有一些在畸变表的基础上进行优化的方法,例如[2]中采用最小重投影的方法计算出最优的相机主点位置,然后使用畸变表进行去畸变处理。在其他场景中,还有些同学先标定出相机的内参,然后将内参与畸变表联合使用。下面我们来讲述基于畸变表的去畸变方法:

    厂家提供的畸变表

    上面的表格展示了相机畸变表的一部分,厂家给出了入射角

    的光线在焦距为f的相机真实成像平面上成像点距离成像平面中心的真实距离

    ,单位为mm。如果想用opencv提供的API做去畸变处理,需要使用厂家提供的焦距f,将

    换算到相机的归一化平面上去(即除以f)。然后通过多项式拟合的方法,计算出

    这几个畸变参数,例如可以使用python的curve_fit库进行多项式拟合。调用Opencv API,m_distortion_coeffs即为多项式拟合的畸变参数。


    通俗讲:鱼眼相机去畸变的过程实际上就是遍历我们想要的无畸变图上的坐标点,通过mapx,mapy两个查找表,找到该坐标点在畸变图上的像素位置。通常这个像素的位置为浮点型,需要做双线性插值。否则在纹理边缘上会有锯齿状的问题,这个结论是作者实现了opencv remap函数验证过的,有兴趣的同学可以自己实现一下mapping的过程(查找+插值)。来看图:

    鱼眼图 去畸变

    右图为基于畸变表去畸变的结果,可以看出去畸变的效果大体上满足要求,例如柱子边、标定布边、车道线为直线。但是仍有部分区域的去畸变效果不好,直线不够直。这个问题会在鸟瞰图中看起来更加突出,也是导致覆盖区域拼接不齐的重要原因。

    原因可能有几种:

    (1)相机光轴与成像平面的交点(主点)与图像平面的中心不重合,即内参矩阵中的

    (2)厂家给的焦距f不准

    (3)厂家给的畸变表有误差。

    理论上讲,相机的标定是一个计算全局最优解的过程,可以理解为:我的内参可以不那么准,我拿到的畸变表也可以不那么准,但是只要我的优化目标重投影误差很小,或者畸变去的比较干净,那么这个全局最优解就是可以接受的。因此引用【2】中使用了最小化重投影误差的方法得到内参中的

    然后再使用畸变表;在有的场景中,还有些同学用棋盘格标定出相机的内参,然后配合畸变表进行使用。这些内容作者后面都会陆续做优化。


    2 四路鱼眼联合标定

    鱼眼相机联合标定的目的是要得到四个鱼眼相机之间的位姿关系,然后将拍摄到的图像搞到同一个坐标系下得到一幅全景环视图。

    相机联合标定示意图

    如图所示,全景鸟瞰图的视野范围是人为给定的参数,可根据用户喜好进行调节。标定布上的棋盘格大小、黑格子尺寸、汽车与标定布之间的间距这些都是已知的先验信息。上述先验信息在现实世界中与在全景图上的尺度关系为1:1,即1个像素代表1cm(当然这个尺度也可以调节,你想让一个像素代表n厘米也没问题)。这样做联合标定的意义在于:我们可以知道前、后、左、右四个鱼眼相机去畸变后图像中棋盘格上角点,与前、后、左、右四个鸟瞰图中棋盘格角点之间对应的坐标关系。这样我们就可以根据投影变换,将整张图像投影到对应的鸟瞰图上去。又由于在联合标定中,四个鸟瞰图是刚好拼接到一块的,因此利用上述方法将四张图全部投影到鸟瞰图上,在不考虑误差的理想情况下,应该是刚好拼接在一起的。以上,就是联合标定的思路。


    3 投影变换

    3.1投影变换原理

    投影变换的通俗理解就是:假设同一个相机分别在A、B两个不同位置,以不同的位姿拍摄同一个平面(重点是拍摄平面,例如桌面、墙面、地平面),生成了两张图象,这两张图象之间的关系就叫做投影变换。张正友老师的相机标定法使用的就是从标定板平面到图像平面之间的投影模型。

    投影变换模型

    图中相机从两个不同的角度拍摄同一个X平面,两个相机拍摄到的图像之间的投影变换矩阵H(单应矩阵)为:

    其中K为相机内参矩阵,R、T为两个相机之间的外参。这个公式怎么推导的网上有很多,我们只需要知道,这个单应矩阵H内部实际是包含了两个相机之间的位姿关系即可。这也就解释了:为什么有的AVM pipeline的方法是需要标定相机的外参,然后通过厂家提供的相机安装参数将四路鱼眼全部统一到车身坐标系下,而我们不需要这个过程,只需要用标定布来做联合标定。其实两种方法内部都是相通的,都绕不开计算相机外参这件事情。


    3.2 投影变换生成鸟瞰图

    生成鸟瞰图的过程可以理解为:将鱼眼相机拍摄到的图像,投影到某个在汽车上方平行地面拍摄的相机的平面上去。这个单应矩阵H具体是多少,由去畸变图中检测到的棋盘格角点坐标和联合标定全景图中棋盘格角点坐标来决定。如图所示,以后置相机为例,联合标定已知图(2)中框出棋盘格的坐标,图(1)中的棋盘格坐标可通过opencv的函数进行检测,从而建立单应矩阵H的求解模型。

    (1)去畸变图中棋盘格位置 (2)联合标定全景图中棋盘格位置 (3)瞰图


    3.3一些经验之谈

    3.3.1尽量选择更多的角点计算单应矩阵

    单应矩阵的求解是一个拟合的过程,如果选用过少的点,容易陷入局部最优解。造成的结果是就是鸟瞰图上只有你选择的那些点可以正确的投影,其他像素的投影可能不正确。这一点有点类似于深度学习中训练样本太少,导致过拟合的问题。

    单应矩阵三种形式(1)(2)(3)

    上面公式可以看出,一对匹配点可以提供两组方程,理论上4对匹配点就可以求解出单应矩阵。Opencv求解单应矩阵提供了两个函数,findHomography和getPerspectiveTransform。

    getPerspectiveTransform的输入是4对点,对(2)中矩阵求逆。理想情况下这种方法是可行的,但由于存在噪声,我们在图像上检测到的角点的误差、标定布棋盘格的误差,这种方法极其不准确。

    findHomography求单应矩阵的方法输入点对很多,解一个超定方程(3)。经过一顿推导,单应矩阵为(3)中矩阵的奇异值分解中最小奇异值对应的特征向量。这种方法用于做拟合的样本更多,最终的效果更好。而且Opencv还有很多优化算法,例如基于ransac思想的单应矩阵求解方法。当然,为了提高效果,可以对标定布进行DIY,某宝上很多这种DIY标定布,你想搞多少格子就搞多少。

    如1.2所述,由于畸变去除的不彻底,导致有些直线仍然是弯曲的。这一现象在投影到鸟瞰图上之后尤为明显,通过大量的棋盘格点进行投影变换,可以从一定程度上强制矫正这个问题。至少可以让车身附近的全景图效果更佳,而我们的avm系统最在意的恰好就是车身周围这部分,距离车身远的部分也不会呈现出来。如图所示为某厂DIY的标定布示意图。

    DIY标定布


    3.3.2尽量让棋盘格处于相机拍摄图像的中心

    鱼眼相机在中心部分畸变小,边缘位置畸变大。去畸变的结果通常也是中间的效果好,边缘残留的畸变多。因此,为了使单应矩阵计算的更佳准确,我们要保证标定布摆放的时候棋盘格位于鱼眼相机中央。这也是为什么某宝上标定布使用的示意图通常是图(2)这种,而不是图(1)。很显然,图(2)中棋盘格位于左侧后视镜附近(左鱼眼相机就在左后视镜上),即相机图像的中间位置,而图1中棋盘格则在相机图像边缘上。

    左侧鱼眼相机鸟瞰图(1)(2)


    4 拼接融合

    经过3中的投影变换,我们得到4张包含重叠区域的鸟瞰图如图所示,需要将这些鸟瞰图进行拼接融合。

    鸟瞰图

    以左、前鱼眼相机俯视图为例,观察下它们的重叠区域重叠区域:

    白色为重叠区域、AB为前鸟瞰图边界、CD为右鸟瞰图边界

    通常的做法是分别以AB、CD为边界,计算白色区域像素点与AB、CD之间的距离,然后计算一个权重,距离CD越近的位置,前俯视图权重越大;距离AB越近的位置,左俯视图权重越大。但会出现边界效应如图所示:

    前俯视图权重图

    其原因也很容易理解:如图所示,将AB、CD延长至O点,在EAOCE这个区域内,使用上述方法计算权重图才是一个完整连续的模型,如果在EABFDCE这个区域内计算权重图相当于把一个完整连续的域强行截断,计算得到的权重图必然是有截断痕迹的

    完整、连续模型示意图 完整、连续模型示意图

    因此需要使用某种策略,让我们在一个连续的作用域上计算权重,这里提供一个思路:在EAFCE这个连续的作用域中计算权重,得到一个非常漂亮的权重图:

    连续模型和权重图


    5 基于光流的鸟瞰图微调

    在整个AVM系统中,厂家提供的畸变表、焦距、相机主点位置,联合标定使用的标定布都会引入误差。这些误差会导致生成的鸟瞰图在重叠区域有一些偏移。第4小节中的拼接融合模块是为了让鸟瞰图在覆盖区域过渡平滑,尽量避免伪影现象。但是我们不能将这个压力全部施加给拼接融合模块。因此需要在拼接融合模块之前,对鸟瞰图进行微调,这个微调功能是供客户或者4S店人员进行手动调节的。
    在调研中发现,现在很多部署在车上的AVM系统都包含有微调功能。但大部分都存在一个问题:只能保证一边是对齐的,另外一边拼不齐。例如,前面对齐后面对不齐。
    作者使用了,将前、后微调光流图进行融合,得到一个平缓过渡的光流图,兼顾了前后两侧的微调。以左俯视图为例,算法流程如下:

    • 固定住前、后两个鸟瞰图
    • 手动微调左鸟瞰图,使左鸟瞰图与前鸟瞰图之间的重叠区域贴合。记录微调矩阵 M1,并根据矩阵计算光流 map1
    • 手动微调左鸟瞰图,使左鸟瞰图与后鸟瞰图之间的重叠区域贴合。记录微调矩阵 M2,并根据矩阵计算光流 map2
    • 根据像素距离计算 map1 与 map2 的权重图 w,即距离前鸟瞰图越近,map1 的权重越大,反之则越小
    • 使用 w 对 map1 和 map2 进行加权融合

    当微调矩阵M1和M2方向正好相反时,这个基于光流的思想可以很好地将两者融合,因为矩阵变换是比较“硬”的一种数学方法,而光流却像水一样的“软”。看下前后对比的融合效果图吧:

    左侧为普通的融合效果 右侧为基于光流思想微调后的效果

    可以看出这个方法可以兼顾前、后的微调效果。可以理解为将拼接区域的误差均摊给中间的区域,而中间这部分区域不存在拼接融合的问题,而且我们在泊车的过程中更注重的是车与周围物体的相对位置而非周围物体的精确位置,因此实际看上去也没什么问题。


    6 三维模型纹理映射

    2D的AVM算法是基于投影变换,将鱼眼图像投影到鸟瞰图上。而单应变换有一个前提:就是平面假设。是把一个平面投影到另外一个平面。存在的问题是:图像中所有的三维物体,例如汽车、柱子、墙,全部被当成平面来处理。这些内容在鸟瞰图上会被拉的很长,如图所示:

    2D图像中的三维物体

    左侧为墙,右侧为车(没错就是车的前杠被拉的好长)。

    安装在车身周围的鱼眼相机是单目相机,单目相机不能获取三维物体的深度。在图形学中有一种真实感增强的方法:制作一个三维模型,把二维的纹理贴图以某种方式映射到三维模型上,3D AVM正是使用了这个纹理映射技术,为驾驶员呈现出一个伪3D的效果。


    6.1 AVM 3D模型构建

    3D模型是由一个个小面片构成的,可以是三角面片、多边形面片等等。面片又是由多个顶点构成的,例如三角面片对应的就是3个顶点。我们先来直观地看一个三维模型:

    3dsMax三维模型

    放大看可以看到,3D模型是由很多个小的多边形面片构成。3D模型的文件形式有很多种,但大体上都是包含:模型顶点、面片、纹理坐标、法向量这些三维信息。具体如何使用3dsMax来制作3D模型,就不叙述了,作者不是专业的美工,方法可能不太聪明,领会精即可。

    AVM 3D模型是一个碗状的三维模型。模拟驾驶员视角,即汽车周围附近是路面,这部分直接映射到碗底平面上;而距离汽车较远的位置可能是楼房、树木、墙等三维物体,这部分内容将使用某种方式映射到三维点上。下面展示的就是我们的3d模型中的必要信息,包含顶点坐标、纹理坐标、法向量、三角面片索引。


    活动推荐:

    华车展ICVS将于2022.9.26-29 苏州国际博览中心举办中国智能汽车及自动驾驶博览会,同期举办:中国智能汽车产业链展,展会规模超30,000㎡、参展品牌500+、共计30,000+专业观众到场,同期还有100场行业大咖演讲。点击ICVS自动驾驶商业化主页—>进入菜单栏展会报名页面,即可免费领取参观门票,现阶段报名还将获取更多福利。

    次阅读
    3评论
    14赞同
    收藏
    分享
    3评论
    14赞同
    收藏
    分享

    评论·0

    头像头像
    提交评论
      加载中…

      热门资讯