0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于OpenCV3.0的BM、SGBM和GC算法对比

机器视觉 2019-06-12 15:10 次阅读

引言:基于OpenCV3.0,对BM、SGBM和GC算法进行了对比测试研究。由于SGBM算法视差效果好速度快的特点,常常被广泛应用和改进,本文针对SGBM算法主要参数设置作了对比测试,以供大家参考。

BM:Block Matching ,采用SAD方法计算匹配代价;

SGBM: 修改自Heiko Hirschmuller的《Stereo Processing by Semi-global Matching and Mutual Information》:http://www.openrs.org/photogrammetry/2015/SGM%202008%20PAMI%20-%20Stereo%20Processing%20by%20Semiglobal%20Matching%20and%20Mutual%20Informtion.pdf;长按以下二维码可直接打开

与原方法不同点:

没有实现原文中基于互信息的匹配代价计算,而是采用BT算法("Depth Discontinuities by Pixel-to-Pixel Stereo()" by S. Birchfield and C. Tomasi);

默认运行单通道DP算法,只用了5个方向,而fullDP使能时则使用8个方向(可能需要占用大量内存);

增加了一些BM算法中的预处理和后处理程序;

GC:OpenCV3.0中没有实现,可以在OpenCV以下版本中找到。该方法效果是最好的,但是速度太慢,不能达到实时的匹配效率;

1、SGBM

主要参数:minDisparity 、numDisparities、blockSize、P1、P2。其他参数设置参照http://blog.csdn.net/zhubaohua_bupt/article/details/51866567

代码:

#include "stdafx.h"

#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;

//SGBM

cv::Ptr sgbm = cv::StereoSGBM::create(mindisparity, ndisparities, SADWindowSize);

int P1 = 8 * left.channels() * SADWindowSize* SADWindowSize;

int P2 = 32 * left.channels() * SADWindowSize* SADWindowSize;

sgbm->setP1(P1);

sgbm->setP2(P2);

sgbm->setPreFilterCap(15);

sgbm->setUniquenessRatio(10);

sgbm->setSpeckleRange(2);

sgbm->setSpeckleWindowSize(100);

sgbm->setDisp12MaxDiff(1);

//sgbm->setMode(cv::StereoSGBM::MODE_HH);

sgbm->compute(left, right, disp);

disp.convertTo(disp, CV_32F, 1.0 / 16); //除以16得到真实视差值

Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1); //显示

normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1);

imwrite("results/SGBM.jpg", disp8U);

return 0;

}

minDisparity:最小视差,默认为0。此参数决定左图中的像素点在右图匹配搜索的起点,int 类型;

numDisparities:视差搜索范围长度,其值必须为16的整数倍。最大视差 maxDisparity = minDisparity + numDisparities -1;

blockSize:SAD代价计算窗口大小,默认为5。窗口大小为奇数,一般在3*3 到21*21之间;

P1、P2:能量函数参数,P1是相邻像素点视差增/减 1 时的惩罚系数;P2是相邻像素点视差变化值大于1时的惩罚系数。P2必须大于P1。需要指出,在动态规划时,P1和P2都是常数。

一般建议:P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

总结:

1. blockSize(SADWindowSize) 越小,也就是匹配代价计算的窗口越小,视差图噪声越大;blockSize越大,视差图越平滑;太大的size容易导致过平滑,并且误匹配增多,体现在视差图中空洞增多;

2. 惩罚系数控制视差图的平滑度,P2>P1,P2越大则视差图越平滑;

3. 八方向动态规划较五方向改善效果不明显,主要在图像边缘能够找到正确的匹配;

2、BM

代码:

#include "stdafx.h"

#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 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);

disp.convertTo(disp, CV_32F, 1.0 / 16); //除以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;

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器视觉
    +关注

    关注

    160

    文章

    3996

    浏览量

    118084
  • OpenCV
    +关注

    关注

    29

    文章

    609

    浏览量

    40710

原文标题:立体匹配算法对比研究

