点击上方“ 3D视觉工坊 ”,选择“星标”
干货第一时间送达
一. 前言 欢迎你进入我的计算摄影学专栏,最近的很多篇文章我都在讲立体匹配相关的知识。现在让我们打开地图看一看现在所处的位置:经过了很多传统立体匹配算法的学习,我们终于来到了新的篇章:
当前进度 在开始之前,让我们先翻阅一下我们学习过的经典立体匹配算法ADCensus和SGM算法,在Middle Burry立体匹配评价榜上的排名情况。
我们先看看ADCensus,我在文章77. 三维重建12-立体匹配8,经典算法ADCensus中介绍过它,当时我说过“这个算法我个人非常喜欢,因为它的流程非常规范,而且易于理解。简直就像学习了Stefano Mattoccia教授的讲义后,将各个标准组件用当时各种优秀的算法实现并串联起来的作品”。不过在最新的Middle Burry排行榜(地址:https:// vision.middlebury.edu/stereo/eval3/ )上你是找不到ADCensus的,你得进入到更老版本的排行榜https://
vision.middlebury.edu/stereo/eval/ ,才能看到ADCensus,估计是算法太早了。在这个非常简单的评价数据集上,ADCensus排名第6。
ADCensus在MiddleBurry早期排行榜上的位置 为了评估它在最新排行榜上的水平,我们观察到在它之前有一个叫做TSGO的算法,恰好TSGO可以在最新排行榜上找到,在bad1.0指标上排名第189位,bad1.0=63.7,也就是说在最新的测试数据集上TSGO有63.7%的像素的视差估计误差超过1个像素。虽然我们不能直接说ADCensus在最新排行榜上就一定差于TSGO,但至少可以间接的说明ADCensus的评分也好不到哪里去。
TSGO在MiddleBurry排行榜上的位置 我们再来看看SGM,我在文章72. 三维重建7-立体匹配3,立体匹配算法中的视差优化中也介绍过它的思想。而作者大佬Heiko Hirschmüller在Stereo Processing by Semi-Global Matching and Mutual Information这篇文章中,完善了SGM的流程,得到了更高效实用的SGM算法。那么它在Middle Burry最新排行榜的情况如何呢?看看下表,我们看到SGM算法在Half分辨率上bad1.0=31.1,排行101位,在Full分辨率上bad1.0=35.8,排行118位。虽然我猜测比ADCensus可能会好点,但误差依然很大。
SGM在MiddleBurry排行榜上的位置 我们看看排名前三位的算法在全分辨率下bad1.0误差百分比都在10以内,这就是差距!
SOTA算法的误差百分比 现在我们来思考一个问题:经典的SGM、ADCensus这些算法,到底为什么技不如人?如何改进它们的效果呢?
二. 传统算法的局限性 让我们观察一下SGM的效果,下面是“摩托车”这个图像中,SGM结果和Ground Truth结果的对比
SGM vs GT - Motorcycle 我们可以清晰的看到,在边缘、镂空、平摊区域,SGM算法出现了不少的错误,一些小细节错误也比较明显,比如摩托车的把手
SGM vs GT - Motorcycle, 细节 而我在文章77. 三维重建12-立体匹配8,经典算法ADCensus中给出的开源ADCensus实现,得到的效果如下
ADCensus vs GT 虽然在摩特车把手区域表现更好,但是地面却是凹凸不平的,而且在镂空部分,比如摩托车的轮胎的镂空,显然还有很多问题。
ADCensus vs GT, 细节 很显然,尽管SGM和ADCensus在当时都是很优秀的算法,而且都很有实用性。但他们确实有一些固有的缺陷:
它们的场景处理能力有限。在处理遮挡、缺乏特征的区域或具有重复纹理的高纹理区域时,往往表现不佳。
它们很难利用场景的先验知识:SGM和ADCensus都暴露了很多可以调节的参数。为了在某个场景达到最佳效果,通常是通过人类观察场景特点,将这些特点转换为某种先验知识,并据此调整相关参数来达到最佳效果。当场景图像特别丰富复杂时,这个过程是很难收敛的,很耗时耗力。
很难利用上数据集提供的理想视差图。像Middle Burry、KITTI这样的数据集都提供了理想视差图——这本身也是先验知识。但SGM、ADCensus这样的算法都很难利用上这么优质的先验知识,通常我们只是在做算法结果评价时,才会和理想视差图作对比。而算法的设计、研发过程中很难成规模的用上数据集提供的理想视差图。
那么,有没有办法做得更好呢?这就是我们下一节想要讲的。
三. MC-CNN ——深度学习的立体匹配算法的缘起 很多读者都知道,从2012年开始,深度学习算法就开始在计算机视觉领域大放异彩。当年Hinton等人提出的AlexNet在ImageNet图像分类比赛中取得了惊人的成绩,将错误率降低了近15个百分点。这个突破性的成果引起了广泛的关注,并且促进了深度学习在图像处理领域的快速发展。自那以后,深度学习已经成为图像处理领域的主流方法,并在许多任务上取得了优秀的结果。
深度学习的这种突破很快蔓延到了立体匹配这样的领域,我们刚才提过的SGM、ADCensus这样的传统算法的缺陷,深度学习都带来了更好的解决方案。
3.1 基本思想 让我们先回顾ADCensus的基本流程,你会发现它是由一个个非常容易理解的子部分组成的,而整个流程的第一步是代价计算,它先提取图像的AD+Census特征,然后再比较左右两图中的特征。
ADCensus算法流程 一种非常简单、直接、粗暴的利用深度学习改善最终效果的方式,就是选择其中某个、或者某几个模块用深度学习方式替换,得到更鲁棒的效果——这也是今天我要介绍的两篇文章Computing the Stereo Matching Cost with a Convolutional Neural Network及Stereo Matching by Training a Convolutional Neural Network to Compare Image Patches的思想。
MC-CNN原始论文 这两篇文章的作者都是Jure Zbontar和Yann Lecun,后者我想很多读者都非常熟悉了,他是深度学习领域的先驱之一,也是Facebook人工智能研究院的创始人之一,在多个领域都做出了重要的贡献,而Jure Zbontar是他在纽约大学计算机科学系的博士后研究员。通过这两篇文章,作者介绍了一种叫做MC-CNN的算法,这可以认为是基于深度学习的立体匹配算法的鼻祖了。
在这两篇文章中,他们明确的写道:
In order to meaningfully evaluate the matching cost, we need to pair it with a stereo method. The stereo method we used was influenced by Mei et al. [11] The stereo method we used was influenced by Mei et al. (2011) and comprises cross-based cost aggregation, semiglobal matching, a left-right consistency check, subpixel enhancement, a median, and a bilateral filter. 也就是说,他们除了替换了开始的代价立方体的计算过程外,MC-CNN的其他流程和ADCensus的完全一致。那么效果呢,我们看看论文中列出的在三个数据集上的效果对比
首先是在KITTI2012数据集上的对比,其中MC-CNN的两种架构(快速架构和准确架构)误差远低于基于Census特征的传统流程。
KITTI 2012, MC-CNN效果展示 下面是KITTI2015数据集上的对比,我们观察到了同样的结论:
KITTI 2015, MC-CNN效果展示 在MiddleBurry数据集上,MC-CNN的两种架构,特别是准确架构,更加展示了困难区域的匹配准确性提升
MiddleBurry, MC-CNN效果展示 要知道整个MC-CNN的架构和ADCensus都是一致的,仅仅是代价立方体的计算过程构建在深度学习的基础上。那么,他们提出的代价立方体的计算过程到底是怎样的呢?
我们先来回顾一下基本的基于固定支持窗的代价立方体计算过程,这在我的文章70. 三维重建5-立体匹配1,立体匹配算法总体理解中有详解:
固定支持窗代价计算过程 最简单的代价计算的过程可以用下面的公式描述:我们从左图选择一个图像块S,在右图根据当前选择的视差d找到对应的图像块,然后计算这两个图像块的差异。如果两个像素刚好是对应点,那么图像块之间的差异应该很小,而如果两个图像块不是对应点,那么图像块之间的差异应该很大。
代价立方体计算公式 两位作者很敏锐的观察到,这个过程可以转换为一个2分类问题——我们要做的就是当给出两个图像块时,它们到底是匹配还是不匹配的,匹配为正,不匹配为负。这样就把立体匹配的代价计算问题转换为了当时深度学习已经取得突破性进展的图像分类或图像识别问题了,我们还是画出其中的底层逻辑吧:
代价计算问题转换为图像分类识别问题 3.2 代价计算网络 我们可以借用下面这幅图,来总结这两篇文章的代价立方体的计算过程:计算代价时,首先从左图取得一个像素I_l(x, y),根据当前的视差d,求得对应在右图的像素q = I_r(x -d, y)。取这两个像素点所在的固定大小的图像块,分别送入到由CNN模块构成的特征提取模块中。当得到特征图后,两个图像块的特征图会被送入到决策网络中,最后输出两个图像块的相似度、或者不相似度。
MC-CNN网络总体结构 在2015年的文章Computing the Stereo Matching Cost with a Convolutional Neural Network中,他们给出的网络结构图如下,非常简单直观,左右两个块会被送入共享权重的两个特征提取网络中,在第3层输出的特征图会在通道维度连接在一起,送入到一堆全连接层中,最终网络会在第八层后输出这两个块相似、或者不相似的SoftMax概率。
MC-CNN早期结构 而在计算代价时,论文中提到的公式如下,即采用网络输出的负类概率作为当前的匹配代价,两个块越不相似,负类概率越高,匹配代价越大。反之则匹配代价越小。
MC-CNN代价计算方法 而在2016年的Stereo Matching by Training a Convolutional Neural Network to Compare Image Patches中,他们提出了两种网络结构,对上面的算法做出了改进:
MC-CNN的两种结构 快速架构和准确架构,跟上一篇文章一样,都是先通过共享权重的特征提取CNN取得特征图(或特征向量)。这些用于特征提取的CNN构成了孪生网络。对于快速架构而言,提取到的归一化后的特征向量会直接进行点积操作,得到两个向量的余弦相似度。而准确架构里面,两个特征图先在通道维度连接在一起,然后通过一系列全连接层,最后通过Sigmoid操作转换为一个相似度评分。由于准确架构里面,分类决策是通过学习得到的,而快速架构里面则是固定的余弦相似度,所以准确架构的最终结果会比快速架构更好,与之相对的则是速度会更慢一些。
MC-CNN的两种结构效果对比 3.3 数据集和网络优化过程 作者使用KITTI或者Middle Burry数据集,来构造训练上面的网络所需要的数据集。当输入一对图像和对应的视差图时,我们可以知道输入的左图中每个像素的真实视差。对左图中的每一个像素p,作者会随机的提取一个正样本和负样本。2015年的论文是这样描述正样本或者负样本的,这代表着从左图和右图中分别提取以p和q为中心的9x9的小块.
其中Nlo, Nhi, Phi ,生成的样本数量n,都是可以设置的参数。你可以看到,这样的方法可以生成巨量的图像对。在论文中他们提到从KITTI2012的194对训练集中,提取了4500万图像对用于训练,正负样本各占一半。
对于快速架构,作者通过优化Hinge Loss来训练,MC-CNN-fst算法的训练过程通过最小化 hinge loss 函数实现。计算时我们需要考虑到围绕相同图像位置的正负样本对。其中一个样本属于正类,另一个样本属于负类。设 s+ 表示网络对于正样本的输出,s− 表示网络对于负样本的输出,m 是一个正实数,表示 margin。对于这一对样本,使用 hinge loss 函数定义为 max(0, m + s−− s+)。当正样本的相似度至少比负样本相似度高出 margin m 时,损失函数为零。在实验中,作者将 margin 设为 0.2。
准确架构的网络优化过程则不一样,作者用了二元交叉熵损失函数进行训练,损失函数被定义为t log(s) + (1 − t) log(1 − s),t代表类别(t=1代表输入样本属于正样本,t=0代表输入样本属于负样本)。这和常见的图像分类问题更加相似。
你可以看到,两种架构用了两种不同的损失函数,这都是基于经验和数据实验结果得出的结论。在论文中,作者对网络的训练过程有详细的描述,这些信息比较枯燥,我就不浪费笔墨了,感兴趣的读者可以参考原文。我们现在来仔细看看代价计算的过程。
3.4 代价计算过程 我们有了分类网络后,计算代价的naive过程跟传统立体匹配算法流程是一致的,可以用下面的伪代码来描述。
你可以看到这里对于每一对图像块,都需要执行网络的推理过程一次(函数mc_cnn.cost),显然是很耗时的。论文中说明了3个技巧,可以大大降低耗时:
对于每个位置,只需要计算两个子网络的输出一次,而不需要为每个视差值重复计算。这样可以避免计算量过大,节省时间和空间资源。
可以通过传播全分辨率图像而不是小图像块,一次性计算所有像素的输出结果。这样做可以减少前向传播的次数,因为许多中间结果可以被重复使用,从而加快了计算速度。
对于准确架构,可以使用 1 × 1 的卷积核代替全连接层,一次性计算出所有输出。这是通过将每个全连接层替换为一个具有 1 × 1 的卷积核的卷积层来实现的。
如果使用这样的技巧改进代码,我们可以分别得到快速架构和准确架构计算代价立方体的代码:
3.5 排名情况 MC-CNN一经发布,就在KITTI、MiddleBurry等榜单中获得了高分,下面是2015年10月份时两种架构在不同的榜单中的排名情况:
KITTI 2012
KITTI 2015
MiddleBurry
四. 总结 今天我介绍了最开始使用深度学习来进行立体匹配的方法MC-CNN。我在此总结几点其中的思想:
正如我最早时提到的,立体匹配是一个让计算机做“连连看游戏”的过程。我们本质上是在比较图像块与图像块之间的相似度。
Jure Zbontar和Yann Lecun正是在理解了上述本质后,将立体匹配的代价计算问题转换为了深度学习中的分类问题。这是一个将未知问题转换为已知问题的过程。
MC-CNN虽然是第一代基于深度学习的立体匹配算法,但一经推出就霸榜了KITTI、MiddleBurry等榜单,展现出深度学习方法的强大威力。但因为它仅仅替换了整个立体匹配pipeline中的特征提取和代价计算部分,所以整体效果还不能说特别惊艳,还有很多待解决的问题。比如不管是哪种架构的MC-CNN,我们都能明显看出一些缺陷。这也是我之后要介绍的算法需要解决的问题。
MC-CNN效果对比