立体匹配算法推理 - 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. JS实现10进制和26进制的转换

    转载:https://blog.csdn.net/quentain/article/details/52803891 //将26进制转10进制 var ConvertNum = function (s ...

  2. 制作带curl命令的容器

    创建一个容器,启动后使用curl命令请求指定的地址 方法一.固定的地址,创建Dockerfile前先修改entrypoint.sh里的地址 vi entrypoint.sh#! /bin/bashcu ...

  3. 用echarts做兼容ie8的三测单(体温单) 代码全

    $.fn.extend({ /** * * @param { * UrineOutputData: 尿量数据 * OutputData: 出量数据 * InputData: 入量数据 * shitDa ...

  4. junit单元测试踩过的坑

    1.测试方法不能直接获取到系统初始化的配置信息,需要专门读取 2.单元测试多线程子线程不执行,不会像主线程一样等待子线程退出而退出, 会直接退出. . https://blog.csdn.net/yu ...

  5. mysql使用support-files下的mysql.server启动报错“Starting MySQL ERROR! Couldn't find MySQL server (/usr/local/mysql/bin/mysqld_safe)”

    报错版本:mysql-5.7.35 1.报错完整提示信息: [root@localhost support-files]# ./mysql.server start ./mysql.server: l ...

  6. TensorFlow 的 Graph 模式转换

    定义 TensorFlow 图形并将其保存到磁盘上. 使用 TensorFlow 的 tf.Graph() 和 tf.Session() 函数来定义和运行 TensorFlow 图形,并使用 tf.t ...

  7. 什么是Placement new ?

    1. 什么是placementNew placement new的作用就是:创建对象(调用该类的构造函数)但是不分配内存,而是在已有的内存块上面创建对象.用于需要反复创建并删除的对象上,可以降低分配释 ...

  8. IntelliJ IDEA常用插件

    Mybatis Log Plugin安装好插件后,在Tools工具栏中可以看到安装好的插件,点击即可打开相应窗口,在Debug时,相应的Sql语句即可输出到此窗口,方便查看.此插件相当好用,提升开发效 ...

  9. GO语言学习笔记-并发篇 Study for Go ! Chapter seven - Concurrency

    持续更新 Go 语言学习进度中 ...... GO语言学习笔记-类型篇 Study for Go! Chapter one - Type - slowlydance2me - 博客园 (cnblogs ...

  10. 使用MyBatis时需要注意到的事情------执行添加、修改和删除操作时,一定要记得提交事务

    今天在重写添加操作代码时,发现自己写的代码没有任何报错,使用断点进行查询,发现一切正常,但是注册使用的数据就是无法添加到数据库里面 然后就去之前看过的视频里面去找错误,就发现这样一个小细节: 在视频里 ...