点击上方“3D视觉工坊”,选择“星标”

干货第一时间送达

作者丨HawkWang

来源丨 计算摄影学

点击进入—>3D视觉工坊学习交流群

一. ADCensus背景介绍

到目前为止,我通过解读Stefano Mattoccia教授的经典讲义,介绍了立体匹配算法的全貌。然后介绍了几个经典的立体匹配算法的评价指标和数据集。下一步我将介绍经典的立体匹配算法,并展示它们在实际中的应用。

先来看看你现在读到哪里了吧:

立体匹配算法总体理解中,我们看到了经典立体匹配算法局部法和全局法的总体流程,如下图所示:

事实上,有一些算法的流程比较混合——比如今天我将介绍的一个经典立体匹配算法,它总体来说是局部法的流程,但其中也有少量模块在进行视差优化的过程。

这个方法很多人简称为ADCensus,是三星先进技术研究院中国实验室以及中科院自动化所的一群学者的成果,文章发表于2011年:

我用下图总结这篇文章的完整流程,我们可以利用Stefano Mattoccia教授给出的流程来对比理解ADCensus。

这个算法我个人非常喜欢,因为它的流程非常规范,而且易于理解。简直就像学习了Stefano Mattoccia教授的讲义后,将各个标准组件用当时各种优秀的算法实现并串联起来的作品,可以说上面图中每一个组件都有当时已经发表的论文做基础。但作者也并非简单的搞了一个缝合怪出来, 而是把许多组件都做了创造性的优化。比如把AD和Census两种特征融合在一起计算代价,并优化了基于十字架的代价聚合算法,同时组合使用了一系列的视差优化的后处理算法。而且,作者还在文章中描述了算法的CUDA实现,使得这个算法可以高效的在硬件上运行。

每一年计算机视觉领域都有大量的研究成果,但其中能够实用化的真的不多,而ADCensus就是其中之一。据我了解,很多硬件实现的立体匹配算法受到了ADCensus的启发。比如OAK相机,这是一个由OpenCV基金会发起的成功的众筹产品,可以实时计算深度图,完成一系列复杂的功能。

它们推出了多款产品,我手上有下面这一款:

这个相机内部集成的立体匹配算法,就是基于ADCensus的思想实现的,我们可以在这里查到相应的介绍,如下图所示,当然这里为了效率在原始的算法上做了必要的裁剪和调整。

另外,Intel公司的著名产品Intel Realsense D400后的系列RGBD相机也借鉴了本文作者提出的立体匹配算法,特别是其中代价计算部分,在Census特征基础上叠加AD这样的特征,就是从ADCensus方法中借鉴的方法。

如果你查看2017年CVPR的下面这篇关于Intel RealSense的论文,你会看到对此的清晰描述

总之,一群中国学者,在2011年左右搞出了一种非常实用化的立体匹配算法,在很多领域都得到了应用,非常值得钦佩!

二. 效果展示

我在github上找到了一个比较原汁原味的算法实现:https://github.com/DLuensch/StereoVision-ADCensus,我们来看看效果吧。

先来看两对MiddleBurry中的经典图像,左上和左下是校正后的图像,右边是算法默认参数生成的视差图,看起来还不错:

再看看这把椅子吧,看起来对这种复杂的场景稍微差点意思,需要仔细的调优参数才行(我几乎用的是默认参数):

来试试摩托车,尽管还遗留了一些空洞,整个画面的深度图还是被正确恢复出来了,总的来说,效果还是令人满意的

再看看在MPI Sintel数据集上的效果,解析合成数据集和工具,可以看到前景效果总体来说不错,背景似乎都为0,看起来是因为太远了的原因?

然后我们请出我的御用模特Sunny妹来试试,看起来默认参数在这种场景下有很多错误,需要仔细调参才能得到更好的结果。我们待会会仔细分析下ADCensu算法的各个步骤和相关参数:

三. 原理简介

3.1 代价计算

