本文节选自此书的第六章:
多摄像头感知后处理
本章目录:
多摄像头标定
多摄像头融合
多视觉感知后处理与BEV算法
随着用户对智能驾驶接受程度的提高和其适用范围的扩大,越来越多的智能驾驶车辆开发商开始考虑开发更高级的功能,如领航辅助(Navigate On Autopilot,NOA) 等。这些高级功能对传感器的配置提出了新的要求(如激光雷达、更多的摄像头、更多的毫米波雷达等),以消除车辆的感知盲区,提高车辆的安全性和可靠性。
根据摄像头的安装位置以及数量的不同,摄像头配置可以分为双目摄像头、多目摄像头、环视摄像头等。图1展示了一组常见的智能驾驶摄像头配置,其中C1为前视摄像头,C4为后视摄像头,C2、C3、C5、C6 为周视摄像头(环视摄像头)。
图 1 多摄像头感知系统
图1中,不同颜色区域代表相应角度摄像头的感知区域,比如C1摄像头的感知区域被标记为紫色区域,其他摄像头的感知范围也以类似的方式用不同颜色区分。这些不同颜色的区域结合起来,构成了一个完整的360°感知区域,确保车辆周围没有感知盲区,从而提高行车的安全性。本章首先对多摄像头标定进行介绍,然后对多摄像头融合算法进行重点介绍,最后对当下流行的多视角感知后处理与BEV 算法进行简单介绍。
多摄像头配置相较于单目摄像头显著提升了感知能力,但也引入了新的技术挑战。相较于单目摄像头,多摄像头系统各自的安装角度以及视野空间存在差异,这种差异可能导致对同一目标在共同视野内的测量结果出现不一致。所以,我们必须通过标定过程,将多个摄像头的测量数据转换到一个统一的坐标系中,以便进行后续的感知后处理。按照图1类似的配置,本节主要介绍双目摄像头标定、多目摄像头标定(包含环视摄像头)等相关技术。
1.1 双目摄像头标定
双目摄像头标定是在单目摄像头标定的基础上,额外增加求解左右摄像头之间的旋转和平移关系。通常,在标定的过程中,往往左摄像头被设定为主摄像头,在此基础上求解右摄像头坐标系相对于左摄像头坐标系的旋转矩阵R和平移矩阵T。
如图2所示的双目摄像头系统坐标系原理图,点P 是世界坐标系中的一个点,其坐标为P, 该点在左右摄像头坐标系中的坐标分别表示为P₁ 、P, 。 通过对左右摄像头分别进行单独标定,可以求得左右摄像头的内参矩阵以及对应的外参矩阵,即从世界坐标系到左右摄像头坐标系之间的旋转矩阵R、R, 和平移向量T₁ 、T, 。所以,点P 在左右摄像头坐标系中的位置可以通过下式表示:
因为P₁ 、P, 表示同一空间点P 在左右摄像头坐标系中的坐标值,将左摄像头坐标系设定为主坐标系,所以右摄像头相对于左摄像头的关系可以通过下式表达:
P₁=R, 2₁P, +T₁2
其中,R₂和T₂表示从右摄像头到左摄像头的旋转矩阵和平移向量,它们是双目摄像头标定过程中需要确定的外参。根据上述公式,转换求得
图 2 双目坐标系原理示意图
1.2 多摄像头标定
所谓“多摄像头标定”,是指在双目摄像头标定的基础上,将标定过程扩展到更多的摄像头。这一过程涉及求解多摄像头系统中每个摄像头的内参以及各摄像头坐标系相对车体坐标系的旋转矩阵和平移向量。
多摄像头坐标系间的位姿传递原理如图3所示。图3中包含n个摄像头坐标系,分别为0₁-x₁y₁z₁ 、O₂-x₂y₂z₂… … 0-x,yn zn,为了方便计算,将0₁-x₁yiz₁设置为主坐标系 (全局坐标系),并用G表示,此时就变成了求解O₂-x₂Y₂z₂… … 0-x,y nz相对O₁-x₁y₁z₁ 的位姿关系。
图 3 多摄像头坐标系位姿变换原理
整体思路是采用递归方法,利用双目摄像头的求解方法,首先计算第n个摄像头相对第n-1个摄像头的位姿关系,接着计算第n-1个摄像头相对于第n-2个摄像头的位姿关系,依此类推,可以得出第n个摄像头相对于第1个摄像头的位姿关系,从而确定第n个摄像头相对于主坐标系的绝对位姿关系。
假设矩阵M,是空间点P由摄像头0,坐标系转换到摄像头0;坐标系的转换矩阵,该矩阵可以表示为旋转矩阵R,和平移向量t的集合:
第n个摄像头与第n-1个摄像头之间的相对位姿转换矩阵为M-,则第n个摄像头向全局坐标系转换矩阵M可以通过递归方式计算,公式如下:
P表示空间点P在摄像头坐标系i下的三维坐标,若使用旋转矩阵R和平移向量t来描述多摄像头位姿的转换关系,空间点P从摄像头0;坐标系到全局坐标系0c的转换关系为
P⁶=R₂ ·P+t₂
按照递推关系,可以得出第n个摄像头转换到全局坐标系的旋转矩阵和平移向量:
所以,P点在第n个摄像头坐标系中的位姿转换到全局坐标系后可以表示为
P⁶=RS·P"+tS
通过上面的公式,我们可以将多摄像头坐标系中的任意点有效地转换到全局坐标系。这种方法确保了在不同摄像头视图之间进行坐标转换的准确性和一致性,增强了多摄像头系统在三维感知和图像分析方面的性能。
多摄像头融合技术的基础在于精确获取多摄像头系统中每个摄像头的内外参。通过这些参数,我们可以利用特征匹配、目标关联等方法,将不同摄像头捕捉的图像拼接在一起,或者将图像中的障碍物信息进行融合。这种技术不仅提升了对图像信息的分析和提取能力,还确保了跨摄像头区域的目标具有一致性,提高了系统的整体感知精度。最常见的多摄像头融合技术有多摄像头立体匹配、多摄像头图像处理(图像拼接)、多摄像头目标融合以及多摄像头车道线融合等。
2.1 多摄像头立体匹配
对极几何是一种用来描述两张或多张图像间对应关系的工具。在寻求这些图像间的对应点时,最直接的方法是逐点匹配,然后通过对极约束的应用来降低搜索范围。具体来说,对极约束是将原本需要在2D平面上的搜索,转变为在1D 直线上的搜索,从而大幅提升搜索速度。
在双目视觉系统中,对极约束的应用尤为广泛。如图4所示,H 为一个空间点,其在左右摄像头成像平面上的成像点分别为u 、u' 。左右摄像头的光心分别为0、0',它们与点H 共同组成的平面被称为“对极平面”。在这个平面中,左右光心0、0'的连线与左右摄像头成像平面的交点被称为“极点”,分别记为e 、e' 。空间点H和极点确定的直线在各自成像平面上的投影被称为“极线”,分别记为L 、I' 。如果一张图像上的像点u 已知,那么在另一张图像上的对应像点u'就能够在u对应的极线I'上找到,反过来照样成立。这种约束关系被称为“极线约束”。极线约束大幅缩小了在图像间寻找对应点的搜索空间,从而加快了匹配。
图 4 双目对极约束
假设存在一个矩阵,可以将一个摄像头成像平面上的像素点坐标与另一个摄像头成像平面的对应点联系起来,从而实现相应点的匹配,这个矩阵被称为“基本矩阵”,表示为 F。基本矩阵捕捉了两个摄像头之间的几何关系,包括它们的相对位置和姿态。基本矩阵F可通过下式求得
m'TFm=0
F=Al[t],RA¹
式中,m、m'分别为投影点u、u'在图像坐标系下的齐次坐标矩阵;A、Ag分别为左右摄像头的内参矩阵;R、t分别为右摄像头相对左摄像头的旋转矩阵和平移向量;[t]。为平移向量的反对称矩阵。
在利用极线约束搜寻匹配点时,由于是1D直线搜索,且实际的成像点可能存在误差,仅利用两幅图像进行匹配,会在像点较为密集的情形下,出现很多不确定状况和误匹配。所以,我们需要利用多摄像头进行拍摄,从多幅图像中来唯一确定待匹配点。如图5所示,空间中点P在3个像平面成像点分别为u₁、u₂、u₃,此时u₂可以在u₁、u₃对应的极线l₂上找到,提升了匹配u₂ 的准确性。由此可见,利用多幅图像相互进行极线匹配,就能极大地降低匹配的出错率。
图 5 多视图对极几何
在完成图像匹配后,通过两个或者更多不同位置的摄像头的内外参以及对应的像素点坐标,可以构建空间点的三维坐标。假设P=A[R; |t;]表示第i个摄像头的投影矩阵,其中i=1,2,…,n(u,v)×为对应的图像坐标,构建如下方程:
其中P代表第i个投影矩阵的第j行,X为目标点的三维坐标。从上式中可以看出,一组图像坐标可以构建两个独立的方程组,至少需要来自两幅图像的坐标信息才能计算出目标点的三维坐标。当采用多摄像头进行测量时,通过对这些方程组的求解,即可得到同一目标点的多个坐标值。
对于多摄像头图像,如果对全图每个像素都进行匹配,计算量是巨大的。为了减小计算量并实现多视图匹配,我们往往会采用基于区域的局部匹配算法。这些算法包括像素差的绝对值(Sum of Absolute Difference,SAD)、像素差平方和(Sum of Squared Difference,SSD)、块匹配(Block Matching,BM),以及半全局块匹配(Semi-Global Block Matching, SGBM)。这些算法通过只关注图像的特定部分来降低计算量,同时仍能有效地完成视点间的匹配任务。
1. SAD算法
SAD算法主要用于图像块的匹配,其基本思想是计算每个像素对应数值之差的绝对值之和,并以此评估两个图像块的相似度。SAD算法速度快,但精度相对较低,经常用于各种立体匹配算法的初步筛选。
SAD算法流程如下:
1) 输入两幅行对准的图像:左视图(Left-Image)与右视图(Right-Image)。
2) 对左视图进行扫描,选定一个锚点并构建一个类似于卷积核的小窗口。
3) 用此小窗口覆盖左视图,并选出小窗口覆盖区域的全部像素点。
4) 同样,用此小窗口覆盖右视图,并选出小窗口覆盖区域的全部像素点。
5) 左视图覆盖区域的像素减去右视图覆盖区域的像素,并求出所有像素点的差的绝对值之和。
6) 移动右视图的小窗口并重复步骤4)和步骤5)的操作(注意,此处会设置一个搜索范围,超过此范围则跳出)。
SAD窗口搜索示意图如图6所示。
图 6 SAD窗口搜索示意图
7)找到这个搜索范围内SAD值最小的小窗口,此时便找到了与左视图锚点的最佳匹配的像素块。
其中,SAD值计算公式如下:
这里给出SAD值计算的示例代码:
1.using namespace cv;
2.
3.Mat SAD::computerSAD(Mat &L,Mat &R)
4. {
5. int Height =L.rows;
6. int Width=L.cols;
7.
8. NMat Kernel_L(Size(winSize,winSize),CV_8U,Scalar::all(0));
9. Mat Kernel_R(Size(winSize,winSize),cV_8U,Scalar::all(0));
10. Mat Disparity(Height,Width,cV_8U,Scalar(0)); //视差图
11.
12. for(int i=0;i
13.
14. for(int j=0;j
15. {
16. Kernel_L=L(Rect(i,j,winSize,winSize));
17. Mat MM(1,DSR,CV_32F,Scalar(0));
18. for(int k=0;k
19.
20. int x=i-k;
21. if(x>=0)
22.
23. Kernel_R=R(Rect(x,j,winSize,winSize));
24. Mat Dif;
25. absdiff(Kernel_L,Kernel_R,Dif);// 求差的绝对值之和
26. Scalar ADD=sum(Dif);
27. float a =ADD[0];
28. MM.at
(k)=a; 29. }
30.
31. Point minLoc;
32. minMaxLoc(MM,NULL,NULL,&minLoc,NULL);
33. int loc=minLoc.x;
34. Disparity.at
(j,i)=loc*16; 35. }
36. double rate=double(i)/(Width);
37. cout <<"已完成" <
38. }
39. return Disparity;
40. }
2. SSD算法
SSD算法流程与SAD算法流程相似,只不过计算的是SSD值,而不是SAD 值。SSD值计算公式如下:
3. BM算法
BM算法是在SAD算法的基础上,通过在左右图像之间建立几何关系来辅助匹配过程。具体来说,BM算法是利用三角形的相似性质来构建两个视图之间的对应关系。如图7所示,P为空间中的物体,0,和O₂是两个摄像头坐标系原点,这3个点构成了一个平面,该平面与两个摄像头的像面相交点为P₁和P₂ 。假设P₁ 的位置已知,P₂ 的位置未知,BM算法的目的是通过这种三角测量方法来近似定位P₂ 的位置。
图 7 BM算法原理示意图
BM算法在处理低纹理区域或者小位移问题时具有较好的性能,而且运行速度快。然而,该算法只考虑了局部信息且缺乏全局优化策略,很容易导致误匹配或者漏匹配的情况发生。
4. SGBM算法
SGBM算法流程如图8所示。
图 8 SGBM算法流程
从图8可以看出,SGBM算法的代价计算包含如下几部分:
1)对输入的左右图像的水平方向进行Sobel算子处理后,计算BT(Birchfield and Tomasi) 代价。
2)将左右图像得到的BT代价值进行组合。
图 9 左右图像中BT代价求解示意图
首先计算左图中像素和之间亚像素位置(x+x,y)的灰度值 I(x+d,y),然后计算右图中像素和之间亚像素位置(x+d+x,y)的灰度值I(x+d,y)。所以,左右两幅图像的BT代价分别为
最终的BT代价为两代价的最小:
e(x,y,d)=min(cos,cosR)
下面给出通过SGBM算法得出视差图的示例代码:
1.using namespace cv;
2.
3.void SGBM::calDispWithSGBM(Mat Img_L,Mat Img_R,Mat &imgDisparity8U)
4. {
5. Size imgSize =Img_L.size();
6. int numberOfDisparities =((imgSize.width/8)+15)&-16;
7. Ptr
sgbm=StereoSGBM::create(0,16,3); 8.
9. //左图像的通道数
10. int cn =Img_L.channels();
11. int SADWindowSize=9;
12. int sgbmWinSize=SADWindowSize>0?SADWindowSize:3;
13.
14. //minDisparity 最小视差,一般默认为0
15. sgbm->setMinDisparity(0);
16. //numDisparity 视差搜索范围,范围值必须为16的整数倍
17. sgbm->setNumDisparities(numberOfDisparities);
18. //一般建议惩罚系数P1 、P2取如下的值,P1 、P2控制视差图的光滑度,P2 越大,视差图越平滑
19. sgbm->setP1(8*cn*sgbmWinSize*sgbmWinSize);
20. sgbm->setP2(32*cn*sgbmWinSize*sgbmWinSize);
21.
22. //左右图像一致性检测最大容许误差阈值
23. sgbm->setDisp12MaxDiff(1);
24. //预处理滤波器的截断值,预处理的输出仅保留I-preFilterCap,preFilterCap] 范围内的值,参 数范围为1~31
25. //
26. sgbm->setPreFilterCap(31);
27.
28. //当视差窗口范围内最低代价是次低代价的(1+uniquenessRatio/100) 倍时,最低代价对应的视差值才是该像素点的视差;否则,该像素点的视差为0。该值不能为负值, 一般取5到15,这里取10
29. //
30. sgbm->setUniquenessRatio(10);
31.
32. //视差连通区域像素点个数的大小。对于每一个视差点,当其连通区域的像素点个数小于speck- leWindowSize 时,认为该视差值无效,是噪点
33. //
34. sgbm->setSpeckleWindowSize(100);
35.
36. //在计算一个视差点的连通区域时,当下一个像素点视差变化绝对值大于speckleRange 时,认为下一 个视差像素点和当前视差像素点是不连通的
37. //
38. sgbm->setSpeckleRange(32);
39.
40. //模式选择
41. sgbm->setMode(0);
42. //设置SAD 代价计算窗口, 一般在3×3到21×21之间
43. //blockSize(SADWindowSize) 越小,表示匹配代价计算的窗口越小,视差图噪声越大;blockSize (SADWindowSize) 越大,表示视差图越平滑。太大的窗口容易导致过平滑,并且误匹配增多,体现在视差图中空洞增多
44. //
45. sgbm->setBlockSize(sgbmWinSize);
46.
47. //3种模式(HH、SGBM、3WAY)选择
48. int algorithm =STEREO_SGBM;
49. if(algorithm ==STEREO_HH)
50. sgbm->setMode(StereoSGBM::MODE_HH);
51. else if(algorithm ==STEREO_SGBM)
52. sgbm->setMode(StereoSGBM::MODE_SGBM);
53. else if(algorithm ==STEREO_3WAY)
54. sgbm->setMode(StereoSGBM::MODE_SGBM_3WAY);
55.
56. Mat imgDisparity16S=Mat(Img_L.rows,Img_L.cols,cv_ 16S);
57. sgbm->compute(Img_L,Img_R,imgDisparity16S);
58.
59.
60. imgDisparity16S.convertTo(imgDisparity8U,CV_8U,255/
(numberOfDisparities*16.));
61.}
2.2 多摄像头图像处理
在完成特征点或者立体匹配后,下一步是对多摄像头图像进行拼接或者获取图像深度信息 。
1. 双目测距
双目是智能驾驶中常见的前向视觉配置。根据光轴的平行度,双目视觉模型可以分为平行式和汇聚式两种,如图10所示。
平行式双目视觉模型也被称为“标准式双目视觉模型”。它是由两个内参相同的摄像头并排摆放在一起,且它们的光轴平行。这是一种精度较高的模型,但这种模型对摄像头的生产工艺要求极其严格 。
汇聚式双目视觉模型对摄像头摆放位置无特殊要求,但在进行计算时,需要输入额外的位置参数来计算投影矩阵,这使得运算更加复杂和耗时 。由于对摄像头的位置要求较低,因此该模型实际应用较为广泛 。
图 10 双目视觉模型的两种表现形式
在实际应用中,我们一般会采用长焦摄像头和短焦摄像头配合 (如FOV30 °与FOV100°的摄像头组合)的方案来获取更广的视野和更远的距离。这种方案也可以看成汇 聚式双目的特殊表现形式。
以标准双目摄像头为例,其计算过程相对简单,能够实现较高的精度,并提供较大的视野。它通过匹配两个单目摄像头的图像,可以得到高分辨率的深度图,满足自动驾驶实时性的要求。双目摄像头测距原理如图11所示。
在图11中,0₁和0,分别为左右摄像头的光心,f为焦距,T为左右光心之间的距离 (也叫“基线距离”),P为双目摄像头共同视野内的任意空间点,假设(x,y,z)为点P在以左摄像头 (主摄像头)光心为原点的坐标系下的坐标。从图11可知,△O₁0.P相似于 △pip,P,根据相似三角形的性质,可以得到点 P 的深度:
图 11 双目摄像头测距原理
其中,x₁和x,分别为点P在左右摄像头图像平面上的横坐标。所以
其中,d为视差,d=(x,-x₁)。得到深度Z后,继续根据相似三角形原理计算出x和y,从 而得到点P的位置:
对于汇聚式双目摄像头系统,我们可以通过转换将其视为标准双目摄像头系统后,再进行计算。
2. 图像融合拼接
图像融合拼接是多摄像头图像处理中比较常见的方法。它通过提取所有摄像头中所需要的特征信息,并删除冗余信息的千扰后,最终生成的一张图像。在智能驾驶领域,多摄像头图像融合拼接可以获得更多的信息,使得车辆更清晰地感知到周围的环境,便于下游控制的决策。如图12所示的鱼眼摄像头拼接就是一种应用实例。
图 12 图像融合拼接示意图(鱼眼)
常见的图像融合方法一般是在完成图像特征匹配后进行的。首先,按照特征匹配的结果求解图像间的相对姿态关系,然后对图像进行配准,再将其中一幅图像按照求解出的姿态复制到另一幅图像的指定位置。这个过程涉及透视变换,这是图像之间最常用也是最复杂的变换之一。透视变换考虑了图像之间所有可能的形变,包括平移、缩放、旋转、水平垂直变形等。由于参考图像和配准图像都是在各自的像素坐标系下,所以需要将它们转换到统一的像素坐标系下,转换公式如下:
式中,(x₁,y₁)为参考图像坐标;(x₂,y₂)为变换后的图像在配准图像中的坐标;H= 就是所谓的“透视变换矩阵”,由8个非零参数组成,其中代表图像间的旋转、缩放,定义了图像间的平移向量,Gc₁c₂)定义了图像间的投影向量。
下面给出鱼眼拼接的示例代码:
1. cv::Mat simulateImage(cv::Mat image,double offset,double angle){
2. angle =angle*M_PI/180;
3. Eigen::Matrix3d rotate_matrix;
4. rotate_matrix<
5. cV::Point2f source_points[4];
6. cv::Point2f target_points[4];
7. Eigen::MatrixXd camera_points(4,3);
8.
9.
10.camera_points<<-1.92712132,1.65,9.45903236,-1.73522111,1.65,12.3165494, 1.12215585,1.65,
11. 12.3165494,1.3278535,1.65,9.45903236;
12. for(int i=0;i
13. CameraPoint camera_point(camera_points.row(i));
14. ImagePoint image_point =cameraToImage(camera_point);
15. source_points[i].x=image_point.x();
16. source_points[i].y=image_point.y();
17. }
18.
19. for(int i=0;i
20. camera_points(i,0)-=offset;
21.CameraPoint camera_point(rotate_matrix*camera_points.row(i).transpose());
22. ImagePoint image_point=cameraToImage(camera_point);
23. target_points[i].x=image_point.x();
24. target_points[i].y=image_point.y();
25.
26.
27.auto transform_matrix=cv::getPerspectiveTransform(source_points,target_points);
28. cv::Mat target_image;
29. cv::warpPerspective(image,target_image,transform_matrix,image.size());
30. return target_image;
31.}
鱼眼拼接示例图像如图13所示。
图 13 鱼眼拼接示例图像
在完成图像拼接后,我们通常会发现图像接缝处存在不自然现象,这是光照和色泽差异导致拼接图的交界处过渡不平滑。为了解决这一问题,我们需要采用特定的处理方法来消除这种不自然。一种常见的处理思路是采用加权融合技术,在图像重叠区域实现从前一幅图像慢慢过渡到第二幅图像。具体来说,就是将图像重叠区域的像素值按一定的权值相加,合成新的图像 。
1.void OptimizeSeam(Mat&img1,Mat&trans,Mat&dst)
2. C
3. //开始位置,即重叠区域的左边界
4.int start =MIN(corners.left_top.x,corners.left_bottom.x);
5. double processWidth =img1.cols-start;//重叠区域的宽度
6. int rows=dst.rows;
7. int cols=img1.cols;//注意,是列数×通道数
8. double alpha =1;//img1中像素的权重
9. for(inti=0;i
10. {
11. uchar*p=img1.ptr
(i); // 获取第i 行的首地址 12. uchar*t=trans.ptr
(i); 13. uchar*d=dst.ptr
(i); 14. for(int j=start;j
15.
16.
17. if[t[j*3]==0&&t[j*3+1]==0 &&tfj*3+2]==0)
18. alpha =1;
19. else
20. //img1 中像素的权重与当前处理点距重叠区域左边界的距离成正比
21. alpha=(procesSWidth-(j-start))/processWidth;
22. d[j*3]=p[j*3j*alpha +t[j*3]*(1-alpha);
23. d[j*3+1]=p[j*3+1]*alpha+t[j*3+1]*(1-alpha);
24. d[j*3+2]=p[j*3+2]*alpha +t[j*3+2]*(1-alpha);
25. }
26. }
27.}
2.3 多摄像头目标融合
不管是多摄像头立体匹配还是多摄像头图像拼接,本质上都是将多个摄像头的特性整合成一个虚拟摄像头进行检测。这种方法对不同摄像头之间的相互姿态具有较强的依赖性,且计算量较大,无法满足车载芯片对实时性的要求。所以,一种可行的方法是,在每个摄像头完成相应的任务后,再根据任务属性将结果组合起来。例如,每个摄像头单独进行目标和车道线检测,然后将结果组合在一起完成跨摄像头的目标跟踪和车道线跟踪等工作。
如图14所示,单个摄像头进行障碍物(图中蓝色车辆)检测,不同摄像头进行跨摄像头目标跟踪。这种方法可以有效地分配计算资源,提高处理速度,满足实时性要求 。
图 14 同一目标跨摄像头示意图
在进行多目标跟踪前,系统需要根据摄像头的视场角和摄像头的外参来确定摄像头的视场边界(即测距范围),并计算摄像头的共视区域。假设摄像头C₁和C₂存在共视区,两个摄像头检测到的目标的轨迹集分别为T₁和T₂,其中T₁={T₁,i∈(1, …,m)},T₂=T₂,j∈(1, …,n)},m和n分别为摄像头C,和C₂下单摄像头跟踪航迹目标的个数,Ti,和T,表示目标的航迹,每次航迹更新记录都被记为一个节点。该节点包含目标所有属性,如目标类型、距离、速度、加速度、朝向等。利用两个队列中的轨迹构建车辆时空相似性矩阵和车型相似性矩阵,并将两个矩阵加权融合构建跨摄像头轨迹匹配代价矩阵,采用匈牙利算法完成不同摄像头下的车辆目标匹配,实现跨摄像头车辆目标跟踪,获取车体多摄像头系统下目标车辆的全局轨迹。
1. 车型相似性矩阵
前文已经介绍过,车辆类型可以分为汽车、卡车等,所以可以构建一个车型相似性代价函数:
在目标检测精度较高的情况下,同类型车辆匹配代价较小,定义为0;不同类型车辆 匹配的代价较大,定义为10000,这种组合方法可以提高匹配的正确率。我们可以依据该 代价函数构建车型相似性代价矩阵:
Mx={fp(T₁,T₂),i∈(1,…,m),j∈(1,…,n)
2. 车辆时空相似性矩阵
对于跨摄像头共视区,系统需要根据前一个摄像头中的航迹信息来预测目标的轨迹信息。假设某个目标i出现在摄像头C₁ 中但未出现在摄像头C₂ 中,此时会在摄像头C₁ 中形成一条轨迹(记为T₁), 根据T 中最后一个节点判断该目标是否处于共视区边缘,同时根据轨迹T₁ 中节点的平均速度和时间间隔来判断该目标是否进入共视区(即进入C₂ 摄像头)。在进入C₂ 摄像头后,形成一个新的航迹T₂,由此构建车辆目标时空相似性函数:
其中,d₁ 表示轨迹T₁ 形成的向量,d₂ 表示轨迹T₁ 第一个节点与轨迹 T, 第一个节点形成的向量,d₃ 表示轨迹T₁ 最后一个节点与轨迹T₂ 第一个节点形成的向量。
通过轨迹时空距离构建时空相似性矩阵,可以表示为
Smx={f₂(T₁,T₂),i∈(1,…,m),j∈(1,…,n)}
3. 车辆目标关联
基于车型相似性代价矩阵和时空相似性代价矩阵,可以构建加权融合的车辆目标关联匹配代价矩阵。假设两个摄像头之间m 条完成匹配的轨迹和n条待匹配的轨迹之间的匹配代价矩阵为Cmx, 可以表示为
Cmxn=λMxn+(1-λ)Smxn
其中,λ表示车型相似性代价矩阵和时空相似性代价矩阵的权重。由于两个摄像头存在共视区,时空相似性准确率较高,且考虑到共视区的目标截断问题,我们可以动态调整λ的值。
所以,车辆目标关联问题可以转换为带权二分图的最优匹配问题。使用匈牙利算法进行求解,将代价矩阵Cm 输入匈牙利算法进行轨迹匹配,代价矩阵中元素值越小,代表两条轨迹之间匹配概率越大,在匹配结果中选择元素值最小的轨迹进行优先匹配。匹配成功的轨迹T₂ 的 ID 置为与其匹配的轨迹T₂ 的 ID 。当元素值大于设定阈值时,轨迹匹配失败。如果轨迹T₁ 未匹配成功,则表示该车辆目标还未出现在下一个摄像头中,后续再进行匹配处理;如果轨迹T₂ 未匹配成功,则认为该轨迹为自系统开始运行后第一次出现,并将其赋予一个新的轨迹ID。将完成匹配的轨迹从待匹配队列T₂ 中删除,再将下一帧图像跟踪结果中待确认轨迹加入待匹配队列进行匹配,在相邻摄像头下进行轨迹匹配,最终形成大范围实时车辆轨迹图,实现多摄像头实时跟踪。
2.4 多摄像头下的车道线融合
由于车道线属于静态要素,所以在多摄像头融合中,车道线的融合相对于目标融合更为简单。最简单、直接的方法是在车体坐标系下,对车道线进行融合。按照多摄像头的安装位置进行组合,可以分为前视多摄像头下的车道线融合(见图15)和周视多摄像头下的车道线融合(见图16)。
图 15 前视多摄像头下的车道线融合示意图
图 16 周视多摄像头下的车道线融合示意图
前视多摄像头下的车道线融合是指通过在前向布置多个不同FOV的摄像头来检测车道线,并将每个摄像头检测出的车道线转换到车体坐标系下,实现车道线数据融合。由于检测误差以及标定系统误差等因素,这些车道线可能无法有效融合(如图15中红蓝绿车道线代表不同摄像头检测出的车道线)。因此,系统需要对前向不同FOV的摄像头检测结果进行融合处理,以确保车道线的一致性。
周视多摄像头下的车道线融合是指车身周围不同视角的摄像头检测到各视角的车道线信息,并将这些车道线信息转换到车体坐标系下进行车道线一致性判断、关联,以及车道线数据融合。由于检测误差以及标定系统误差等因素,同一条车道线可能会出现岔开等现象,所以我们需要对这些车道线进行融合拼接。
由于车道线最终输出形式是基于车体坐标系的曲线方程,这就意味着需要将所有以曲线方程表示的车道线进行离散化,得到对应的点集后再进行融合,所以不管是周视多摄像头还是前视多摄像头,其车道线融合的方法都一样。
假设有摄像头C₁ 和 C₂, 在车体坐标系下两摄像头检测到某一帧的车道线集表示为L₁和L₂, 其 中L₁={L₁,i∈(1,…,m) |,L₂=L,je(1,…,n)},m 和 n 分别为摄像头C₁ 和C₂中车道线的数目。L₁ 和 L2,包含车道线所有信息,包括车道线曲线方程系数、起始点、 终点、类型、长度等。
对于某一帧车道线,由于不同摄像头探测的视场不同,检测到的车道线类型可能有所不同(如前视摄像头检测为实线、而后视摄像头可能检测为虚线),所以车道线关联最可靠的方法是通过距离进行关联。首先,根据车道线方程的系数将车道线分为左侧和右侧车道线,然后分别对左右侧车道线进行融合,计算两条车道线之间的距离d,并以此构建车道线距离代价矩阵:
其中,thres 表示是否为同一条车道线的阈值,一般设定为0.2m 。f 取值100是为了提高车道线的匹配率。所以,车道线距离代价函数可以表示为:
Lxn={fa(L₁,L₂),i∈(1,…,m),j∈(1,…,n)}
下面给出车道线距离计算的示例代码:
1.template
2.T calculatePolynominal(std::vector
&poly,Tx){ 3.T res =0;
4. for(size_ti=0;i
5. return res;
6. }
7.
8. double calculateDistanceBetweenLanes(Lane detect1,Lane detect2){
9. double a0_t=detect1.c0;
10. double al_t=detect1.cl;
11. double a2_t=detect1.c2;
12. double a3_t=detect1.c3;
13.
14. double a0=detect2.c0;
15. double al=detect2.cl;
16. double a2=detect2.c2;
17. double a3=detect2.c3;
18.
19. double max_dis =std::min(detect2.EndDis truck,detect1.EndDis_truck);
20. double min_dis=std::max(detect2.beginDis_truck,detect1.beginDis_truck);
21.
22. double dis_avg =0;
23. int count =5;
24.
25. double gap =fabs(max_dis -min_dis)/static_cast
(count); 26. for(size_ti=0;i
27. std::vector
poly_t={a0_t,al_t,a2_t,a3_t}; 28. std::vector
poly ={a0,al,a2,a3}; 29. double x=min_dis +i*gap;
30. double dis_t=calculatePolynominal
(poly_t,x); 31. double dis=calculatePolynominal
(poly,x); 32. dis_avg +=fabs(dis_t-dis);
33.
34. dis_avg/=static_cast
(count); 35. return dis_avg>2000?10000:dis_avg;
36.}
在判定为同一条车道线后,系统需要将车道线上的点进行离散化处理。这意味着将判定为同一条车道线的所有曲线函数进行离散化,然后按照车道线拟合步骤进行重新拟合,具体可参见第4章车道线后处理部分。车道线融合前后的示意图如图17所示。
图 17 车道线融合前后示意图
作为传统的视觉感知方法,视觉感知后处理是在图像2D检测的基础上,利用摄像头参数等信息将2D感知结果映射到3D空间,以支持自动驾驶相关的任务。然而,这类传统后处理方法局限比较多,如对路面的平整度、车辆颠簸的敏感度等都有很高的要求。虽然当下大规模和深度学习的发展使得2D 感知技术日益成熟,单目3D感知技术也得到了一定提升(如通过几何假设或者其他方式来估计图像深度信息),但单目3D感知的精度相对较低。
虽然利用深度学习的双目检测方法可以解决单目3D感知精度低的问题,但双目摄像头的视野和距离范围都受到比较大的限制,即只能感知到车辆前方中距离目标,对于远距离目标感知误差较大。对于高级自动驾驶系统而言,双目感知范围仍然不够,它需要探测车身360°范围内的目标和障碍物。为了更好地解决这一问题,系统需要利用深度学习方法将来自多个摄像头的图像从透视图转换到鸟瞰图 (Bird's Eye View,BEV)。
相比于传统的2D感知方法,BEV感知方法可以将多摄像头特征转换到相同尺度和统一的空间 (即BEV空间),在BEV空间完成特征融合并进行检测,直接得到目标的大小和朝向信息。对于遮挡目标,BEV感知方法基于先验知识完成区域预测,脑补出被遮挡区域可能存在的物体;同时还可以结合时序信息,形成4D BEV空间,更好地完成一些感知任务(如测速等),甚至可以直接输出运动预测到下游的决策规控模块。这种端到端的方法既可以避免误差累积,也大大减少了人工逻辑的作用,让感知网络可以通过数据驱动的方式来自学习,从而更好地实现功能迭代。
纯视觉BEV感知系统可以分为3部分:2D特征提取器、视图转换模块(可选)、3D 解码器,图18所示。
图 18 纯视觉BEV感知系统
由于纯视觉BEV感知系统和2D感知系统有着相同类型的输入数据,所以特征提取器可以表示为
F2D(u,v)=Mfeat(I°(u,v))
其中,F20表示2D特征,I表示图像,Me表示2D特征提取器,(u,v)表示2D平面的坐标,*表示一个或多个2D图像对应的特征。
BEV感知系统的核心是视图转换模块,这与2D感知系统存在较大的差异。一般视图转换有3种方法。
1) 2D-3D方法:这种方法是输入2D图像特征,通过深度估计将2D特征提升到3D 空间。最常用到的就是LSS算法(见图19),其在2D特征上预测网络深度分布,然后基于网络深度信息将2D特征映射到体素空间,公式如下:
F₃p(x,y,z)=[F2p(u,0)×D*(ü,0)]y
其中,F₃p表示3D(或体素)特征,(x,y,z)表示这些特征在3D空间中的坐标,F2D表示图像2D特征,(ü,0)表示这些2D特征在图像中的2D坐标,D*(ü, i)表示在点 (ü,0)上预测的图像深度信息,⊗表示外积操作。
图 19 LSS算法架构示意图
2) 3D-2D方法:采用IPM(反透视映射)算法,通过建立3D到2D的投影映射,将 2D特征编码到3D空间。这种方法强依赖于两个假设:乡个是3D空间中的所有点都位于同一水平面上;另一个是它对摄像头的内外参有着强依赖。为了避免对上述两种假设的依赖,在网络中引入Transformer中的交叉注意机制(见图20),同时构建几何投射关系,具体公式如下:
F₃D(x,y,z)=CrossAttention(q:P,kv:F²n(ǜ,0))
图 20 Transformer中的交叉注意力机制在BEV中的应用
其中,q、k、v 分别表示查询 (query) 、键 (key) 、值 (value),P 表示体素空间预定义的锚点。F³0 表示3D空间 (或体素空间) 中的特征,(x,y,z) 表示3D空间中的坐标,F²0表示图像2D特征,(ǜ,0)表示这些2D特征在图像中的坐标。该公式的核心思想是使用3D空间中预定义的锚点作为query, 通过交叉注意力机制从2D特征中获取value。
3) 纯网络方法:不论是2D-3D方法还是3D-2D方法,几何投射过程中都可能引入投影偏差。神经网络可以隐式地获取摄像头的投射关系。很多BEV分割方法采用了多层感知机(MLP) 或 Transformer架构来隐式地建模3D到2D的投射关系。如图20所示的检测网络采用一个多层感知机(MLP) 构建视图关系模块,通过处理多视图输入数据,获得映射视图下的特征,从而获得表征多个视角的共享特征表示。
随着BEV感知算法应用越来越广,传统后处理方法的生存空间越来越小。然而,并不是所有的任务都能被BEV算法覆盖的,如红绿灯识别、交通标识牌分类等。另外,由于BEV 算法覆盖车身周围环境信息的同时,无法兼顾远距离的目标(如100m外) , 所以对于远距离目标测距,我们依然需要依靠传统后处理方法保证感知性能的稳定。对于BEV 算法中的静态要素(如车道线等),我们也需要借助SLAM中的相关传统方法进行静态图的构建。
作者介绍:
韦松,智能驾驶领域的资深技术专家,目前就职于吉咖智能,担任感知算法总监,主要从事自动驾驶感知相关的算法开发和落地工作带领团队完成某热门车型智能驾驶系统的落地和交付。曾就职于挚途科技等多家创业公司,从0到1完成了这些公司的团队组建、技术开发、产品交付等工作,涉及的产品包括智能相机、商用车感知系统、机器人感知系统等。