立体匹配---动态规划

原文:http://blog.csdn.net/chuhang_zhqr/article/details/52586793

近来研究立体匹配,从入门开始,先学习一些基本的算法思想。 
立体匹配算法中,全局匹配是一个很重要的部分,利用图像的全局约束信息,对局部图像的模糊不敏感,它的计算代价很高。全局匹配算法通过构建全局能量函数,然后通过优化方法最小化全局能量函数以求得致密视差图。

全局匹配算法一般有动态规划、置信传播、模拟退火、图割法、遗传学等,这里首先介绍动态规划,也是从一些论文中提取的思想,可能有不对的地方,望指正。

动态规划的思想就是把求解整个图像深度值的过程分解为一些子过程,逐个求解子过程,具体过程为根据外极线顺序约束,通过在视差图像上寻找最小代价路径得到最终视差图,从而减少了算法的复杂度,动态规划的思想体现了顺序约束和连续性约束。传统的动态规划算法可以很好的处理因局部纹理单一而造成的误匹配,算法复杂度不高,缺点是匹配过程忽略了每条极线间视差的约束,导致了视差图有条纹瑕疵现象。

1:首先了解下动态规划算法的思想: 
解决爬楼梯的问题: 
一个人每次只能走一层楼梯或者两层楼梯,问走到80层一共有多少种方法。 
解:设DP[i]为走到第i层一共有多少种方法,那么DP[80]就是所求的目标。很显然DP[1]=1,DP[2]=2(走到第一层只有一种就是走一层楼梯,第二层有两种:走两次一层楼梯或者走一次两层楼梯)。同理走到第[i]层楼梯可以从第i-1层走一层,或者从i-2走两层。很容易得到: 
递推公式:DP[i]=DP[i-1]+DP[i-2] 
边界条件:DP[1]=1 DP[2]=2 
则自顶向下的解法:

long long dp[81] = {0};/*用于保存中间结果 否则会重复计算很多重复的子问题*/  
long long DP(int n)  
{  
    if(dp[n])  
        return dp[n];  
    if(n == 1)  
        return 1;  
    if(n == 2)  
        return 2;  
    dp[n] = DP(n-1) + DP(n-2);  
    return dp[n];     
}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

自低向上的解法:

int i;  
long long dp[81]; /* 注意当n超过75时,结果值将超过int范围 */  
dp[1] = 1;  
dp[2] = 2;  
for(i=3; i <= 80; i++)  
    dp[i] = dp[i-1] + dp[i-2];  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

动态规划大致就是这个思路。

2:动态规划立体匹配基于极线约束,通过依次寻找每条极线上匹配点对的最小代价路径的动态寻优方法求解全局能量最小化,得到匹配视差图。算法步骤: 
A:阶段划分:传统的方法是只在水平方向寻找扫描点,所以算法是在水平扫描线的视差空间切面上寻找最优路径的过程,以像素点的行方向为横坐标,视差值d为纵坐标,依次将整个过程分为1,2,3,4……k个阶段,每个x坐标点对应一个阶段,把立体匹配划分成可以排序的若干个阶段。 
《立体匹配---动态规划》

B:确定状态 
将上述各个阶段所处的匹配阶段用不同的状态表示。状态的选择要满足无后向性。无后向性的意思就是当前阶段的状态只是之前阶段的综合结果,并不对后续阶段产生影响。 
《立体匹配---动态规划》

共有三种状态:相互匹配M,左可见右遮挡为L(某点在右图中没有匹配点),右可见左遮挡为R(如果前一个点的视差比后一个视差大,就是前面点的匹配点在后一个点的匹配点的后面)。 
C:状态转移方程:所谓状态转移方程就是根据前一阶段的状态确定当前阶段的状态,根据顺序性的约束,允许的状态转移形式有7种(用小写字母表示前一阶段的状态,大写字母表示当前阶段的状态) 
《立体匹配---动态规划》

0表示正确匹配,1、2表示匹配产生左图像遮挡,4、5表示产生右图像遮挡点,3、6表示图像由背景进入前景,视差跳变产生并不连续点。

D:求取最优解,并记录该最优解的路径 
在实际编程中,按顺序自左向右,或者自右向左对各阶段(即同一极线上的点)依次进行计算,计算相似性测度函数和平滑函数的最小值,当所有阶段都计算完成后,全局能量函数最小的一条最优匹配路径也就得出来了。

