1. 背景:什么是立体匹配
双目视觉(Stereo Vision)利用左右两个相机模拟人眼,通过计算同一空间点在左右图像中的位置差异(视差,Disparity)来恢复三维深度信息。
假设双目系统已经完成标定和极线校正:
text
Left Image Right Image
P(x,y) -----------------> P'(x-d,y)
其中:
- d:视差(Disparity)
- f:相机焦距
- B:双目基线长度
- Z:目标深度
深度计算公式:

可以看出:
- 视差越大 → 物体越近
- 视差越小 → 物体越远
因此双目视觉的核心问题变成:
对于左图中的每个像素,找到其在右图中的对应位置,从而计算视差 d。
这个过程称为:
Stereo Matching(立体匹配)
2. BM(Block Matching)算法
2.1 基本思想
BM 全称:
Block Matching(块匹配)
它是最经典、最简单的局部立体匹配算法。
核心思想:
不匹配单个像素,而是匹配一个窗口(Block)。
例如:
左图某位置:
text
23 25 27
30 32 31
40 41 42
在右图同一行不断向左搜索:
text
d=0
d=1
d=2
...
d=maxDisp
找到最相似的窗口。
对应的位移就是视差。
2.2 BM算法流程
Step1 极线校正
Rectification
校正后:
text
Left
---------------------
Right
---------------------
对应点一定位于同一行。
原本:
text
二维搜索
变成:
text
一维搜索
大幅降低计算量。
Step2 构建匹配窗口
对于左图像素:
text
(x,y)
构建窗口:
text
9×9
或者:
text
5×5
7×7
11×11
Step3 搜索视差
在右图对应行搜索:
text
(x-d,y)
其中:
text
d∈[0,maxDisp]
例如:
text
maxDisp=64
Step4 计算匹配代价
SAD
最常见:

绝对差求和。
即,左图窗口内每个像素值减去右图候选窗口对应像素值,然后取绝对值,再全部累加。
SSD

平方差求和。
NCC
归一化互相关:NCC, 对光照变化更鲁棒。
Step5 选择最佳视差
对于每个候选视差:
text
d=0
d=1
d=2
...
计算代价。
选择:

生成视差图。
3. BM存在的问题
BM本质属于:
Local Matching(局部匹配)
仅依赖当前窗口信息。
3.1 弱纹理区域
例如:
text
白墙
天空
窗口内容:
text
255 255 255
255 255 255
255 255 255
多个位置完全相同。
无法判断真正对应关系。
3.2 重复纹理
例如:
text
窗户
栅栏
瓷砖
多个区域长得非常相似。
容易匹配错误。
3.3 深度边界问题
窗口覆盖:
text
前景
背景
例如:
text
物体边缘
一个窗口同时包含两个深度。
导致:
text
Depth Bleeding
深度边缘模糊。
3.4 噪声严重
BM只考虑局部最优。
容易产生:
text
飞点
孔洞
条纹噪声
4. SGBM(Semi-Global Block Matching)
4.1 为什么需要SGBM
BM只考虑:Cost(p,d)
即:
当前像素匹配得好不好。
但实际上:
邻近像素深度往往连续。
例如:
text
地面
──────────
深度应该平滑变化。
因此需要加入:
text
空间连续性约束
4.2 SGBM核心思想
SGBM全称:
Semi-Global Block Matching
即:
半全局块匹配
核心思想:
text
局部匹配
+
全局优化思想
在保持较高速度的同时提高匹配精度。
5. SGBM优化目标
目标函数:

包含两个部分。
5.1 数据项(Data Cost)
匹配代价:C(p,d)
表示:
text
左图像素
↓
右图搜索
↓
匹配质量
与BM类似。
5.2 平滑项(Smoothness Cost)
约束:
text
邻近像素视差不要剧烈变化
P1:小变化惩罚
若:

增加:P_1
例如:
text
20
21
20
22
属于合理变化。
轻微惩罚。
P2:大变化惩罚
若:

增加:P_2
例如:
text
20
50
18
45
通常不合理。
给予更大惩罚。
通常:P_2 >> P_1
例如:
text
P1=200
P2=800
6. 为什么叫 Semi-Global
真正的全局优化算法:
- Graph Cut
- Belief Propagation
需要同时优化整张图像:
text
1000 × 1000
计算量极大。
SGBM采用折中方案:
只沿若干方向进行动态规划。
例如:
text
←
→
↑
↓
↖
↗
↙
↘
8个方向。
每个方向累计代价:

最终:

然后选择:

因此称为:
text
Semi-Global
半全局优化
7. SGBM中的路径聚合(Path Aggregation)
这是SGBM最核心的部分。
对于某个方向:
text
←
当前像素不仅考虑:
text
当前匹配代价
还考虑:
text
前面路径上的视差连续性
例如:
text
20
20
21
20
代价较小。
而:
text
20
45
18
50
代价较大。
这样就能有效抑制噪声。
8. OpenCV实现
StereoBM
cpp
cv::Ptr<cv::StereoBM> bm =
cv::StereoBM::create(
64,
9
);
StereoSGBM
cpp
cv::Ptr<cv::StereoSGBM> sgbm =
cv::StereoSGBM::create(
0,
128,
5
);
常见参数:
| 参数 | 含义 |
|---|---|
| minDisparity | 最小视差 |
| numDisparities | 搜索范围 |
| blockSize | 窗口大小 |
| P1 | 小变化惩罚 |
| P2 | 大变化惩罚 |
通常:
P2 \\approx 4P1
9. BM与SGBM详细对比
算法思想
BM
text
局部窗口匹配
仅依赖当前窗口。
SGBM
text
局部匹配
+
多方向全局约束
考虑邻域一致性。
精度对比
BM
容易出现:
text
孔洞
飞点
噪声
深度图较粗糙。
SGBM
深度图更平滑。
边界更准确。
误匹配更少。
弱纹理区域
BM
text
表现较差
容易随机匹配。
SGBM
利用邻域连续性。
明显改善。
深度边缘
BM
text
边界模糊
Depth Bleeding明显。
SGBM
边缘保持更好。
计算复杂度
BM
速度快。
CPU即可实时。
SGBM
需要路径聚合。
计算量增加。
通常慢2~5倍。
工程应用
BM
早期机器人系统。
教学用途较多。
SGBM
工业界应用广泛:
- ROS双目视觉
- 自动驾驶
- 机器人导航
- 三维重建
- 深度感知
10. BM和SGBM有什么区别?
BM是一种局部立体匹配算法,它通过固定窗口在左右图像之间搜索最佳匹配位置,仅利用局部窗口相似度计算视差,因此实现简单、速度快,但容易受到弱纹理、重复纹理和深度边界的影响。
SGBM则在局部匹配的基础上引入半全局优化思想,通过多方向路径代价聚合,同时考虑数据项和视差平滑项。其中P1用于惩罚小视差变化,P2用于惩罚大视差跳变,从而获得更加平滑和准确的视差图。
相比BM,SGBM在精度、鲁棒性和边缘保持能力方面显著提升,因此在实际SLAM、机器人和自动驾驶系统中应用更加广泛。
11. 一句话总结
BM:
只看当前窗口,寻找最相似块,是典型的局部匹配算法。
SGBM:
在BM基础上加入多方向路径聚合和视差平滑约束,用较小计算代价近似全局优化,是目前传统双目视觉中最常用的立体匹配算法。