立体匹配算法总体理解中说过代价计算的过程类似于连连看的过程:

最简单的代价就是左右图中相应像素的亮度绝对差,这种代价被称为AD

然而,这种代价在图像中的平坦区域(亮度值都差不多)很显然会得到错误的结果。此时显然应该使用别的特征来计算代价。Cencus就是一种很好的特征,它衡量了局部区域中像素亮度的排序,这是一种结构信息。这就使得它很好的避免了左右图像素亮度差异、噪声、重复纹理等因素带来的错误。

不过,仅使用Census特征的话,在图像中重复结构的区域,也会得到错误的结果。这时候颜色或亮度特征则可以加以辅助。所以ADCensus的作者创造了一种很不错的融合亮度差异和结构差异的方法,如下面公式所述。这里前一部分是基于Census的代价,后一部分是AD代价,所以这个算法才被很多人称为ADCensus:

这里面,为了让两部分代价归一化到[0,1]之间,作者采用了下面这个归一化函数,它能很方便的将输入的原始代价转换为[0,1]之间的值,而这里的λ则用于设置代价的权重:

我们通过作者给出的下图可以很容易的看到混合两种代价带来的好处:

这时候,直接利用AD-Census计算固定窗口的代价,然后用WTA得到视差图,如下图所示。我们可以看到这里有大量的噪声和空洞区域。这是很容易理解的,所以才需要下一节所述的代价聚合过程:

3.2 代价聚合

ADCensus所用的代价聚合方法很有意思。立体匹配中的代价聚合中,我提到了代价聚合的假设:

  • 空间上接近的像素,其视差值也是接近的,于是代价值也是接近的

  • 像素值接近的像素,其视差值也是接近的,于是代价值也是接近的

  • 左右两张图的相邻像素,在关键信息上具有局部相似性

我们还看到了各种各样的聚合方式,有一类方式就是用可变形状的支持窗来进行聚合的——ADCensus的方法就属于这种。当要确定某个像素点p的支持窗时,它是通过寻找上下左右四个"臂",在这四个臂的包裹下构成了其支持窗。确切说,首先找到p的上下臂,也就是在空间和像素值两个维度上都尽可能接近p的两端像素。这样就构成了一个包含在p内的垂直的像素线段。在这条线段上的任何一个点q,我们都确定其左右臂,得到水平的远端像素。这样,所有q点的左右臂的远端像素就形成了一个包络,其中就是p点的支持窗。

有了支持窗后,就比较容易聚合了,先在水平方向聚合,将水平方向的代价值加到一起。然后在垂直方向聚合,得到总的代价:

事实上,ADCensus中为了让结果更好,进行了4次交替方向的聚合。即先水平再垂直,这是第1次。第二次相反,先垂直,再水平。然后再进行2次交替的聚合。最终四次的代价整合到一起,成为最后聚合后的代价值。

那么,如何得到上面所说的p点的四个臂呢?这似乎是得到支持窗的关键。我们以获得p的左臂为例来说明:

所以很显然,这里面的几个参数L1, L2等参数 τ2

都很重要。总之,通过这一步代价聚合后,我们能够得到更加平滑的视差图,如下图所示:

3.3 扫描线优化

立体匹配算法中的视差优化中,我们看到了一种扫描线优化的方法。ADCensus也采用了这种方法,通过聚合后的代价优化得到视差图。在这篇文章中我已经详细阐述了方法,这里只说说不同之处。在原始的扫描线优化方法中,一共是8个方向。而ADCensus为了提高计算速度,只采用了其中的0、1、2、3这几个水平和垂直的扫描线:

通过这一步,能得到更加准确的视差图,如下图所示。相比上面代价聚合后的结果,这里明显噪声小了很多:

3.4 视差后处理

接下来就是视差后处理了,这里是我觉得这个算法的可圈可点之处。作者几乎把我在73. 三维重建8-立体匹配4,利用视差后处理完善结果中提到的视差后处理方法都用上了,形成了一个复杂的管线,如下图所示。我会在后面对这种方式进行评价,但让我们先跟着作者的脉络往下学习吧。