全局能量函数表示如下, 
E(d)= E(data) + E(smooth) 
其中 E(data) 为图像数据约束项,判断匹配像素点之间的相似性, E(smooth)为相邻点间的平滑约束项,判断相邻点之间的连续性。

数据项由匹配代价获得 
《立体匹配---动态规划》 
其中《立体匹配---动态规划》表示左像素点与视差为d的右像素点的匹配代价函数。

《立体匹配---动态规划》 
其中N表示相邻像素对的集合,dp,dq分别表示像素点p与像素点q的视差,平滑项s(dp,dq)表示相邻像素点p、q之间的平滑约束,定义如下:

《立体匹配---动态规划》 
其中P1,P2,P3表示不同情况下的惩罚常量,Cp,q表示待匹配的像素点与其相邻点q之间的色彩差异,当相邻点视差值相同时,惩罚量为0;差值为1时惩罚量为P1,当差值大于1且两个对应像素点的色彩差异小于阈值T时,惩罚量为P2,否则惩罚量为P3。P1,P2,P3,T分别赋值10、20、40、35 。

Cp,q也可以是图像中相邻像素点p和q之间的梯度。

最优解d*=arg minE(d),这里是指使E(d)取得最小值时的d值。d是一个数组,传统的是一行行求每个点的视差,每一行组合起来就是视差图,并且是稠密的。

传统的动态规划思想: 
我做一个类比,求这个最优路径就相当于上面求怎么最少步数的登上80层,每一步上几个台阶就相当于每一个点的视差值,每一点的视差值得范围是设定的视差搜索范围,求出最优路径就是把每一步上的台阶数计算出来了,相当于每一步的视差也就计算出来了。边界值就设为0,可能有更好的设法,然后依次计算。

先逐个计算每个像素在每个视差下的匹配代价聚合值,这样一行像素就构成一个以行像素为横坐标,以视差值为纵坐标的二维数组,然后根据唯一性约束和顺序性约束使全局能量函数最小,就是求所有点的视差匹配代价加上平滑约束得到的值最小。这样既求得比较精确的视差又让视差平滑了。 
不知道这样理解对不对。谁理解的更好,请指导一下,菜鸟求指导

这样的动态规划求出的只是在水平扫描线上寻径,忽略了扫描线间视差的约束,视差图有明显的条纹现象。

3:改进的动态规划:

A:基于行列双通道的动态规划算法,在行扫描线上寻径的同时考虑垂直方向的视差一致约束,对扫描行间也进行动态规划的寻优。首先用水平路径所求的匹配视差结果作为初始视差值,再次在列方向上二次动态寻优,求取能量函数最小值,生成致密视差图。

引入一种奖惩的方法,通过减小初始视差值d*所对应匹配代价函数的值来引导其在列方向动态寻优,即将在行方向上动态寻优求解得到的初始视差值作为一个结果,然后对这个视差结果对应的数据项给予一个更新,其它数据项在这个过程中保持不变。 
《立体匹配---动态规划》 
r是一个相对于代价函数较小的数,这里取3,太大会对列寻优没作用,太小对行寻优没意思。

在列方向上进行动态寻优,即为只考虑列方向上相邻像素点的视差约束,运算过程与行方向一致。这样可以改啥条纹现象,但时间复杂度比原来高出一倍,失去了效率优势。

这样得到的结果有少量明显的视差点。后处理方法:在行方向上如果一个像素点左右邻域上像素点的视差相等,则把其左右邻域像素视差值赋予该像素点;在列方向上如果一个像素点其上下邻域像素点的视差相等,则将其上下邻域像素的视差值赋予该像素点,其它情况下不变。

B:基于树结构的动态规划算法 
在全局能量函数中的平滑项 E(smooth)表示相邻像素点p、q在其对应视差值dp、dq情况下约束项。 
《立体匹配---动态规划》 
其中集合N表示像素点间相互约束的邻域范围,这个算法是研究邻域N的几种树结构DP算法。 
《立体匹配---动态规划》 
a就是传统的行扫描线动态寻优; 
b是一种类似于树的结构来连接四个方向的点,排除边界点与角点,邻域N选择上下左右四个方向,每个点都与它的四个相邻像素点有关,算法有效解决行扫描线间的垂直约束问题。 
c、e是算法对每一个像素点建立水平和垂直两个方向的树结构,首先在行扫描方向进行动态寻优计算最佳匹配代价值,然后检查最优值是不是也是垂直方向的最优值,用WTA得到最优视差值。

