双目立体匹配算法:ADCensus概述

22 篇文章 1 订阅
11 篇文章 3 订阅

ADCensus立体匹配算法是Xing Mei, Xun Sun, Mingcai Zhou等几个人

在2011年,发表的一篇题目为:《On Building anAccurate Stereo Matching System on Graphics Hardware》中提出的。

ADCensus双目立体匹配算法曾一度排在MiddleBurry官网上第一的位置,引用量很高。

其主要优点是并行加速,精度又好,能有效兼顾这两点。

本经验主要分为以下几个方面:

ADCensus算法优点;算法步骤;匹配代价;代价聚合;视差优化;视差细化;


1、ADCensus算法优点;

基于GPU下的ADCensus立体匹配算法兼顾匹配速度和精度;

根据Scharstein 和Szeliski提出的理论算法分为以下四个步骤:

代价计算(cost initialization):绝对差AD+Census变换算法

代价聚合(cost aggregation):动态十字交叉域

视差优化(disparity computation):扫描线视差优化

后处理(refinement):多步后处理操作

以上算法都可以通过并行加速提高速度。


2、AD-Census Cost Initialization:

对每个像素点和视差等级进行处理,本质上是并行的;

所以此步骤就只考虑如何提高代价计算精度。

常见的代价计算方法:绝对差AD,

互熵信息BT(“Depth Discontinuities by Pixel-to-Pixel Stereo” by S. Birchfield and C. Tomasi),基于梯度的,Census等。

Hirschmuller和Scharstein证明:Census是具有最好效果的算法;

Census是通过对图像局部区域进行编码,具有很好的相对次序性,对光照和图像噪声鲁棒;

然而在重复区域和相似纹理区域具有匹配模糊性,导致误匹配;

又由于AD绝对差对差异性比较敏感,

所以进行结合形成ADCensus算法计算初始代价;

函数的作用:

①使匹配代价的范围在[0,1];

②通过lambda调节两者的作用;

公式效果如图所示:



3、Cross-basedCost Aggregation

代价聚合的目的:减少初始代价中的匹配模糊和图像噪声的影响。

代价聚合的依据:相似的区域具有相似的视差;

常见代价聚合方法:图像分割,自适应权重,自适应窗口等。

这篇文章采用动态交叉域的代价聚合方法:

分为两步:交叉域构建,代价聚合;

代价聚合规则:计算颜色差值和空间距离,通过3规则构建交叉域;通过4次迭代进行代价聚合。

优点:对大的少纹理和视差不连续区域减少匹配误差。




4、ScanlineOptimization

目的:选择最佳的视差范围,生成视差图。

4方向的扫描线优化策略:适合并行计算,减少匹配模糊。

P1、P2惩罚系数:


5、Multi-stepDisparity Refinement

多步视差细化

①:通过左右一致性准则,检测出离群点:遮挡区域和视差不连续区域的点

②:Iterative Region Voting:

③:Proper Interpolation:

④:Depth DiscontinuityAdjustment:

⑤:Sub-pixel Enhancement:


6、实验效果:ADCensus匹配算法:兼顾精度和速度;

据说可以达到实时的效果。


还有篇博文也是ADcensus的,http://www.cnblogs.com/sinbad360/p/7842009.html,互相印证,更好的理解。

 


  • 4
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
以下是双目立体匹配算法SGM的实时代码: ``` #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; const int max_image_size = 960; const int max_disparity = 64; const int P1 = 5; const int P2 = 70; const int penalty_scale = 10; const int uniqueness_ratio = 15; const int speckle_window_size = 100; const int speckle_range = 32; int main(int argc, char** argv) { if(argc != 3) { cout << "Usage: ./sgm_stereo left_image right_image" << endl; return -1; } Mat imgL = imread(argv[1], IMREAD_GRAYSCALE); Mat imgR = imread(argv[2], IMREAD_GRAYSCALE); if(imgL.empty() || imgR.empty()) { cout << "Error: Could not open or find the images" << endl; return -1; } int width = imgL.cols; int height = imgL.rows; if(width > max_image_size || height > max_image_size) { cout << "Error: Image size too large" << endl; return -1; } int min_disparity = 0; int max_disparity = 64; Mat disparity_map = Mat::zeros(height, width, CV_8UC1); for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { int min_cost = INT_MAX; int best_disparity = min_disparity; for(int d = min_disparity; d < max_disparity; d++) { int sum = 0; int count = 0; for(int dy = -1; dy <= 1; dy++) { for(int dx = -1; dx <= 1; dx++) { int xl = x + dx; int xr = x + dx - d; if(xl < 0 || xl >= width || xr < 0 || xr >= width) { continue; } int diff = abs((int)imgL.at<uchar>(y+dy, x+dx) - (int)imgR.at<uchar>(y+dy, xr)); sum += diff; count++; } } int cost = sum / count; if(d > min_disparity) { int diff = abs(d - best_disparity); cost += (diff == 1) ? P1 : (P1 + (diff - 1) * P2); } if(cost < min_cost) { min_cost = cost; best_disparity = d; } } disparity_map.at<uchar>(y, x) = best_disparity; } } Ptr<StereoSGBM> stereo = StereoSGBM::create(min_disparity, max_disparity, penalty_scale, 8 * imgL.channels() * speckle_window_size * speckle_window_size, 32 * speckle_range, uniqueness_ratio, StereoSGBM::MODE_SGBM_3WAY); stereo->compute(imgL, imgR, disparity_map); namedWindow("Disparity Map", WINDOW_NORMAL); imshow("Disparity Map", disparity_map); waitKey(0); return 0; } ``` 需要注意的是,此代码只是SGM算法的实现之一,针对不同的场景和需求,实现方式可能会有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值