Stereo Processing by Semi-Global Matching and Mutual Information基础算法解析

本文主要是介绍Stereo Processing by Semi-Global Matching and Mutual Information基础算法解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

*原创文章,非作者允许,禁止一切形式的转载。

Stereo Processing by Semi-Global Matching and Mutual Information 是立体匹配中一个非常有名的算法,算法快、重建精度也不错、非常适合并行加速。

 

A.匹配代价计算

这部分作者在讲匹配代价计算,作者用的是信息熵,然而在实际应用中发现这一匹配代价好像效果也比较一般,使用census transform的很多。如果对信息熵想仔细了解,可以参考 @迷雾forest 这篇文章。

代价计算这一步,首先要确定disparity range(就是你觉得这张图片中场景的深度范围,比如是20),然后对disparity range划分间隔,可以把间隔划分为256份,这里间隔是多少,就决定了视差图的分辨率。每一个深度值都可以计算出每个像素处的匹配代价,那么就得到了一个cost volume,如图1所示,宽width高height分别对应图像的宽和高 ,disparity range是深度空间,每一个小格子是一个匹配代价。

图1. 匹配代价图

 

B.代价聚合

匹配代价是有噪音的,有时候错误的深度对应的匹配代价反而会比正确深度对应的匹配代价小。因此需要进行优化,也就是代价聚合。论文中构建的能量函数是:

\small E(D)=\sum_{p}(C(p,D_{p})+\sum_{ q\in N_{p}}P_{1}T[|D_{p}-D_{q}|=1]+\sum_{ q\in N_{p}}P_{2}T[|D_{p}-D_{q}|>1]) \quad (1) 

第一项是匹配代价,第二项表示如果该像素的视差与周围像素相差1,则要加一个值为P1的惩罚,注意这里是累加符号,表明周围有几个视差相差1的像素,则要加几个P1,第三项表示如果该像素的视差与周围像素相差大于1,则要加一个值为P2的惩罚。也是周围有多少个像素满足就要加几个P2.。为什么要有第二项和第三项呢?这两项往往也被称为平滑项,可以这样理解,一个像素点的视差值取决于他自身的cost以及周围像素的视差情况,如果完全相信自身,那就是第一项,但是自身有误差,所以要考虑周围的像素的视差,那么就是后两项,但是要想相信周围的视差必须要加一个惩罚项,表明来自周围的信息的可靠程度没有自身cost的可靠程度高,P1的惩罚主要是为了在弯曲或者倾斜的表面进行调整(深度变化小),P2的惩罚则主要是为了处理深度不连续的情况(深度变化大)。

要最小化这个能量函数,直接求解很困难,论文中说是NPcomplete 问题,但是如果在单独的行上进行1D的求解,求解将会非常的快,所以作者把这个问题分成了在多个方向上进行1D的求解,把一个二维问题分解成多个一维求解问题,注意这里只是一种近似,因此最终的结果并不一定是最优的。下面先说1D方向上的代价聚合:

\large L_{r}^{'}(p,d)}=C(p,d)+min(L_{r}^{'}(p-r,d),L_{r}^{'}(p-r,d-1)+P1,L_{r}^{'}(p- r,d+1)+P1,min_{i}}L_{r}^{'}(p-r,i)+P2) \qquad \qquad (2)

第一项是匹配代价,后面的项是传播项。公式的意思是说当前像素某个深度对应的聚合的代价=自己本身的代价(就是census计算的代价)+传播过来的代价,传播过来的代价根据深度不同分为四类:a,等于当前深度 b,比当前深度少1 c,比当前深度大1 d,其他深度值,会在这四类深度中选择一个对应的代价最小的深度,如果是a类深度,就直接是对应代价,如果是b,c类深度,需要在对应代价的基础上加上P1,如果是d类深度,需要在对应代价的基础上加P2。 如下图:注意这里有个简化是d类深度加P2,只需找到d类深度的最小代价加P2即可

图2. 一个方向上某个像素的代价聚合过程

 

图2是一个方向上的某个像素代价聚合的过程,假设有10个深度空间,d=1,2...10,分别对应10个匹配代价,该匹配代价就是第一步计算的匹配代价聚合后的结果,当前像素的匹配代价就是第一步直接计算出的匹配代价,然后每个匹配代价都按照公式(2)进行代价更新,更新后的匹配代价作为继续向下一个像素传播,重复该过程。

要求解(1)式,可以把它近似看成在多个1D方向上的聚合, 就可以近似求解这个问题了。要注意的是:

  • 代价聚合的方向一般要不少于8个,每个像素最终的代价是所有方向相加的结果。
  • 随着代价聚合的进行,匹配代价会很大造成具体实现时的数据溢出,一般会在代价聚合的时候减去当前像素所有匹配代价中的最小值,对于这个例子来说就是减去11.这个操作对应sgm论文中的公式(13)。
  • p1,p2的选取可以根据具体的应用进行调整,一般p1是一个定值,p2可以随着图像梯度变化而变化,往往要保证p2>=p1
  • 时间复杂度是o(whd)

C.视差计算

代价聚合后,选择每个像素处最小的代价所对应的深度作为该像素的深度,至于亚像素级的深度预测,使用二次曲线进行拟合。

论文后面部分还讲了multi-baseline情况的处理、视差图优化,以及视差图融合等内容,直接利用sgm算法计算出的深度图一般是有很大噪声的,后面的视差图的优化和融合在实际应用中是一个非常重要的部分,不过我认为这些优化和融合策略可以根据自己的具体应用去设计,论文的后面的部分这里不再讨论。

总结:sgm算法重建精度还可以,非常适合cuda加速,加速之后速度可以很快,缺点是有些细小的物体可能不太容易建出来,由于算法是基于前向平行假设的,与成像平面非平行的平面重建的不是太好,尤其是与与成像平面垂直的平面。

 

这篇关于Stereo Processing by Semi-Global Matching and Mutual Information基础算法解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695404

相关文章

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

java解析jwt中的payload的用法

《java解析jwt中的payload的用法》:本文主要介绍java解析jwt中的payload的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解析jwt中的payload1. 使用 jjwt 库步骤 1:添加依赖步骤 2:解析 JWT2. 使用 N

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三