sad代价计算_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算法,这样不仅可以给大家讲清楚算法流程,还可以给大家贴出更多的中间结果供大家编码参考和学习,也欢迎大家加入学习立体匹配算法中,提高自己。

一、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算法源码的同学肯定能一眼看出问题,或者在评论区留言,我会给出解答。

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

上面三幅图可以看出,随着成块尺寸的变大,整体效果就越好,但是边缘也就变得越平滑,但仅凭代价计算就可以达到这么好的效果,还是很不错的。那么想要达到更好的效果要怎么办呢,就要回到本文的第一段内容所提到的立体匹配流程了。因为代价计算往往只能提高较好的初始视差图,想要得到更好的视差图还需要后面多个步骤的优化才可以,所以许多的代价聚合算法(CBCA等)或者全局优化算法便闪亮登场。那么经典的SGM算又是怎么一回事情呢,请期待本专栏《立体匹配算法推理笔记》下一期的文章:《SGBM算法详解(二)》,有问题的小伙伴也可以留言,会给出详细的解答哦。

你可能感兴趣的:(sad代价计算)