[双目视差] 立体匹配算法推理 - SGBM算法(二)
立体匹配算法推理 - 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算法(二)的更多相关文章
- opencvSGBM半全局立体匹配算法的研究(1)
转载请说明出处:http://blog.csdn.net/zhubaohua_bupt/article/details/51866567 这段时间对opencvSGBM半全局立体匹配算法进行了比較仔细 ...
- OpenCV3.4两种立体匹配算法效果对比
以OpenCV自带的Aloe图像对为例: 1.BM算法(Block Matching) 参数设置如下: ) + ) & -; cv::Ptr<cv::StereoBM> b ...
- 字符串匹配算法之 kmp算法 (python版)
字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...
- 字符串匹配算法之BM算法
BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...
- TensorFlow 入门之手写识别(MNIST) softmax算法 二
TensorFlow 入门之手写识别(MNIST) softmax算法 二 MNIST Fly softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...
- 分布式共识算法 (二) Paxos算法
系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.背景 1.1 命名 Paxos,最早是Le ...
- 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!
前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...
- 字符串匹配算法之Sunday算法(转)
字符串匹配算法之Sunday算法 背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是Ω(m*n),也就是达到了字符串匹配效率的下限.于是后来人经过研究 ...
- python+openCV实现双目视差图及测距
通过matlab标定得到相机参数放到stereoconfig.py import numpy as np import cv2 #双目相机参数 class stereoCameral(object): ...
- 字符串匹配算法(三)-KMP算法
今天我们来聊一下字符串匹配算法里最著名的算法-KMP算法,KMP算法的全称是 Knuth Morris Pratt 算法,是根据三位作者(D.E.Knuth,J.H.Morris 和 V.R.Prat ...
随机推荐
- geom_smooth trasparent alpha 透明度
stat_smooth (geom="line", alpha=0.3, size=3, span=0.5) + geom_line(stat="smooth" ...
- yapi的一些基本操作
一.yapi能干什么 强大的接口管理平台 提供mock功能 提供测试功能 项目管理功能 插件齐全 二.yapi的权限 项目权限 操作 游客 项目开发者 项目组长 超级管理员 浏览公开项目与接口 √ √ ...
- Java中的方法增强
A:在不影响业务情况下,增强一个方法有几种方法呢? B:3种! A:哪三种呀? 一.继承类来重写方法: 1.要可以获取这个类的构造: class Man{ public void run(){ Sys ...
- 替换yum源
1.yum源进行备份 进入到yum源的配置文件中 执行命令如下:cd /etc/yum.repos.d 将yum源进行备份:mv Centos-Base.repo Centos-Base.repo.b ...
- Action: Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
错误原因 在pom中引入了mybatis-spring-boot-starter ,Spring boot默认会加载org.springframework.boot.autoconfigure.jdb ...
- FastJson参数
名称 含义 备注 QuoteFieldNames 输出key时是否使用双引号,默认为true UseSingleQuotes 使用单引号而不是双引号,默认为false WriteMapNull ...
- 22.this指针
1.this指针工作原理 我们知道,c++的数据和操作也是分开存储,并且每一个非内联成员函数(non-inline member function)只会诞生一份函数实例,也就是说多个同类型的对象会共用 ...
- PMP常见会议小结
转载请注明出处: 会议是吸引项目团队和其他干系人参与的重要方式.它们是整个项目的主要沟通方式. 一. 项目启动会 召开时间:是启动阶段结束时召开的会议. 主要任务:发布项目章程,并任命项目经理,赋予项 ...
- KMP 自动机,孤独的自动机(同时也是CF1721E的题解)
给定字符串 \(s\),以及 \(q\) 个串 \(t_i\),求将 \(s\) 分别与每个 \(t_i\) 拼接起来后,最靠右的 \(|t_i|\) 个前缀的 border 长度.询问间相互独立. ...
- 【CS231n assignment 2022】Assignment2 - Part 1,全连接网络的初始化以及正反向传播
文章目录 前言 FullyConnectedNets 网络初始化 代码注意事项 1. W 的尺寸怎么知道? 2. np.random.norml() 3. batchnorm loss(self, X ...