3.4.1 错误检测和区分

首先需要通过左右一致性检查判断哪些像素是错误的:

然后,通过一个简单的法则来区分到底是因为遮挡导致的错误,还是因为错误匹配导致的错误。遮挡像素无论调整d为多少,都无法通过左右一致性检测。而错误匹配则可以通过调整d,得到满足左右一致性检查的新视差值。

接下来,就可以分别对遮挡和错误匹配进行处理了。

3.4.2 区域投票

首先进行区域投票。在错误像素点p的支持窗内,对所有正确计算视差的像素(即通过了左右一致性检测)的视差值建立一个直方图。如果这个支持窗中稳定视差值足够多,并且直方图中占比最大的视差值的占比大于某个阈值,我们就把p点的视差值更新为最大占比的视差值:

这里面,Sp代表支持窗中正确视差值的个数,Hp(d*p)代表直方图中占比最大的视差值的数量

3.4.3 分情况插值

前面我们区分了遮挡像素和错误匹配的像素,现在分情况进行插值。

  1. 首先对于错误像素,我们寻找16个方向上的最相似的正确匹配的像素。

  2. 接下来,如果当前像素在3.4.1节中被划分为了遮挡像素,那么就从这些正确像素中挑选最小的视差,用于填充当前像素的视差值,也就是说假设遮挡像素属于背景。

  3. 而如果当前像素是错误匹配的像素,那么就从这些正确点中挑选与当前像素颜色维度最相似的那一个,用其视差填充当前像素。

现在再来看看结果,很明显大量的错误像素被成功插值了。不过也可以看到,部分遮挡像素还是未填充视差值,这是因为在其16个方向都找不到满足条件的正确像素,这里主要是因为用1个参数限制了在一个方向上的最大搜索像素。如果增加这个参数的值,应该可以使得更多的像素得到填充。

3.4.4 修正边缘处的视差值

考虑到物体边缘的视差值不稳定,容易出错,因此作者还加入了一个步骤,对边缘处的视差值进行微调。具体来说,先检测到所有的边缘,接着对边缘上的像素p,我们判断其在边缘两侧的两个相邻像素p1或p2的代价是否小于p点的代价。如果确实如此,那么就用p1和p2中代价最小的那个像素的视差值来替换p点的视差值。

不过对于当前这对图像,似乎边缘调整带来的变化很小,肉眼几乎分不出来。当然,这是可以理解的,因为这只是“微调”

3.4.5 亚像素增强和滤波

调整完边缘后,利用视差后处理完善结果中提到的亚像素增强,将整数型的视差值插值为了浮点数型的视差值

然后,对最后的视差图做了1个3x3的中值滤波,去除微小的噪声,这就得到了最终的视差图:

我把整个过程做成一个视频,可以看得更清楚些:

四. 算法讨论

正如我在文章开篇所说,我挺喜欢ADCensus这个算法的。因为它是由一个又一个非常容易理解的子部件组合而成的。这种结构也使得实现起来很容易,而且还可以根据工程需要删除或者替换其中的子部件。

比如,在文章开篇我们看到的OAK Camera的流程,通过官方的流程图可以看出跟原版ADCensus很相似,用了Census特征,扫描线优化,左右一致性检测后的插值,还增加了更多的滤波器。似乎裁减掉了区域投票、边缘调整等步骤:

从效果上看,OAK Camera仅通过单通道的双目图像,就已经能实时得到不错的结果,这进一步证明了类ADCensus算法的有效性:

而且,作者还专门阐释了在硬件上优化实现的方案,包括代价计算,代价聚合,扫描线优化等在内的步骤都可以用硬件来并行计算。在作者的论文中,通过硬件加速,算法执行速度提升了最高140倍!OAK Camera应该也是借鉴了其中的思想,所以能实时计算得到视差图。