d是将匹配中二维约束近似转化为多个一维约束,采用以中心像素点为根节点的八个不同方向的平滑约束对图像进行动态规划寻径,缺点是在求解最优视差值的过程中各个方向都不能提供有效的纹理信息使得算法在弱纹理区域误匹配率高。

其中b的解决方案: 
首先对每一列做向下的动态规划运算,得到极线间从最左边开始的每一个像素的最优匹配代价,将所得的优化代价存放在矩阵 
《立体匹配---动态规划》 
《立体匹配---动态规划》

接着对每一列做向上的动态规划运算,得到极线间从最下边开始的每一个像素的左右匹配代价,这时的q指向p下面的像素,把得到的结果存放在矩阵《立体匹配---动态规划》

为了得到每个像素的优化代价,可以将向上和向下动态规划运算代价进行累积,在坐标(x,y)的像素记为px,y,则赋予它视差d时的最小能量函数 
《立体匹配---动态规划》

上式等于 
《立体匹配---动态规划》

最后在得到优化矩阵后,将极线间的动态规划与极线上的动态规划结合,用已取得的运算结果更新视差空间代价值 
《立体匹配---动态规划》

其中a是用来调整极线间动态规划对视差结果影响的参数。

然后进行极线上的动态规划,在基于上面的更新后的视差空间进行的,最后把累积结果存放在矩阵《立体匹配---动态规划》 
最小化这个矩阵,就可以求取每个像素的视差了。 
这种方法复杂度过大,时间太长。

4:基于控制点的双向动态规划匹配。 
利用事先确定的正确匹配点作为匹配控制点,在动态规划过程中对寻优路径进行指导,从而煎炒条纹瑕疵,降低了复杂度。

控制点是那些事先知道的正确的匹配点。那么就可以通过将这些正确匹配点设为一个较小值迫使所找寻的路径经过这些正确点。这些点满足左右一致性约束;避免伪最优匹配,匹配代价小于遮挡代价,排除孤立的控制点,即那些没有直接近邻控制点的点。

《立体匹配---动态规划》 
b中的黑点就是控制点,有效缩小搜索空间。

具体步骤: 
A:得到每个像素的初始匹配代价C(x,y,d),处理遮挡问题需要计算出左右视差图像,故左右视差图像都需要得到。 
B:控制点集的计算,采用以下方法计算控制点集。

《立体匹配---动态规划》

C:初始匹配代价的聚集 
首次在极线间分别采用下面两式进行自上而下和自下而上的动态规划计算,然后进行垂直方向的匹配代价累积 
《立体匹配---动态规划》

《立体匹配---动态规划》 
为避免视差图在极线间出现垂直条纹,采用权重方式实现匹配代价的更新。 
《立体匹配---动态规划》

D:基于控制点的双向动态规划 
以左图为准时,从左到右搜索最优路径,以右图为准时,从右到左搜索最优路径。当路径到达控制点时,记录下控制点处的视差值,用来约束控制点后面像素的能量函数计算,进而达到约束后面像素的视差结果的作用。非控制点处,左右极线上分别进行动态规划的计算,然后利用动态规划回溯的方法寻找每个像素的视差。

计算出左右视差图像后,根据弱一致性约束,当左视差图像中的某点视差大于右视差图像对应点的视差时采用其对应点的视差取代,这样可以有效的处理半遮挡及前景物体区域的误匹配。 
对于无纹理区域的误匹配利用同区域已匹配点的视差填充。 
《立体匹配---动态规划》

对大视差的图像对误差比较大。 
若求取的控制点个数为C,那么控制点的采用可以使传统复杂度由O(MND*D)降低为O((MN-C)D*D),获得的控制点越多,动态规划的计算复杂度越小。

在论文中看到的测试结果

《立体匹配---动态规划》

《立体匹配---动态规划》

    原文作者:动态规划
    原文地址: https://blog.csdn.net/u010368556/article/details/72623041
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