立体匹配算法推理 - SGBM算法(二)

一、SGM算法

SGM算法的全称为Semi-Global Matching,网上关于它的介绍有很多不细讲,它的论文出处详见文末参考文献,但是这里也要为作者赞一把,很牛逼。

SGM其实本质上还是一种代价聚合算法,和局部立体匹配算法中的代价聚合很像,不然也不会叫Semi-Global了(当然也不全是哈,重点在后面~),而Global又是从何而来呢?为了达到和全局立体匹配算法一样全局能量函数最小化的效果,就需要更多或者全图所有的像素参与到当前像素的约束当中。但是刚刚也说了,SGM类似代价聚合,也就是一定范围内的邻域操作(邻域求和,加权平均等),那如何与整张图像上的像素扯上关系而不提高太多性能呢(重点是远距离像素也能扯上关系),于是作者想出了多路径约束聚合的思路,简单说就是让当前像素的代价聚合过程受多个方向(或路径)上所有像素的影响,方向越多参与影响当前像素的邻域像素就越多(原文说一般来讲8-16方向就比较不错了),这样既保证了全局像素的约束,又不用建立全局最小能量函数,避免了复杂运算符,降低了性能,所以才叫半全局算法(纯属个人理解哈),是不是很厉害呢?示意图如图1所示。不知道我这样讲解,有没有让你明白一点半全局的意思呢?

那么讲到这里,大家是不是会有一个疑问,对于每个像素点P都进行多个路径像素代价的聚合,是不是太夸张了,鲁棒性怎么解决?错误的或不正确的代价要怎么解决?和全局能量最小化差远了吧?还有就是数据越界了怎么办?写代码可是硬伤啊!

所以接下来就要说到作者提出的聚合公式,如下。说实话一看到公式我就浑身发抖,但是我们大致可以看出来,有多个最小值的比较,包括有点像惩罚参数P1和P2。what? 惩罚参数?这不是和全局立体匹配算法很像嘛,哈哈。如果把 r 看做是方向的话,那么下面两个公式看起来就像是多方向某个变量的求和(聚合)对吧?

这里必须给出公式的解释(很重要):
第一项表示视差为D时所有像素匹配代价之和。第二项表示对像素点p的邻域Np中的所有像素q增加一个惩罚常数P1(仅在视差差值为1个像素时起作用)。第三项表示对视差差值大于1的像素使用更大的惩罚常数P2。P1是为了适应倾斜或弯曲的表面。P2则是为了保留不连续性。同时作者也对P2阈值设定给出了方法:因为不连续性通常与梯度变化是对应的,因此,可以使用一下的计算公式:

简单讲P1与视差图的平滑有关,P2与视差图的边缘有关,这里给出两组不同P1和P2的效果图,给大家更清晰的认识。先看P1的结果,可以看出在P2不变的情况下,P1越大,图像越平滑。

0.1 * P1

P1

3*P1

再看P2,P2越大图像边缘越差:

P2 = 0.8 * P1

P2 = 1.6 * P1

P2 = 2.4 * P1

但是这里需要强调的是,P1和P2的变化规律并不是线性的,而是非线性的,意思就是达到某一个值以后,可能效果就不会再改变。

如果不容易理解的话,我们可以这样想,SGM的本质是想像素P的聚合过程有多个方向上的全局像素参数,那么我们可以先看单一方向的全局像素是如何参与聚合的。公式如下:

那么完成单一方向聚合约束,再把所有方向上的聚合约束加起来,是不是就是我们前面所说的多方向代价聚合约束了呢?公式如下:

我们这里先不管这个公式,先看opencv里面的代码是如何描述这个公式的。

简单说明一下:

L0 - L3 表示三个不同方向上的聚合值,一般来讲是左上角顺时针计算方向。类似下面这个样子:
1 2 3
0 p 4
7 6 5
Lr_p0 - Lr_p3 表示不同方向上的邻域像素的代价值。
这样我们大致就能看出来,这个公式和代码还是很对应的,无非就是求多个方向的最小值之和并约束一下嘛,我们以L0的计算为例:

假设
T0 = 像素p在0方向上的像素Lr_p0在视差值为d时的代价

T1 = 像素p在0方向上的像素Lr_p0在视差为d-1时的代价 + P1

T2 = 像素p在0方向上的像素Lr_p0在视差为d+1是的代价 + P1

T3 = 像素p在0方向上的像素Lr_p0在非d-1和d+1时的代价最小值 + P2

L0 = 当前代价 + min(T0, T1, T2, T3)- delta(防止聚合结果过大)

因此,我们只要将多个方向的代价求和,就完成了当前像素P的聚合过程。可以看出P1和P2惩罚的代价值所在位置是有区别的,较近的用P1,而较远的用P2,同时P2>P1,所以他们的作用也就比较明显,通过两个惩罚项来保证视差图的平滑和边缘,简单说如果P1或P2任意一个拦住了你,那么此处应该是平滑的(或者存在异常值)要好好保护起来,如果P1和P2都没能拦住你,那此处或者附近就真的是边缘,也要好好保护。

等到代价立方体所有代价值完成聚合,也就完成了代价的SGM优化。

完成SGM优化以后,SGBM算法剩下的就是视差计算和视差后处理步骤。视差计算相信大家都比较了解,这里采用的是胜者为王(WTA)算法,不过多介绍。

二、 后处理

重点介绍一下后处理算法。SGBM算法的后处理流程包括:置信度检测、亚像素插值和左右一致性检测。

置信度检测是利用代价立方体本身进行错误视差值的剔除。简单来讲就是最佳视差值要与一定范围内的视差值在代价值上面保持一定的全局最优关系,这样可以避免算法中经常遇到的局部最优解问题。置信度代码如下:

亚像素插值的目的简单说就是让物体表面视差更加的平滑,因为我们在立体匹配的时候是将双目视角所在空间粗略的分为了maxDisparity个平面,但是真实场景却又是连续且渐变的,其计算公式如下:

左右一致性检测的目的则是为了消除左右遮挡带来的视差错误,代码如下。这里要特别说明一下,左右一致性检测是需要用到左右视差图的,但是SGBM算法中并没有重新计算右视差图,而是采用左视差图推断出右视差图的。

最后给出WTA的结果和后处理完以后的结果,可以看出,后处理的效果还是非常明显的,是一个必不可少的部分。

参考文献:

Hirschm? H . Stereo Processing by Semiglobal Matching and Mutual Information[J]. IEEE Transactions on Pattern Analysis and Machine Intelligence, 2007, 30(2):328-341.

[双目视差] 立体匹配算法推理 - SGBM算法(二)的更多相关文章

  1. opencvSGBM半全局立体匹配算法的研究(1)

    转载请说明出处:http://blog.csdn.net/zhubaohua_bupt/article/details/51866567 这段时间对opencvSGBM半全局立体匹配算法进行了比較仔细 ...

  2. OpenCV3.4两种立体匹配算法效果对比

    以OpenCV自带的Aloe图像对为例:     1.BM算法(Block Matching) 参数设置如下: ) + ) & -; cv::Ptr<cv::StereoBM> b ...

  3. 字符串匹配算法之 kmp算法 (python版)

    字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...

  4. 字符串匹配算法之BM算法

    BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...

  5. TensorFlow 入门之手写识别(MNIST) softmax算法 二

    TensorFlow 入门之手写识别(MNIST) softmax算法 二 MNIST Fly softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...

  6. 分布式共识算法 (二) Paxos算法

    系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.背景 1.1 命名 Paxos,最早是Le ...

  7. 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!

    前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...

  8. 字符串匹配算法之Sunday算法(转)

    字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...

  9. python+openCV实现双目视差图及测距

    通过matlab标定得到相机参数放到stereoconfig.py import numpy as np import cv2 #双目相机参数 class stereoCameral(object): ...

  10. 字符串匹配算法(三)-KMP算法

    今天我们来聊一下字符串匹配算法里最著名的算法-KMP算法,KMP算法的全称是 Knuth Morris Pratt 算法,是根据三位作者(D.E.Knuth,J.H.Morris 和 V.R.Prat ...

随机推荐

  1. v-imgerror作用:当图片链接无效的时候,显示默认图片内容

    // 回顾自定义指令 // 作用: 自定义一些对DOM的操作快捷指令 // 前提: 指令就是用来操作DOM (v-if/v-show/v-for....) // 语法: Vue.directive(指 ...

  2. 持续集成环境(3)-Jenkins用户权限管理

    我们可以利用Role-based Authorization Strategy 插件来管理Jenkins用户权限 安装Role-based Authorization Strategy插件 开启权限全 ...

  3. linux 部署轻量级堡垒机Next Terminal

    对比 类似的开源堡垒机有 Teleport,Jumpserver,Next Terminal等等. Teleport 安全性最好,较轻量,但是对被管理资产不透明,纳管前需要双向认证,在资产设备上需额外 ...

  4. Windows平台在当前文件夹下打开CMD

    Windows平台在当前文件夹下打开CMD的方法: 在路径栏中输入 cmd.exe ,然后敲回车.

  5. Java学习文档

    数在计算机中是以二进制形式表示的,分为有符号数和无符号数,原码.反码.补码都是有符号定点数的表示方法.一个有符号定点数的最高位为符号位,0是正,1是负(以8位整数为例),例如0000001 就是+1, ...

  6. ArcEngine(平板电脑墨迹错误代码。多次调用 RtpEnabled (异常来自 HRESULT:0x80040239))问题未有效解决

    测试数据库中的要素无法执行ITopologicOperater接口下的方法,错误如图 暂记,错误未解决 tip: 1.随便移动一个节点 也不报错/ 2.手动按照他的节点画一个也不报错 3.bufer参 ...

  7. postman 8.7.0 下的cookie 禁用

    简介:以下过程描述在postman8.7.0中,如何禁用掉cookie,使每次请求都带空cookie去请求服务器. 有一个简单投票场景.投票连接是一个get请求, 类似如http://domain/t ...

  8. Glist 按钮属性

    grayed 变灰与否不影响点击等事件 touchable 为false,不会变灰,但会无法点击, enabled为false自动变灰,且无法点击

  9. python调用方法或者变量时出现未定义异常的原因,可能会是没有正确实例化

    当引用某个某块时 例如 Testpython import test class test(object): def __init__(): -- self.mimi = test def test1 ...

  10. java异常--处理机制

    java异常处理机制 异常处理的关键字:try catch finally throw throws package charpter6.Demo02; public class Test { pub ...