点击上方“3D视觉工坊”,选择“星标”
干货第一时间送达
作者丨HawkWang
来源丨计算摄影学
点击进入—>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。
为了评估它在最新排行榜上的水平,我们观察到在它之前有一个叫做TSGO的算法,恰好TSGO可以在最新排行榜上找到,在bad1.0指标上排名第189位,bad1.0=63.7,也就是说在最新的测试数据集上TSGO有63.7%的像素的视差估计误差超过1个像素。虽然我们不能直接说ADCensus在最新排行榜上就一定差于TSGO,但至少可以间接的说明ADCensus的评分也好不到哪里去。
我们再来看看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可能会好点,但误差依然很大。
我们看看排名前三位的算法在全分辨率下bad1.0误差百分比都在10以内,这就是差距!
现在我们来思考一个问题:经典的SGM、ADCensus这些算法,到底为什么技不如人?如何改进它们的效果呢?
二. 传统算法的局限性
让我们观察一下SGM的效果,下面是“摩托车”这个图像中,SGM结果和Ground Truth结果的对比
我们可以清晰的看到,在边缘、镂空、平摊区域,SGM算法出现了不少的错误,一些小细节错误也比较明显,比如摩托车的把手
而我在文章77. 三维重建12-立体匹配8,经典算法ADCensus中给出的开源ADCensus实现,得到的效果如下
虽然在摩特车把手区域表现更好,但是地面却是凹凸不平的,而且在镂空部分,比如摩托车的轮胎的镂空,显然还有很多问题。
很显然,尽管SGM和ADCensus在当时都是很优秀的算法,而且都很有实用性。但他们确实有一些固有的缺陷:
它们的场景处理能力有限。在处理遮挡、缺乏特征的区域或具有重复纹理的高纹理区域时,往往表现不佳。
它们很难利用场景的先验知识:SGM和ADCensus都暴露了很多可以调节的参数。为了在某个场景达到最佳效果,通常是通过人类观察场景特点,将这些特点转换为某种先验知识,并据此调整相关参数来达到最佳效果。当场景图像特别丰富复杂时,这个过程是很难收敛的,很耗时耗力。
很难利用上数据集提供的理想视差图。像Middle Burry、KITTI这样的数据集都提供了理想视差图——这本身也是先验知识。但SGM、ADCensus这样的算法都很难利用上这么优质的先验知识,通常我们只是在做算法结果评价时,才会和理想视差图作对比。而算法的设计、研发过程中很难成规模的用上数据集提供的理想视差图。
那么,有没有办法做得更好呢?这就是我们下一节想要讲的。
三. MC-CNN ——深度学习的立体匹配算法的缘起
很多读者都知道,从2012年开始,深度学习算法就开始在计算机视觉领域大放异彩。当年Hinton等人提出的AlexNet在ImageNet图像分类比赛中取得了惊人的成绩,将错误率降低了近15个百分点。这个突破性的成果引起了广泛的关注,并且促进了深度学习在图像处理领域的快速发展。自那以后,深度学习已经成为图像处理领域的主流方法,并在许多任务上取得了优秀的结果。
深度学习的这种突破很快蔓延到了立体匹配这样的领域,我们刚才提过的SGM、ADCensus这样的传统算法的缺陷,深度学习都带来了更好的解决方案。
3.1 基本思想
让我们先回顾ADCensus的基本流程,你会发现它是由一个个非常容易理解的子部分组成的,而整个流程的第一步是代价计算,它先提取图像的AD+Census特征,然后再比较左右两图中的特征。
一种非常简单、直接、粗暴的利用深度学习改善最终效果的方式,就是选择其中某个、或者某几个模块用深度学习方式替换,得到更鲁棒的效果——这也是今天我要介绍的两篇文章Computing the Stereo Matching Cost with a Convolutional Neural Network及Stereo Matching by Training a Convolutional Neural Network to Compare Image Patches的思想。
这两篇文章的作者都是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特征的传统流程。
下面是KITTI2015数据集上的对比,我们观察到了同样的结论:
在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模块构成的特征提取模块中。当得到特征图后,两个图像块的特征图会被送入到决策网络中,最后输出两个图像块的相似度、或者不相似度。
在2015年的文章Computing the Stereo Matching Cost with a Convolutional Neural Network中,他们给出的网络结构图如下,非常简单直观,左右两个块会被送入共享权重的两个特征提取网络中,在第3层输出的特征图会在通道维度连接在一起,送入到一堆全连接层中,最终网络会在第八层后输出这两个块相似、或者不相似的SoftMax概率。
而在计算代价时,论文中提到的公式如下,即采用网络输出的负类概率作为当前的匹配代价,两个块越不相似,负类概率越高,匹配代价越大。反之则匹配代价越小。
而在2016年的Stereo Matching by Training a Convolutional Neural Network to Compare Image Patches中,他们提出了两种网络结构,对上面的算法做出了改进:
快速架构和准确架构,跟上一篇文章一样,都是先通过共享权重的特征提取CNN取得特征图(或特征向量)。这些用于特征提取的CNN构成了孪生网络。对于快速架构而言,提取到的归一化后的特征向量会直接进行点积操作,得到两个向量的余弦相似度。而准确架构里面,两个特征图先在通道维度连接在一起,然后通过一系列全连接层,最后通过Sigmoid操作转换为一个相似度评分。由于准确架构里面,分类决策是通过学习得到的,而快速架构里面则是固定的余弦相似度,所以准确架构的最终结果会比快速架构更好,与之相对的则是速度会更慢一些。
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月份时两种架构在不同的榜单中的排名情况:
四. 总结
今天我介绍了最开始使用深度学习来进行立体匹配的方法MC-CNN。我在此总结几点其中的思想:
正如我最早时提到的,立体匹配是一个让计算机做“连连看游戏”的过程。我们本质上是在比较图像块与图像块之间的相似度。
Jure Zbontar和Yann Lecun正是在理解了上述本质后,将立体匹配的代价计算问题转换为了深度学习中的分类问题。这是一个将未知问题转换为已知问题的过程。
MC-CNN虽然是第一代基于深度学习的立体匹配算法,但一经推出就霸榜了KITTI、MiddleBurry等榜单,展现出深度学习方法的强大威力。但因为它仅仅替换了整个立体匹配pipeline中的特征提取和代价计算部分,所以整体效果还不能说特别惊艳,还有很多待解决的问题。比如不管是哪种架构的MC-CNN,我们都能明显看出一些缺陷。这也是我之后要介绍的算法需要解决的问题。
本文仅做学术分享,如有侵权,请联系删文。
点击进入—>3D视觉工坊学习交流群
干货下载与学习
后台回复:巴塞罗那自治大学课件,即可下载国外大学沉淀数年3D Vison精品课件
后台回复:计算机视觉书籍,即可下载3D视觉领域经典书籍pdf
后台回复:3D视觉课程,即可学习3D视觉领域精品课程
3D视觉工坊精品课程官网:3dcver.com
1.面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)
2.彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进
3.国内首个面向工业级实战的点云处理课程
4.激光-视觉-IMU-GPS融合SLAM算法梳理和代码讲解
5.彻底搞懂视觉-惯性SLAM:基于VINS-Fusion正式开课啦
6.彻底搞懂基于LOAM框架的3D激光SLAM: 源码剖析到算法优化
7.彻底剖析室内、室外激光SLAM关键算法原理、代码和实战(cartographer+LOAM +LIO-SAM)
16.透彻理解视觉ORB-SLAM3:理论基础+代码解析+算法改进
重磅!粉丝学习交流群已成立
交流群主要有3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、多传感器融合、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、ORB-SLAM系列源码交流、深度估计、TOF、求职交流等方向。
扫描以下二维码,添加小助理微信(dddvisiona),一定要备注:研究方向+学校/公司+昵称,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,可快速被通过且邀请进群。原创投稿也请联系。
▲长按加微信群或投稿,微信号:dddvisiona
3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列、三维点云系列、结构光系列、手眼标定、相机标定、激光/视觉SLAM、自动驾驶等)、源码分享、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答等进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,6000+星球成员为创造更好的AI世界共同进步,知识星球入口:
学习3D视觉核心技术,扫描查看,3天内无条件退款
高质量教程资料、答疑解惑、助你高效解决问题
觉得有用,麻烦给个赞和在看~