立体匹配(Stereo matching)的步骤如下:
1: 预处理:亮度归一化,去噪,图像增强,滤波等等
2: 匹配Cost计算Cost aggregation
每个像素点的matching cost可用下图所示的两种方式表示
将所有像素的Cost加起来,选择和最小的方案。
3: 全局最优化
4: 后处理:Refinement 精化
一般基于像素点的匹配含有较大的噪音,所以人们更愿意使用基于局部或全局的匹配算法。常用的立体匹配算法可分为基于局部的匹配方法和基于全局的匹配方法。
(1)基于局部的匹配算法:块匹配,模板匹配,SIFT
[1],SURF
[2],AKAZE
[3]
(2)基于全局的匹配算法:首先定义Cost Function,然后根据约束条件优化Cost Function.
- Dynamic Programming
- Scaling Optimization
- Graph Cuts
- Belief Propagation:Markov Random Field
一般的Cost Function如下:ED基于像素的亮度,Es基于像素邻居之间的Smoothness。
1:Graph Cut: 将每一个像素看作Graph中的一个Node,然后假设该图有L个不同的深度值,则添加L个
新的Node作为Label,然后求视差图的问题就变成了多重Labelling的问题了,具体Graph Cut参照文
献[4]。
2:Belief Propagation: 将图像看作马尔科夫随机场,则求视差问题变成了最大化联合后验概率的问题,
每一个像素对其深度值的猜测来自于其邻居给的信息,然后再把信息传给其他的邻居。每一个信息有 一个可靠度(概率)。最后经过多次循环深度值会收敛。
[1]
Lowe, David G. (2004). "Distinctive Image Features from Scale-Invariant Keypoints"
[2
]
Herbert Bay,Tinne Tuytelaars, and Luc Van Gool,SURF: Speeded Up Robust Features,ECCV,2006
[3]
Pablo F. Alcantarilla, Adrien Bartoli and Andrew J. Davison, KAZE Features. In European Conference on Computer Vision (ECCV), 2012.
[4]
Yuri Boykov and Vladimir Kolmogorov (2003), "Computing Geodesics and Minimal Surfaces via Graph Cuts"
OpenCV提供了以下四种立体匹配算法的函数:
- Block Matching(BM) StereoBM
- Semi-Global Block Matching(SGBM) StereoSGBM
- Graph Cut(GC)cvStereoGCState()
- Dynamic Programming(DP)cvFindStereoCorrespondence()
计算量小速度快,而全局匹配计算量大速度慢,所以作者提出了SGBM算法[5]:
第一步对每一个Pixel使用块匹配BM进行匹配,得到了全部Pixel的disparity map。
第二步对Disparity map建立图,用Graph Cut对其进行全局优化。利用Rectification将二维转化为一维:
则对每一个像素的可能的Disparity值d,从以下4中里面选取一个最小值:
- 左相邻像素disparity取值为d时,其最小的cost值。
- 左相邻像素disparity取值为d-1时,其最小的cost值+惩罚1。
- 左相邻像素disparity取值为d+1时,其最小的cost值+惩罚1。
- 左相邻像素disparity取值为其他时,其最小的cost值+惩罚2。
要对每一种取值进行一次计算,计算量比SGBM要大得多。
[5]
H. Hirschmuller, Stereo Processing by Semi-global Matching and Mutual
Information,"IEEE Transactions on Pattern Analysis and Machine
Intelligence,
Vol. 30, Issue 2, pp. 328-341, Feb. 2008.
下图给出了各种不同算法的结果比较:
左右原图如下:
精度与速度统计图如下: