美文网首页
SGBM算法详解(二)

SGBM算法详解(二)

作者: OrdinaryW | 来源:发表于2019-08-13 16:04 被阅读0次

    上一期的SGBM算法详解(一)得到了许多网友的热烈回复,心里很开心,已经一一作了解答,如果有不懂的可以继续咨询,今天开始第二个部分《SGBM算法详解(二)》。本次主要包括SGM算法和后处理两个部分。

    一、SGM算法

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

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


    SGM

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

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

    E(D) = \sum_{p}(C(p,D_{q}) + \sum_{q\in N_{p}}P_{1}T[|D_{p} - D_{q}| = 1]+\sum_{q\in N_{p}}(P_{2}T[|D_{p}-D_{q}])

    这里必须给出公式的解释(很重要):
    第一项表示视差为D时所有像素匹配代价之和。第二项表示对像素点p的邻域Np中的所有像素q增加一个惩罚常数P1(仅在视差差值为1个像素时起作用)。第三项表示对视差差值大于1的像素使用更大的惩罚常数P2。P1是为了适应倾斜或弯曲的表面。P2则是为了保留不连续性。同时作者也对P2阈值设定给出了方法:因为不连续性通常与梯度变化是对应的,因此,可以使用一下的计算公式:
    P_{2} = (\frac{P'_{2} }{|I_{p}-I_{q}}|)
    简单讲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的聚合过程有多个方向上的全局像素参数,那么我们可以先看单一方向的全局像素是如何参与聚合的。公式如下:
    singlepath
    那么完成单一方向聚合约束,再把所有方向上的聚合约束加起来,是不是就是我们前面所说的多方向代价聚合约束了呢?公式如下:

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

    简单说明一下:

    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的结果和后处理完以后的结果,可以看出,后处理的效果还是非常明显的,是一个必不可少的部分。


    WTA + subPixelRefine WTA+All_Refine

    参考文献:

    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算法详解(二)

          本文链接:https://www.haomeiwen.com/subject/ozxbjctx.html