上一篇文章86. 三维重建21-立体匹配17,端到端立体匹配深度学习网络之如何获得高分辨率的视差图我们讲了端到端深度学习网络中获取高分辨率视差图的各种方法,我们看到这里面有自底向上和自顶向下两大类算法,而我个人最喜欢的还是自顶向下的方法,它与传统的金字塔图像处理算法非常类似,并且在获取到初始视差图后可以根据需要附加特定的信息,来逐层的提升视差图的准确性,这一点又和联合双边滤波、引导滤波这一类的传统算法在精神上高度吻合。
在开始之前,还是让我们再看看我们目前的位置(怎么还没有完 ):
那么我们就开始吧~
我在文章83. 三维重建18-立体匹配14,端到端立体匹配深度学习网络之特征计算中给大家提到过2018年Chang Jia-Ren等在CVPR上发表的文章Pyramid Stereo Matching Network,即PSMNet[2]。
我当时提到"PSM提出了一种使用空间金字塔池化和3D CNN两个主要模块的金字塔立体匹配网络。PSMNet的架构总览如下,这里面左右输入的图像被输入到两个权重共享的分支中,每个分支包含一个用于计算特征图的CNN,一个通过拼接不同大小子区域信息的SPP模块用于收集特征,以及一个用于特征融合的卷积层。然后,这些特征被用来形成一个4D的代价体,这个代价体被送入一个3D CNN子网络中,进行代价体的的正则化,并最终回归计算出特征。这里我们也能从图上清晰地看出,每个输入图对应着自己的特征图。"
虽然PSM当时取得了不错的结果,然而它的架构中包含比较复杂的代价体构造和代价体的聚合步骤,你从上面的图上也看得出来,这就导致了即便使用nNvidia Titan-Xp GPU,这两个关键步骤也需要消耗250ms以上。事实上,在PSMNet的论文中我们可以看到它的速度远远谈不上实时
下面是KITTI 2015和KITTI 2012数据集的结果,注意看最后一列:
事实上,很多端到端的立体匹配算法,在实时性上都不够好,尽管他们在效果上看起来很不错。这也导致现在在工业界,很多时候还在采用SGBM、ADCensus这样的传统算法来做双目立体视觉的核心算法,这些传统算法经过硬件加速后,可以在低价的设备上取得很不错的性能、效果也可堪一用。
那么,基于深度学习的端到端的立体匹配算法,如何才能破解速度慢这个挑战呢?下一节我们来看一些人们尝试过的方法。
2.1 StereoNet采用的逐级迭代细化的思想
正如上一讲提到的获取高分辨率视差图的自顶向下的思想一样,这种思想也被成功应用于实时立体匹配算法中。Google 在 2018 年发布的 StereoNet[3] 就是这一策略的一个典型代表,我们之前也多次提到这个算法:
在StereoNet中,作者通过首先构造一个低分辨率的视差图,随后逐级优化它,有效地加速了整个算法的运行过程。在最终的实现中,StereoNet在Nvidia Titan X GPU上运行时能够达到每秒60帧的处理速度,这一速度表明它能够满足许多实时应用的需求。
这里,逐层细化(Hierarchical Refinement)是一个关键的步骤,用于从粗略的匹配中恢复出细节信息,特别是在图像的边缘部分。这种细化过程是通过一种边缘感知的上采样网络来完成的,该网络能够保持边缘的清晰度,同时提升视差图的精细度。这个细化网络使用双线性上采样的视差图和调整大小的颜色图像作为输入,这样能够减少上采样过程中的伪影。
StereoNet的细化网络通过一个3x3卷积层优化双线性上采样的视差图,增强了32通道的特征的精细度。此网络不仅通过一系列3x3卷积层、批量归一化和Leaky ReLU激活函数增强了这些特征,并且还巧妙地运用了空洞卷积,其扩张因子的多样配置(1, 2, 4, 8, 1和1)允许网络在不扩大模型尺寸的情况下捕捉广泛的上下文信息。这样,网络最终产生的一维视差残差,在叠加到预测上后,ReLU激活函数确保了视差值的正确性。
实验中的层级化细化方法,不仅提高了细化步骤的效果,而且通过连续的优化,显著减少了平均误差,证明了其在实时处理中的实用性。由彩色图像引导的边缘调整,特别是在细化过程中的膨胀或侵蚀,显著提升了视差图的质量,这在图2的逐级改进中得到了体现。这一细化过程不仅增强了StereoNet在捕捉图像边缘和纹理细节方面的性能,还对实时应用中的快速响应能力做出了贡献。StereoNet通过这种层级细化,实现了高精度与实时处理的完美结合,为实时立体匹配提供了一种既快速又准确的解决方案。
我们可以把这种细化过程用伪代码表示如下:
作者还对StereoNet的运行时间进行了细致的分析,我们可以看到其时间消耗的主要分布。如截图中所示的分析图表清晰地展示了各个处理阶段所占用的时间比例。值得注意的是,特征提取、代价立方体构建和滤波等步骤合起来消耗了不到整体计算时间的一半。最为耗时的步骤是在最后一层精细化处理阶段,此阶段独占了总运算时间的38%。这一点揭示了实时立体匹配算法的一个关键瓶颈:即在全分辨率下进行的细化处理。
图中的运行时间分析进一步证明了StereoNet在实时处理方面的潜力。尽管在不同的细化层级上时间分配不均,但整体上该方法能够在720p的图像上实现实时处理。结合图中所展示的精确度与速度的权衡关系,我们可以看出StereoNet在保持高精度的同时,其运行速度也达到了实用标准。
在论文中还有这么一幅图展示了精确度与速度的散点图,它清楚地展现了不同算法及其变体的性能对比。通过对比,我们可以发现StereoNet即使在细化层级较低的情况下也能够保持较高的精度,同时维持较低的运行时间。这种性能的平衡是实时立体匹配在实际应用中变得可行和有用的关键。
2.2 HD3采用的局部离散分布分解方案
2019年UC伯克利大学的Zhichao Yin等人发表的文章Hierarchical Discrete Distribution Decomposition for Match Density Estimation[4] ,简称HD3,则采用固定的从粗到细的过程来迭代地找到匹配
HD3适用于光流和立体匹配应用,为了理解它的思想,我们先来看看一个基本事实。如果我们在对两个1000x1000的经过校正后的图像做立体匹配,并假设可能的视差范围为[-50, 50)。那么根据我之前的文章70. 三维重建5-立体匹配1,立体匹配算法总体理解),我们将需要构建一个包括10^8 108 个元素的代价立方体(1000 * 1000 * 100),即1亿个元素!
如果你是在做光流,那更不得了,此时你的代价立方体将有1000*1000*100*100=100亿个元素,即10^10 1010 个元素!这显然对任何算法来说都是一个计算上的巨大挑战!
那么怎么办呢?作者说,我把任何一点的1维视差或者2维的位移看做是随机整数,那么这个随机数是符合某个分布的,作者用匹配密度来描述这种分布,它细化了每个像素可能位移的概率。匹配密度为我们提供了一个概率框架,用以描述和计算这些随机运动场的统计特性。
接着作者指出,完整的匹配密度可以通过尺度上的层层分解,变成多层次的概率分布函数。比如论文中这张图,你可以看到对于汽车玻璃上的一个像素,在多个尺度下它们分别对应不同层次的概率分布。
作者指出,经过这样的尺度分解后,每一层的匹配密度通常有很低的方差,也就是说概率集中在较小的子集中。这样一来,在解决匹配密度问题时,我们可以只关注这些概率密集的子集,从而在没有丢失太多信息的情况下减少必要的计算量。而最终的视差或光流,则可以通过每一层预测的信息整合到一起。同时,通过最大后验分布方法,能够在保持效率的同时获得满意的匹配密度近似,这对于实时处理系统来说至关重要。
通过这种思想,就能够快速地计算出整个视差图或者光流图。我们来看看论文中下面的比较,可以看到这个算法得到了不错的结果,而不准确的地方一般出现在边缘和遮挡区域,这也在意料之中。
论文中下面这个表格给出了在KITTI数据集上的速度和质量比较。
下面这个表格则是在MPI Sintel数据集上的速度和效果比较。
上面两个表格都说明,当前算法比起之前的算法有大幅度的速度提升,同时效果也超越了很多传统算法,比如下表是StereoNet论文中的速度和效果,你可以看到其中Out-Noc和Out-All两个指标都比 ��3� HD3差很多,时间上也比HD3慢
��3�慢。
这个算法和StereoNet的思想非常相似,都采用了逐层细化来保证速度。我们再来看看下面一个算法StereoDRNet。
StereoDRNet算法[5]来自北卡罗来纳大学教堂山分校及FaceBook的学者发表的论文,我在之前的文章86. 三维重建21-立体匹配17,端到端立体匹配深度学习网络之如何获得高分辨率视差图中也提到过。
为了加速立体匹配算法,StereoDRNet采用了3D空洞卷积,这也是其名称中Dilated Residual的由来。这种卷积能够在计算量几乎减半的情况下,实现更好的效果。比如论文中下面这张图,就展示了输入特征图经过所谓的Vortex池化的过程,这里特征图首先经过不同范围的平均池化,然后经过三种不同间隔的3x3的空洞卷积。这样既能够扩大感受野,又保持了低运算量。
不过这个网络的整体运行速度还不够高,你可以看到它甚至在KITTI数据集上需要两百多毫米才能完成推理。所以读者只需要看到它最核心的优化点是采用了空洞卷积就够了!
2019年由Shivam Duggal等学者发表的DeepPrune论文[6],结合了深度学习与PatchMatch的思想。作者的目标是显著加快立体匹配算法的运行时间,以实现实时推理。为了实现这一目标,他们开发了一个可微分的PatchMatch模块,该模块允许在不需要优化完整的代价立方体的情况下丢弃大多数视差信息。然后就可以利用这种表示方法来学习每个像素的潜在视差范围。通过逐渐减少搜索空间并有效地传播这样的信息,就能够有效地计算高概率的匹配代价,并实现内存和计算的节约。最后,利用图像引导精细化模块来进一步提高性能。由于所有的组件都是可微分的,因此可以端到端地训练整个网络。作者的实验表明,DeepPrunder可以以62ms每帧的速度进行KITTI和SceneFlow数据集的推理,而且还取得了非常不错的效果!
下面这张图说明了这种方法的关键思想,这里你可以看到作者首先是用一个特征提取网络,从两幅图像中提取出多尺度的特征图。接下来,基于特征图利用PatchMatch的思想为每个像素估计一个小的视差范围。然后利用所谓的Confidence Range Prediction(置信区间估计)机制进一步的缩减解空间,再经过3D聚合后,利用一个轻量级的网络对结果精细化,得到最终的视差图。
正如我之前在78. 三维重建13-立体匹配9,经典算法PatchMatchStereo中所提到的,立体匹配的搜索空间很大,但在精确的匹配时,我们可以自信地丢弃大量候选匹配;其次,由于世界的连续性,相邻像素往往具有相似的视差。这表明,一旦我们知道一个像素的视差,我们就可以有效地将这些信息传播给它的邻居。DeepPruner就是利用了这种思想。这里面我们最重要需要学习的思想是所谓的可微分的PatchMatch。
首先让我们来回顾一下PatchMatch[7],我们来看看下面这篇经典论文的思想
论文中提到,当我们在A、B两幅图像之间进行匹配时,PatchMatch算法主要包括下面几步:
DeepPruner在第2、3步之间进行迭代优化,直到收敛或达到某个迭代次数。
为了能够端到端进行立体匹配,作者用循环神经网络来实现了广义PatchMatch,每个循环过程都近似了PatchMatch中的一个迭代,具体来说作者的网络分成了几个层:
总之,通过这种近似PatchMatch的循环迭代方式,DeepPruner可以为每个像素得到一个很小的视差范围。接下来再通过一个置信区间估计网络,进一步为每个像素调整这个范围。这个操作删除了不太可能匹配的空间,使昂贵的代价立方体构建和聚合只在少数视差值下发生。
下图列出了DeepPruner在KITTI2015数据集上的量化结果。这里有两个模型DeepPruner-Best和DeepPruner-Fast,它们分别得到了下采样4倍和8倍的代价立方体。可以看到DeepPruner-Fast只需要61ms即可完成一帧的匹配,而且其误差得分与CRL等需要几百毫秒才能完成推理的算法相当!
实时立体匹配是双目立体视觉能够在实际工程中使用的一个非常关键的议题,人们想了很多方法来加速基于深度学习的立体匹配算法。今天这篇文章仅仅给大家管中窥豹式地看了其中几种方法。
总结起来,今天我们看到了几种方案:
在之后的文章中,我还会为大家介绍更多的优化立体匹配算法的思想。有一些方法能得到的效果和运行速度,真是让人叹为观止!
现在来看看我们的进度:
下面是目前已经讲过的基于深度学习的立体匹配的内容: