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

SGBM立体匹配算法,总体来讲包含以下6个步骤:

  1. Preprocess ( GaussBlur , SobelX, …etc)
    预处理

  2. Cost Compute ( AD, SAD, SSD, BT, NCC, Census, …etc)
    代价计算

  3. Cost Aggregation ( Boxfilter, CBCA, WMF, MST, …etc)
    代价聚合

  4. Cost Optimization ( BP, GC, HBP, CSBP, doubleBP, …)
    代价优化

  5. Disparity Compute( WTA)
    计算视差

  6. Postprocess ( MedianFilter, WeightMedianFilter, LR-check, …etc)
    后处理

一般情况下,组合12356称为局部立体匹配算法, 12456称为全局立体匹配算法,区别在于是否构建全局能量优化函数。

一、SGBM与SGM的区别

回到今天的主题SGBM(Semi-Global Block Matching)算法,为什么要分析这个算法呢,原因有二:

  1. 算法核心为非常经典的SGM(Semi-Global Matching)算法;

  2. SGBM算法自OpenCV2.4.6开始就已经被开源,非常的方便,并被广泛使用。

可能说到这里,大家可能还是不明白SGBM算和SGM算法的区别,那么直接看我自己整理的算法流程图:

看完这幅图以后,是不是对SGBM算法与SGM算法的区别有了清晰的认识呢?没错,SGM算法只是SGBM算法中的一个步骤,而SGBM中的“Block”其实就是将每一个代价(cost)值进行成块计算(领域求和运算)后用于SGM算法进行视差优化,是不是非常的简洁!

二、代价计算

从刚才的流程图中,我们可以看到SGBM算法的代价计算其实包含了如下基本步骤:

  1. 输入图像经过SobelX处理后,计算BT代价

  2. 输入图像直接计算BT代价值;

  3. 将上面两步的代价值进行融合;

  4. 对上述步骤得到的代价值进行成块处理。

对于第一种代价计算,SobelX大家很容易理解,就是对原图进行水平方向的梯度滤波,然后再进行BT代价值计算。但是,这里需要注意,这里得到的水平方向梯度并没有直接使用,而是进行了分段处理。BT代价值的计算公式可以参考论文《Depth Discontinuities by Pixel-to-Pixel Stereo》,直接按照论文中2.1.1小节中的计算公式敲代码即可。第二种代价就是直接在原图上进行BT的计算,那么这两种代价值有什么区别呢?,请看下图:

从两幅图可以看出,经过SobelX + BT后的代价保留了较多的边缘和细节信息,而直接从原图进行计算BT得到的代价值保留了更多的原图信息,因此两种代价的融合可以说是不但没有冲突,而且还相辅相成的提高了代价值的准确性,非常的赞。得到了前两步的代价值,便可以进行代价融合和代价成块,这里的代价融合便是将两种代价值进行简单的相加即可。
Tips:如果大家尝试自己编写这部分的代码,可能在结果上会有小小的不一样(如下图,在右上角的小熊旁边有条纹瑕疵现象),这与原图计算BT的方式有关


经过前面的分析和编码,就到了代价计算的最后一步,也是就是成块计算。在SGBM算法中,成块计算就是就是对每个像素的代价值用周围邻域代价值的总和来代替(类似SAD算法),提高匹配的鲁棒性,那么这里同样给出不同成块尺寸的结果图供大家参考:


上面三幅图可以看出,随着成块尺寸的变大,整体效果就越好,但是边缘也就变得越平滑,但仅凭代价计算就可以达到这么好的效果,还是很不错的。那么想要达到更好的效果要怎么办呢,就要回到本文的第一段内容所提到的立体匹配流程了。因为代价计算往往只能提高较好的初始视差图,想要得到更好的视差图还需要后面多个步骤的优化才可以,所以许多的代价聚合算法(CBCA等)或者全局优化算法便闪亮登场。

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

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

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

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

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

  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. 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!

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

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

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

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

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

  8. 字符串匹配算法之SimHash算法

    SimHash算法 由于实验室和互联网基本没啥关系,也就从来没有关注过数据挖掘相关的东西.在实际工作中,第一次接触到匹配和聚类等工作,虽然用一些简单的匹配算法可以做小数据的聚类,但数据量达到一定的时候 ...

  9. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

  10. 字符串匹配算法之————KMP算法

    上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符.但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博 ...

随机推荐

  1. 9.6 2020 实验 1:Mininet 源码安装和可视化拓扑工具

    一.实验目的 掌握 Mininet 的源码安装方法和 miniedit 可视化拓扑生成工具.   二.实验任务 使用源码安装 Mininet 的 2.3.0d6 版本,并使用可视化拓扑工具生成一个最简 ...

  2. @click使用三元运算符

    @click="scope.row.status == 1 ? '' :  blockUp(scope.row) "

  3. 统信桌面端专业版开启cron日志,确认定时任务执行情况

    默认没有开启cron日志记录 1. 修改rsyslog vi /etc/rsyslog.conf #将cron前面的注释符去掉 cron.* /var/log/cron.log 排查完毕需关闭,重新注 ...

  4. Istio思考往前一小步~系列一

    思考起源于现实应用需求,随着微服务理念普及,基础设施从单机到容器到Kubernetes,体验过集群的各种好处之后,我们还缺少什么?为什么还要在kubernetes的基础上部署Istio?个人认为Ist ...

  5. arp 基本功能

    地址解析协议(英语:Address Resolution Protocol,缩写:ARP)是一个通过解析网络层地址来找寻数据链路层地址的网络传输协议,它在IPv4中极其重要.ARP最初在1982年的R ...

  6. supervisor不一样的日志轮转

    出于项目需求,需要读取某个进程的最新日志,而这个进程刚好是supervisor管控. 很自然地我就想到了,根据日志的编辑时间排序,获取最新的日志文件. 然而,发现了奇怪的一幕: 发现什么没有? web ...

  7. .Net中跨域问题的解决方案

    开发中前端与后端完全分离并分开发布,遇到跨域问题,一通百度之后,解决方案如下: 把下面的代码放在web.config文件中的 System.WebServer 节点下 <httpProtocol ...

  8. WinUI(WASDK)使用ChatGPT和摄像头手势识别结合TTS让机器人更智能

    前言 之前写过一篇基于ML.NET的手部关键点分类的博客,可以根据图片进行手部的提取分类,于是我就将手势分类和摄像头数据结合,集成到了我开发的电子脑壳软件里. 电子脑壳是一个为稚晖君开源的桌面机器人E ...

  9. java生态下的后端开发都有哪些技术栈?

    前言 我08年毕业,那时(2003-2010)C#还比较时髦的,大学跟着老师进修的,毕业后就从事winform窗体应用程序开发.慢慢的web网站兴起,就转到aps.net开发,再到后来就上了另一艘船( ...

  10. C++/Qt网络通讯模块设计与实现(三)

    上一节给大家从源码级别分析了SNetClient网络客户端的实现过程,详见​C++/Qt网络通讯模块设计与实现(二),并给大家留了一个疑问,即引入SNetClientRunning类是为了解决什么问题 ...