到目前为止,我已经介绍了很多立体匹配技术,它利用两幅图像的视差来重建三维场景。我们可以把立体匹配技术用在很多领域,像我所讲的将它应用在手机上进行大光圈的虚化渲染,它还可以用在三维目标检测、自动驾驶、虚拟现实等很多领域。
人们提出了很多立体匹配算法,它们的匹配质量也越来越高。特别我之后会详细描述的SOTA级别的立体匹配算法,它们的结果简直让人叹为观止!
然而,即便是最优秀的算法,也无法做到百分之百的正确匹配——这是由于这个算法的本质缺陷导致的。我在这个系列的第一篇文章70. 三维重建5-立体匹配1,立体匹配算法总体理解中就给大家展示了很多困难的情况,这里让我们再次回顾一下这些立体匹配的困难
在实际场景中,可以同时包含了以上多种困难之处,甚至还会出现标定及立体校正导致的极线不对齐的情况,因此就像我刚才所讲,即便是最佳的立体匹配算法,也可能产生错误的匹配。
由此,我们有必要为立体匹配的结果引入置信度,当某些像素的视差置信度很低时,可以被判断为错误的匹配,然后用邻域像素的视差值来替换。这样可以避免将错误的匹配引入到后端的应用。另外,还可以将置信度整合到视差的优化过程中,指导视差优化模块得到更好的视差图。
作为一个示意,下面这个视频是本人的视差图 ,以及对应的置信度图
那么,如何才能估计立体匹配的视差图的置信度呢,怎么把置信度图整合到视差优化过程呢?本篇文章先给大家看几篇典型论文的方法,算是一个热身吧。接下来我还会再撰写一些文章,做深入的探讨。
如之前好几篇文章一样,今天的文章也大量参考引用了参考文献[1],再次对作者表示敬意!
传统的置信度判别方法,一般是通过在输入图像、输入视差图、匹配代价等中去寻找特殊的特征,作为匹配结果优劣的判据。我们来看看下面这篇文章介绍的内容
这篇文章里面展示了理想的匹配结果和可能导致错误的匹配结果之间的差异
左图是理想的匹配结果,横轴是视差值,纵轴是匹配代价。理想的匹配结果拥有一个唯一的最低点,而且这一点和其他点的代价具有明显的差异。
右图是实际中包含某种不确定性的匹配结果,我们看到代价曲线弯弯曲曲,具有多处不明。比如c1点是全局最低点,但它和旁边的第二最低点c2之间的代价差异并不大。另外c2m是第二个局部最低点,与c1的代价相差也不大。
这个示意图给了我们一些直觉,优质的匹配和不确定性的匹配之间的差异可以体现在匹配代价曲线上!
实际上,这篇文章给出了几种用于判断匹配优劣的信息来源,作者把它们分成了5组:
上面第5点我在73. 三维重建8-立体匹配4,利用视差后处理完善结果一文里面也详细描述过,通常一个简单的左右交叉检查,就可以起到很大作用:
3.1.1 一种基于Patch的置信度计算方法
正如计算机视觉的很多领域的情况一样,置信度的传统计算手段在很多时候效果都不是很好,既然立体匹配技术本身已经从传统算法演进到了基于深度学习的算法,那么与之相应的置信度图的计算,也可以一样利用深度学习来完成。
我们来看看下面这篇2016年的文章[2],它给出了一个很不错的示范,可以逐Patch计算出稠密的置信度图
作者首先引用一些文章指出,由于我们这个世界具有空间中的连续性,所以在一个像素的局部窗口内,视差值应该也是相似的。如果我们发现窗口内的局部视差值具有很大的变化,那么此时的匹配结果很可能不靠谱。
好了,那么现在如果有一个输入的从左图到右图的视差图,当我们要判断某个像素的匹配优劣时,可以以这个像素为中心取一个小窗口,计算窗口内每个像素的视差值与该像素的视差差异,这样我们可以构成一个以这种视差差异为值的二维视差块,就是下面图中的p1
在第二节我讲过,左右视差图应该具有一致性,可以利用这种一致性来判断匹配的优劣。那么接下来要做的第一步,是把右视差图映射到左图的坐标上:
好了,接下来计算基于右视差图的视差块就比较容易了
这个视差块信息编码了左右视差的一致性,比如作者列出的下图中,(b)是映射后的右视差图,(a)是左视差图。良好的匹配像素的左右视差值是一致的,对应着置信度图中的浅色区域,而像墙面、天空这些匹配困难的区域,视差值则不一致,也就对应着置信度图中的深色区域。
好了,现在我们有了两个视差块p1和p2,我们可以在通道方向把它们连接在一起,送入一个神经网络,进行匹配正确或者错误的判断了。作者论文里面给出的图示如下,选择的视差块的大小是15x15,经过简单的几层,最后送入到全连接层和SoftMax层,输出二分类的伪概率作为最终的置信度。
这种形式,非常类似我们一开始在文章81. 三维重建16-立体匹配12,深度学习立体匹配之 MC-CNN中看到的,基于Patch的立体匹配的方案。只要选择一个具有理想视差图的数据集,就可以根据上面的思想,从中采样一些视差块,用于训练。训练后的模型就具有对任何一个像素输出置信度的功能了。
正如我们在描述基于Patch的立体匹配时所说,这类方法最大的问题是速度慢,因为每一个Patch都需要单独的进行计算,无法做到对全图推理一次性输出整个置信度图。那么如何改进,使得可以做到一次推理输出完整的置信度图呢?
我们重新审视上面的公式(1)和公式(2)会发现,之所以需要每个Patch单独计算一次,是因为我们总是需要减去中心像素的视差,很难把这个操作直接转换为一个卷积操作(至少比较麻烦)
所以,作者又提出了下面这种视差块的计算方法,它比上面的更快,不需要单独计算每个像素的视差块,使得可以简单的卷积就可以完成计算整个置信度图。
公式(1)和(2)中得到的视差块,作者称为Disposable Patch,而公式(3)中得到的视差块,作者称为Reusable Patch,作者还提出可以把两种方式结合在一起,提供精度和速度上的平衡:
3.1.2 将置信度图和SGM整合到一起对视差图进行优化
除了刚才讲到的基于Patch进行的置信度图计算,这篇文章有意思的地方还在于作者提出了一种将置信度图和SGM结合在一起,对视差图进行优化的框架。
我在文章72. 三维重建7-立体匹配3,立体匹配算法中的视差优化中给大家提到过基于半全局匹配的视差优化方法,这种方法尝试整合多个扫描线方向的匹配代价进行最小化,达到优化匹配结果的目的
需要优化的能量函数可以描述为:
这里C(x, Dx)(�,��) 代表着当视差值为时的匹配代价,所以整个能量函数的第一项是所有像素点的匹配代价之和。第二项,当相邻像素的视差值像差1时,我们认为是潜在的倾斜平面,此时用惩罚代价P1来增加这种情况下的匹配代价值,本质上是认为一个局部窗口包含倾斜平面的概率比纯平面的概率低,所以需要用P1来惩罚把纯平面当做倾斜平面的情况。第三项,当邻域像素的视差值大于1时,只可能出现在视差不连续区域。如果仅仅是因为一个图像上因为颜色跳变、亮度跳变,在邻域中算出了不一样的视差值,显然是不正确的。所以要用一个P2来惩罚这种情况。
SGM的原理就是这样的,它在很多论文里面都得到了使用,并且取得了不错的效果。那么这里很关键的一个问题就在于如何设置两个惩罚参数P1和P2。现在我们看看作者是如何将置信度图和SGM结合起来的。
就像我上面讲的,如果一个局部窗口内部出现了视差值的不连续,是什么情况呢?两种情况:
在这种情况下,作者认为应该根据置信度图来调制P1和P2的值。置信度高的,惩罚系数低,置信度低的,惩罚系数更高。于是,作者用下面的方式来设置两个惩罚系数:
这里面\xi(x)) 代表归一化到0到1之间的置信度,m和lambda则是两个参数。具体的公式解读,可以参看原始论文,但我们只要仔细观察一下上面的式子,就会看出,当置信度�)大时,惩罚系数会变小,这就是作者的核心思想。
在论文中,作者专门列出了下面这幅图,来说明当使用了置信度来优化SGM的惩罚系数时,最终的视差图明显变得更好——黄圈内原本的错误匹配没有了,而不使用置信度来辅助优化时,这里明显有错误。
后面作者还列出了他们的方案在KITTI2012和KITTI2015上的结果,具体来说是先用MC-CNN-acrt(忘了这个算法的可以重新看之前的文章81. 三维重建16-立体匹配12,深度学习立体匹配之 MC-CNN)进行左右图立体匹配得到视差图和代价,然后利用这些信息计算置信度图,利用置信度图结合原有的后处理流程进行更好的视差优化。在这两个数据集上,这样的方案都取得了非常好的结果。
下面是论文中的两个示意图:
刚才我们看到的文章,可以认为是将视差图的优化分为了计算置信度图+视差图优化这两部分,前者可以变相认为是一个检测正确匹配像素(或检测错误匹配像素)的任务,后者是一个根据前者的结果,优化视差匹配结果的任务。
那么,接下来,我们看看第二篇文章[3],这篇文章系统的探索了多种利用置信度图进行包括视差图等一切可能的稠密图像精细化的方案,然后提出了一种通用的框架。
我们以视差图优化举例子,作者指出,有多种联合输入的彩色图像对视差图进行优化的方案,大体上可以分为两类,要么是直接通过神经网络给出优化后的结果,即下图中的模式2,要么是通过神经网络预测出残差,然后原始视差图+残差得到优化后的视差图,即下图中的模式1.
而这篇文章的作者则指出,这两种方案都不是最优的。相反,作者将视差图的优化分成了三个子任务:
我截取论文中的下图,来说明作者的思想:
浓缩论文中的关键步骤,可以用下面几个公式来描述:
作者指出,只要将3个模块都用可微分的神经网络来实现,就可以实现端到端的训练,达到好的效果。另外作者还和其他的模式做了对比,发现这种细分子任务的方法能得到更好的效果。下面我再列出论文中的图3,能看到整个过程的细节。
作者还指出,上面的3步不仅仅可以做一次,还可以做多次,这样就构成了迭代式的优化方案,可以取得比单次优化更好的效果。
从原理上我个人是比较认可作者这种思想的,正好我最近在搞dTOF稀疏深度联合输入图像进行稠密化的工作,我也会实验这种方案。
下面这篇我要介绍的是[4]
作者指出,传统的算法利用左右一致性来检测出视差图中的缺陷,然后利用一系列人工设计的视差优化方法来改进视差图——这种方法的结果是不够好的,一方面结果不够好,一方面还需要外部输入视差图。作者提出了一种模型,即所谓“左右比较循环模型(Left Right Comparative Recurrent Model - LRCR Model)”,能够将视差图的生成和左右一致性检测等统一到同一个流程中,得到更好的结果。
我们看看下面这幅图,就能理解作者的意图:
这里,整个流程的每一步骤都涉及到对两个视图的所谓堆叠卷积长短期记忆网络(Stacked ConvLSTMs)的操作。这些网络分别以对应视图的匹配代价立方体(matching cost volume)和在上一步骤中获得的该视图的误差图作为输入。然后,生成的视差图之间进行比较,以产生将在下一步骤中输入模型的两个视图的误差图。这些误差图充当软注意力指导(soft attention guidance),使得模型能够选择性地改进特定区域。
左右视差图的具体比较方式如下图所示:首先,预测的视差图(即DL和DR)被转换到相反的坐标中,以获得用于比较的视差图(即D′L和D′R)。然后,DL和D′L输入到一个包含几个卷积层的简单网络中,以学习左视图的误差图EL,作为比较输出。对右视差图也执行同样的操作。这一过程使得模型能够识别和纠正预测视差图中的潜在误差,进而提高视差估计的准确性。
通过RNN架构,整个过程迭代式的进行,因而视差图会越来越准确,直到停止迭代。我们可以看看论文中下面的图表,就更加理解了
总体来说,这个方案有下面的优点:
不过,由于使用了这种循环迭代的方式,速度也就很慢了,论文中有一个表格很能说明这个慢的问题:
今天这篇文章中,我给大家介绍了几个在立体匹配过程中进行置信度计算,并且利用置信度优化匹配结果的方法,我总结其中的思想如下:
关于立体匹配中的置信度生成和使用,还有更多的信息,我会在下一篇文章中为大家体现