文章出处:【微信号:www_51qudong_com,微信公众号:机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于QT+OpenCv的目标跟踪算法实现

    目标跟踪算法作为一种有着非常广泛的应用的算法,在航空航天、智能交通、智能设备等领域有着非常广泛的应用。本系列博客将教大家在410c开发板上基于linux操作系统环境,采用QT+Opencv来实现
    发表于 09-21 10:42

    算法对比误差公式

    算法对比误差公式 D
    发表于 09-17 08:38

    关于BM_OPENCV相关问题

    upsample的做法没有标准强制统一,jpeg-turbo提供了默认Fancy upsample,也提供了快速复制上采样的算法,原生opencv采用默认的fancy upsample;而BM
    发表于 09-19 07:28

    如何在开发环境中的Python环境下使用我们提供的BM-OpenCV?

    如何在开发环境中的Python环境下使用我们提供的BM-OpenCV?
    发表于 09-19 07:14

    关于BM-OpenCV中GB28181接口,说的是接国标流是吧?本身支持转国标流功能吗?

    关于BM-OpenCV中GB28181接口,说的是接国标流是吧?本身支持转国标流功能吗?
    发表于 09-19 06:31

    openCV的库自带了模板匹配算法吗?

    openCV的库自带了模板匹配算法
    发表于 10-10 06:48

    改进的AC-BM字符串匹配算法

    提出了改进的AC-BM算法,将待匹配的字符串集合转换为一个类似于Aho-Corasick算法的树状有限状态自动机。匹配时,采取自后向前的方法,并借用BM
    发表于 12-10 17:30 13次下载

    基于网络入侵模式匹配的BM 算法研究与优化The Optim

    本文在分析现有网络入侵模式匹配BM 算法的基础上,提出了改进BM 规则匹配算法。该算法克服了传统BM
    发表于 05-27 16:42 29次下载

    BM模式匹配算法的研究和改进

    模式匹配算法在数字通信、入侵检测等多种领域都有着广泛的应用,BM算法以其高效的匹配过程成为模式匹配算法中应用最为广泛的算法之一。尽管如此,
    发表于 10-17 11:23 0次下载
    <b class='flag-5'>BM</b>模式匹配<b class='flag-5'>算法</b>的研究和改进

    直方图对比_《OpenCV3编程入门》书本配套源代码

    OpenCV3编程入门》书本配套源代码:直方图对比
    发表于 06-06 15:52 9次下载

    字符串的KMP算法BM算法

    本文主要介绍KMP算法BM算法,它们分别是前缀匹配和后缀匹配的经典算法。所谓前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从左到右;所谓后缀匹配是指:模式串和母串的的比较
    发表于 11-15 14:53 2269次阅读
    字符串的KMP<b class='flag-5'>算法</b>和<b class='flag-5'>BM</b><b class='flag-5'>算法</b>

    opencv3.0.0(x86)安装教程与配置设置教程

    OpenCV3.0的几个变动   更加细颗粒度的模块化,大量的 module   更加的 C++ 化,所有算法继承自 cv::Algorithm,算法的接口统一   向过去
    发表于 12-14 18:30 2次下载

    opencv 白平衡算法

    白平衡就是图片中最亮的部分为白色,最暗的部分为黑色,其余部分进行拉伸。下文将详细介绍OpenCV实现的灰度世界算法
    发表于 01-17 09:05 7376次阅读

    立体匹配:经典算法Fast Bilateral Solver

    而下面左图是OpenCVSGBM算法得到的视差图,右边则是通过我今天要介绍的算法处理后的视差图。看了它们后,我想你应该对什么叫做”化腐朽为神奇“有了深刻印象了吧。
    的头像 发表于 01-03 10:59 1052次阅读

    深入探讨SGBM参数影响效果

    SGBM(Semi-Global Block Matching)是一种用于计算双目视觉中视差(disparity)的半全局匹配算法,在OpenCV中的实现为semi-global block matching(
    的头像 发表于 06-28 09:29 1327次阅读
    深入探讨<b class='flag-5'>SGBM</b>参数影响效果