自动泊车之AVM环视系统算法进阶
之前的博文详细讲述了自动泊车领域的AVM环视系统框架中基础的算法,包含相机去畸变、相机联合标定、投影变换、拼接融合、2D AVM环视pipeline,以及3D的一些初步尝试。
本文的内容为在上一篇avm的进阶版,主要讲述AVM 3D算法pipeline,一种自研提取角点标定方法,汽车辅助视角。每个部分都涵盖了完整的算法理论以及部分代码,适合有一些计算机视觉基础的同学,或许可以给相关方向的同学做些参考。
关键词:3D纹理映射、标定、外参、单应变换、PNP
附赠自动驾驶学习资料和量产经验:链接
1. 一种更优的联合标定方案
1.1 算法原理分析
在前面的工作中,我们调用opencv函数findChessboardCorners提取图像上位于标定布中间的棋盘格角点,然后计算投影矩阵H。在SLAM 14讲中[1],计算H就是求解Ax=0这样一个问题。其原理就是构造一个最小二乘的形式,用奇异值分解的方式来计算一个误差最小的解。而为了逼近这个最小误差,可能造成除了棋盘格角点以外的其他像素值的投影误差很大。换句话说,由于棋盘格角点集中于鸟瞰图的中心很小的一部分区域,如果选择棋盘格角点进行H的计算,会导致只有棋盘格附近的区域能够进行准确的投影,远离该区域会有较大误差。类似于nn的训练数据过于局限,训练的模型过拟合了。这也就能够解释为什么在之前的工作中,我们的鸟瞰图拼接区域总是拼不齐,就是因为我们选择的角点远离拼接区域,计算出的投影矩阵H在拼接区域的投影误差太大。
我们开发了一种_基于自动提取角点算法的汽车标定方法_,该方法可以提取标定布上拼接区域黑色方格的角点。如图所示:
拼接区域角点提取
通过提取拼接区域的角点最终获得的全景鸟瞰图与前面工作的对比如下,左侧为以前的工作中提取棋盘格角点的方法且没有使用光流微调,右侧是我们提取拼接区域角点的拼接结果。差别就很大。
左:提取棋盘格角点 右:提取拼接区域角点
再仔细想想这样做是很合理的,因为AVM产品中最影响驾驶体验的就是拼接区域的伪影,其他一切都好说。标定布的测量误差会导致单应矩阵计算不准确,这一问题是无法避免的,我们选择拼接区域的特征点计算单应矩阵,使得拼接区域的拼接结果非常准确。随之而来的可能是其他区域的不准确,例如贴近车身周围的棋盘格区域,但是这些区域用户并不care,虽然车身周围会引入些许误差,但只要车身与周围环境的的相对位置呈现的正确,不会引起碰撞事故,对于驾驶员来讲就是OK的。
以上就是为什么我们要开发一种_基于自动提取角点算法的汽车标定方法_。
1.2 基于自动提取角点算法的汽车标定方法
标定场景
对于标定布上的棋盘格,我们可以使用opencv的角点检测函数findChessboardCorners来提取,建议读者自行阅读该函数源码,我们提出的方法的思路就来源于这个算法。下面我们来简述我们提取大方格角点的方法:
算法流程: |
---|
1. 双峰自适应阈值二值化 2. 多边形检测 3. 四边形筛选 4. 提取四边形顶点 |
- 双峰自适应阈值二值化
大体思路为:计算图像的亮度直方图。分别计算暗区局部极大值,亮区局部极大值,即“双峰”。计算双峰亮度的平均值,作为阈值,来对图像做二值化。因此称为“双峰自适应阈值”。
解释下这样做的理论基础:标定布上的大块黑色方格被白色布包围在中间,我们的目的是将标定布上的黑色方格与白色布通过某个阈值分割开。通常白色布的亮度值在直方图亮部阈值附近,黑色方块的亮度值在直方图暗部阈值附近。因此取两个亮度峰值取平均,一定可以将黑色方块与白色标定布分开。当然,光照条件不能过于恶劣,对于这一点即便是opencv提取棋盘格的方法也要限定光照条件。
基于自适应阈值的二值化
- 多边形检测以及四边形筛选
约束条件 |
---|
1. 多边形拟合结果必须为四边形,即筛选出二值化图中的四边形 2. 四边形面积必须大于某阈值(opencv源码中这个超参适用于筛选棋盘格的,我们要把这个阈值搞得大一些,用于筛选大方格) 3. 相邻边长不可相差过多 4. 选取黑色的四边形,而不是白色的四边形 5. 限制四边形分布范围,即四边形不能过于靠近图像边缘,具体情况与相机的位姿相关 |
- 使用上述约束条件筛选出大方格的角点。
综上,使用这种方法提取出的角点分布得更广泛,且都在鸟瞰图的分布区域,因此拼接融合得效果更佳。
2. AVM辅助视角——基于外参的视角变换
本章节主要讲述单应矩阵与PNP的原理,以及它们在AVM辅助视角中的实际应用,附带部分代码。
关键词:单应矩阵、PNP、标定、广角、超广角、车轮视角、越野模式
车载鱼眼相机可以获取到范围非常大的内容,但是鱼眼图像并不能够在汽车行驶过程中给驾驶员提供符合人类视觉习惯的视频图像,这一章节主要来讲述如何利用鱼眼相机的图像信息,来提供各种辅助视角。
例如:
(1)在进出车位或经过狭小空间时,驾驶员会更加关注车轮位置的内容,那么我们需要使用某种算法对左侧、右侧的鱼眼相机拍摄到的内容进行处理,得到“车轮