立体匹配是立体视觉研究中的关键部分,其目标是在两个或多个视点中匹配相应像素点,计算视差。双目摄像头类似人眼的工作原理,对同一目标可以形成视差,用来感知三维世界,由于成本远低于激光雷达,因此在自动驾驶领域被广泛研究。
SGM(semi-global matching)是一种用于计算双目视觉中视差的半全局匹配算法。在OpenCV中的实现为semi-global block matching(SGBM)。
SGBM的思路是:通过选取每个像素点的disparity,组成一个disparity map,设置一个和disparity map相关的全局能量函数,使这个能量函数最小化,以达到求解每个像素最优disparity的目的。
本文梳理了SGM算法的各步骤的实现细节,帮助快速理解算法中每一步到底在做什么。已知,左右两张矫正过的双目相机图片。left_img, right_img。
1,图像前处理,Census变换
left_img, right_img按(5*5)窗口,stride=1滑动,得到各自Census变换的二维矩阵。其中,原图像的左右各补pad=2,维持滑动之后二维数组宽高不变。
census变换是指,窗口所有数据依次和其中心点数据相比,大于为1,小于等于为0,窗口按照左右,上下的顺序,组成一个5*5=25长度的二进制序列,即为该窗口的census变换数。
汉明距离是指,两个二进制数异或操作,即不同的bit对应个数。
census变换与汉明距离示意图:
2,代价计算
以左图为标准,计算右图和左图同样坐标位置的census值的汉明(hamming)距离。设置视差范围d,得到一个h,w,d的三维矩阵cost。
视差范围d在第三维,这样对应:逐行遍历,假设P的二维坐标为(x,y),点P的d_range代价计算为:
cost[x,y,0] =hanming_dis(L[x,y], R[x,y])
cost[x,y,1] =hanming_dis(L[x,y], R[x-1,y])
cost[x,y,2] =hanming_dis(L[x,y], R[x-2,y])
cost[x,y,d-1] =hanming_dis(L[x,y], R[x-(d-1),y])
3, 代价聚合
如果没有代价聚合,得到的视差图有很多噪声,所以,分别计算每个像素不同角度的代价值,然后加权综合考虑,会得到很大的优化。经典聚合策略有:4路径聚合,8路径聚合,16路径聚合。
下图左边是按不同方向聚合的示意图,右图是以左→右聚合为例,像素P在d视差上的代价计算示意图。
这一步需要根据选择几路径,来更新每个路径的代价矩阵。
左右的话,P-r就是同一行的前一个像素,或者同一行的后一个像素
上下的话,P-r就是同一列的上一行像素,或者同一列的下一行像素
p1,p2是超参数; C(p,d)表示p像素,d视差的代价,
如果是4路径聚合的话,就是左右,右左,上下,下上的四个路径的代价矩阵对应坐标位置值相加,就是最终聚合的代价矩阵。
4, 视差计算
采用WTA(Winner Takes All)赢家通吃算法。就是每个像素位置在所有视差范围内找到一个代价值最小值,其所在的index就是该像素的最终视差,是一个二维矩阵。
5,视差优化
优化目的:
- 提高精度
- 剔除错误
- 弱纹理区优化
- 填补空洞
提高精度:前面的视差计算步骤中,我们选择最小代价值对应的视差值,它是一个整数值(整数值我们才能有离散化的视差空间W H D WHDWHD),即整像素级精度,而实际应用中整像素精度基本无法满足需求,必须优化到子像素精度才有意义。
剔除错误:即剔除错误的视差值,比如a像素本应和b像素是同名点,而结果却是a像素和c像素是同名点,这就是错误的视差值。造成错误匹配的原因有遮挡、弱纹理等,所谓错误是永恒的,完美是不存在的。
弱纹理区优化:弱纹理区域是所有立体匹配都会面对的难题,极端情况下,一块白墙,怎么找同名点?SGM提出的是一种基于图像分割+平面拟合的处理弱纹理的方法。
填补空洞:剔除错误匹配后,被剔除的像素会造成无效值空洞,如何填补使视差图更加完整也是优化所研究的内容。
优化手段
子像素拟合,一致性检查,唯一性约束,剔除小连通区,中值滤波
参考:(博文很细致,有具体代码实现)文章来源:https://www.toymoban.com/news/detail-465300.html
【码上实战】【立体匹配系列】经典SGM:(1)框架与类设计_李迎松~的博客-CSDN博客_sgm立体匹配文章来源地址https://www.toymoban.com/news/detail-465300.html
到了这里,关于双目立体匹配算法SGM步骤拆解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!