### 计算机视觉中的视差图与SGBM算法 #### 一、引言 在计算机视觉领域,双目视觉技术是实现三维重建的重要手段之一。通过对比两个摄像头(通常为左、右摄像头)拍摄的同一场景图像,可以计算出物体在不同视角下的位置差异,这种差异被称为“视差”。利用这些视差信息,可以生成视差图,并进一步估计场景的深度信息。 #### 二、SGBM算法简介 **Semi-Global Block Matching (SGBM)** 算法是一种高效的视差估计方法,它结合了局部匹配和全局匹配的优点。相比于传统的块匹配算法,SGBM能够在保持较高准确度的同时显著减少计算量。其核心思想是在多个一维方向上执行局部块匹配,以此来近似全局优化过程。 #### 三、SGBM算法关键参数解释 1. **mindisparity**: 最小视差值。这是视差搜索的起始点。 2. **ndisparities**: 视差范围。即最大视差与最小视差之间的差距乘以16。 3. **SADWindowSize**: 结构相似性指标(Sum of Absolute Differences, SAD)窗口大小。用于衡量两块像素之间的相似性。 4. **PreFilterSize**: 预滤波器大小。用于平滑输入图像,减少噪声影响。 5. **PreFilterCap**: 预滤波器上限。限制预滤波器的强度,避免过度平滑。 6. **TextureThreshold**: 纹理阈值。用于区分高纹理区域和低纹理区域,提高视差图的质量。 7. **UniquenessRatio**: 唯一性比例。用于确保找到的最佳匹配是唯一的。 8. **Disp12MaxDiff**: 左右视差图之间的最大差异。用于校验结果的一致性。 #### 四、SGBM算法实现流程 1. **初始化SGBM对象**:通过调用`cv::StereoBM::create()`创建SGBM对象,并设置基本参数,如`ndisparities`和`SADWindowSize`。 2. **设置SGBM参数**:根据具体需求调整SGBM算法的参数,例如预滤波器大小、预滤波器上限等。 3. **图像预处理**:对输入图像进行必要的预处理操作,比如填充边界等,以便于后续计算。 4. **视差图计算**:调用`compute()`方法计算视差图。 5. **后处理**:将计算得到的视差图转换为合适的格式,并进行归一化处理,便于显示或保存。 #### 五、示例代码解析 ```cpp // 加载必要的库 #include "opencv2/opencv.hpp" using namespace std; using namespace cv; int _tmain(int argc, _TCHAR* argv[]) { // 读取左右图像 Mat left = imread("imgL.jpg", IMREAD_GRAYSCALE); Mat right = imread("imgR.jpg", IMREAD_GRAYSCALE); // 初始化视差图 Mat disp; // 设置SGBM算法参数 int mindisparity = 0; int ndisparities = 64; int SADWindowSize = 11; // 创建SGBM对象 cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create(ndisparities, SADWindowSize); // 设置额外的参数 bm->setBlockSize(SADWindowSize); bm->setMinDisparity(mindisparity); bm->setNumDisparities(ndisparities); bm->setPreFilterSize(15); bm->setPreFilterCap(31); bm->setTextureThreshold(10); bm->setUniquenessRatio(10); bm->setDisp12MaxDiff(1); // 图像预处理 copyMakeBorder(left, left, 0, 0, 80, 0, IPL_BORDER_REPLICATE); copyMakeBorder(right, right, 0, 0, 80, 0, IPL_BORDER_REPLICATE); // 计算视差图 bm->compute(left, right, disp); // 转换视差图格式 disp.convertTo(disp, CV_32F, 1.0 / 16); // 将视差值转换为浮点数 // 去除多余的边缘 disp = disp.colRange(80, disp.cols); // 归一化处理 Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1); normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1); // 保存视差图 imwrite("results/BM.jpg", disp8U); return 0; } ``` #### 六、总结 SGBM算法是双目视觉中一种重要的视差估计方法,它能够快速准确地生成视差图。通过对SGBM算法的关键参数进行合理设置,可以在保持高精度的同时有效降低计算复杂度。上述示例代码展示了如何使用OpenCV库实现SGBM算法,这对于从事计算机视觉研究的开发者来说具有很高的参考价值。
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat left = imread("imgL.jpg", IMREAD_GRAYSCALE);
Mat right = imread("imgR.jpg", IMREAD_GRAYSCALE);
Mat disp;
int mindisparity = 0;
int ndisparities = 64;
int SADWindowSize = 11;
cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create(ndisparities, SADWindowSize);
// setter
bm->setBlockSize(SADWindowSize);
bm->setMinDisparity(mindisparity);
bm->setNumDisparities(ndisparities);
bm->setPreFilterSize(15);
bm->setPreFilterCap(31);
bm->setTextureThreshold(10);
bm->setUniquenessRatio(10);
bm->setDisp12MaxDiff(1);
copyMakeBorder(left, left, 0, 0, 80, 0, IPL_BORDER_REPLICATE); //防止黑边
copyMakeBorder(right, right, 0, 0, 80, 0, IPL_BORDER_REPLICATE);
bm->compute(left, right, disp);
- 空木莲华2702022-04-20有没有stdafx.h头文件,我打开了,报错显示无法打开源文件“stdafx.h”
- 粉丝: 8
- 资源: 15
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助