然而,硬币总有两面,由多个子部件来构成一个完整的算法管线,也会带来新的问题。由于每个部件都有自己的参数,这就导致要将算法调整到最佳状态非常困难,因为参数数量太多了,而且各个部件之间有强相关关系,调整前一个步骤的参数,可能会影响到后一个步骤,这就使得调整参数更加复杂。而且,在不同的数据集上,参数的值显然不相同,所以导致这个算法的泛化性很成问题。

前面的开源实现 https://github.com/DLuensch/StereoVision-ADCensus, 里面,就定义了众多参数:

前面我们Sunny妹的图片,采用MiddleBurry数据集上调出的默认参数时就存在很多区域的错误。很显然,此时应该在这种场景下对参数进行精调才行。

比如在OAK-Camera上调整参数后,可以得到这个结果,明显的错误像素少了许多:

用多个子部件组成算法管线,还存在性能优化的问题。因为你不得不优化每一个部件的性能,才能得到一个高性能的算法——这对立体匹配通常非常重要。

五. 总结

今天,我为你介绍了一个经典的立体匹配算法ADCensus,其流程非常规整。它很容易理解,很容易实现,并且被许多知名的硬件设备所借鉴,比如OpenCV官方推出的OAK Camera,以及Intel Realsense。

它的作者是一群中国学者,嗯,好感度++

它遵循的范式是用一堆容易理解的子模块构成整个算法,似乎咱普通人也能想得到这种思想:

ADCensus算法也有自己的缺点:参数众多、难以调整、泛化性不够高。模块众多,优化复杂,很吃经验。

那么,有没有更好的方式呢?这也是我后面的文章中会讲述的,让我们拭目以待吧。

六. 参考资料

1、X. Mei etc.,On building an accurate stereo matching system on graphics hardware

2、OAK-Camera:https:/store.opencv.ai/products/oak-d

3、Leonid Keselman etc. Intel RealSense Stereoscopic Depth Cameras

4、开源实现: https://github.com/DLuensch/StereoVision-ADCensus

本文仅做学术分享,如有侵权,请联系删文。

点击进入—>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)

8.从零搭建一套结构光3D重建系统[理论+源码+实践]

9.单目深度估计方法:算法梳理与代码实现

10.自动驾驶中的深度学习模型部署实战

11.相机模型与标定(单目+双目+鱼眼)

12.重磅!四旋翼飞行器:算法与实战

13.ROS2从入门到精通:理论与实战

14.国内首个3D缺陷检测教程:理论、源码与实战

15.基于Open3D的点云处理入门与实战教程

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天内无条件退款

高质量教程资料、答疑解惑、助你高效解决问题

觉得有用,麻烦给个赞和在看~  

三维重建立体匹配: 经典算法ADCensus相关推荐

  1. 基于MVS的三维重建算法学习笔记(五)— 立体匹配经典算法PatchMatch论文翻译及要点解读

    基于MVS的三维重建算法学习笔记(五)- 立体匹配经典算法PatchMatch论文翻译及要点解读 声明 问题提出 问题建模 通过PatchMatch获取平面参数--Inference via Patc ...

  2. 基于MVS的三维重建算法学习笔记(四)— 立体匹配经典算法Semi-Global Matching(SGM)论文翻译及要点解读

    基于MVS的三维重建算法学习笔记(四)- 立体匹配经典算法Semi-Global Matching(SGM)论文翻译及要点解读 声明 SGM概述 Cost Calculation(像素代价计算)--M ...

  3. 立体匹配经典算法:PatchMatchStereo

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨HawkWang 来源丨计算摄影学 一. 前言 学习路线图: 那么,今天咱们就进入经典视差优化算 ...

  4. 双目立体匹配经典算法之Semi-Global Matching(SGM)概述:匹配代价计算之互信息(Mutual Information,MI)...

      半全局立体匹配算法Semi-Global Matching,SGM由学者Hirschmüller在2005年所提出1,提出的背景是一方面高效率的局部算法由于所基于的局部窗口视差相同的假设在很多情况 ...

  5. 双目立体匹配 等 算法 论文 综述 全局局部算法 CSCA NLCA SegmentTree树 DoubleBP Belief-Propagation AD-Census SGM

    双目立体匹配 等 算法 论文 综述 本文GITHUB 博文末尾支持二维码赞赏哦 _ 双目立体视觉技术实质就是模拟人的双眼视觉处理系统来处理通过摄像机采集所 获取的图像,它利用两台或多台摄像机在一定约束 ...

  6. 立体匹配:经典算法Fast Bilateral Solver

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨HawkWang 来源丨计算摄影学 点击进入->3D视觉工坊学习交流群 一. 前言 你好, ...

  7. PMVS:多视图匹配经典算法

    导语:Multi-View Stereo(MVS)多视图立体匹配与三维重建的任务是:以已知内外参数的多幅图像(SfM的结果)为输入,重建出真实世界中物体/场景的三维模型. 本文作者提出了PMVS的经典 ...

  8. 双目立体匹配_SGM算法

    双目立体匹配_SGM算法 视觉感知使人类能非接触地感知三维空间,通过大脑处理快速推断出周围环境的空间特性,从而执行一些生存所需的关键任务,如在环境中移动.识别和抓取物体等等.由于图像是三维世界的二维投 ...

  9. 详解三维重建立体匹配:视差计算和优化

    点击上方"计算机视觉工坊",选择"星标" 干货第一时间送达 作者丨HawkWang 来源丨计算摄影学 本篇我们继续解读Stefano教授的经典讲义 Stereo ...

最新文章

  1. HDoj-1042 大数阶乘
  2. 降低网站跳出率的技巧分享!
  3. QoS是否提供更多带宽?-Vecloud
  4. python连接oracle导出数据文件
  5. python标准库书籍_Python标准库中文版 Python Standard Library 329页Python标准库合集
  6. *(已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  7. C++11:using 的各种作用
  8. CMAKE and Ninja
  9. 为何超四成人反感大数据应用
  10. LayaAir Geolocation 获取地理位置
  11. -XX:HandlePromotionFailure: 是否设置空间分配担保【了解】
  12. 计算机软件性能测试的过程,软件性能测试过程研究与应用
  13. poj:2455 Secret Milking Machine 秘密挤奶机(二分+最大流)
  14. 【四二学堂】基于unicloud的跨平台项目-华夏画苑APP
  15. 樊登读书搞定读后感_樊登读书会听书《搞定》《高效人士的七个习惯》《人生效率手册》《搞定3》第四周学习感悟...
  16. 基于【NPU+AI ISP】多媒体SoC方案开发硬件边缘计算_AI 摄像机产品
  17. ajax导致服务端线程粘滞,解决js ajax同步请求造成浏览器假死的问题
  18. 国内的IT生意,敢问路在何方?
  19. 【实用工具】Gephi下载与安装
  20. libxml2对XML文件的创建、解析、查找、修改

热门文章

  1. 前后端接口测试神器Swagger基本使用
  2. 【第150期】游戏策划学习UE4:如何实现角色之间的切换
  3. 深入了解JavaScript 中的For循环之详解
  4. 符号速率,码片速率,业务速率,信道编码,扩频因子(转)
  5. 每日一道leetcode题 82.删除排序链表中的重复元素
  6. 移动、电信、联通的对手不是腾讯,5G消息要再造互联网生态?
  7. Windows 10 “红与黑”:装机量不是唯一指标
  8. SAP内表转json json转内表方法(自定义实现 ZCL_JSON)
  9. 如何设置图例的位置?如何去掉图例的边框?如何调整图例的大小?如何调整图例中图标和文字说明的间距?
  10. VPS6001 双阶输出线性稳压器 100V 超高压输入推荐介绍