转载请说明出处:http://blog.csdn.net/zhubaohua_bupt/article/details/51866567

这段时间对opencvSGBM半全局立体匹配算法进行了比較仔细的研究。现总结一下。

本文先描写叙述一下opencvSGBM算法流程,接着给出调用opencvSGBM须要设置參数的含义、数值选取以及执行效果。最后贴出opencvSGBM源代码。

第一部分:SGBM算法研究总结:

整个算法实现分为

1预处理

2代价计算

3动态规划(默认4条路径)

4后处理

这四个步骤。

下面分别说明一下各个步骤:

预处理

Step1:SGBM採用水平Sobel算子,把图像做处理,公式为:

Sobel(x,y)=2[P(x+1,y)-P(x-1,y)]+ P(x+1,y-1)-P(x-1,y-1)+ P(x+1,y+1)-P(x-1,y+1)

Step2:用一个函数将经过水平Sobel算子处理后的图像上每个像素点(P表示其像素值

)映射成一个新的图像:PNEW表示新图像上的像素值。

映射函数:

  preFilterCap 为一个常数參数,opencv缺省情况下取15,例程中取63。

预处理实际上是得到图像的梯度信息。

经预处理的图像保存起来,将会用于计算代价

代价计算

代价有两部分组成:

1经过预处理得到的图像的梯度信息经过基于採样的方法得到的梯度代价

2原图像经过基于採样的方法得到的SAD代价

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" width="400" height="80" />

上述两个代价都会在SAD窗体内进行计算。

关于什么是基于採样的方法,參考论文:DepthDiscontinuities by Pixel-to-Pixel Stereo     在计算代价的时候,用基于採样的方法效果会好一些。

动态规划

规划公式:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" width="400" height="120" />

默认4条路径,当中动态规划非常重要两个參数P1。P2是这样设定的:

P1 =8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

cn是图像的通道数, SADWindowSize是SAD窗体大小。数值为奇数。

能够看出,当图像通道和SAD窗体确定下来。SGBM的规划參数P1和P2是常数

后处理

opencvSGBM的后处理包括下面几个步骤:

Step1:唯一性检測:视差窗体范围内最低代价是次低代价的(1 + uniquenessRatio/100)倍时。最低代价相应的视差值才是该像素点的视差,否则该像素点的视差为0。当中uniquenessRatio是一个常数參数。

Step2:亚像素插值

       插值公式:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" width="300" height="90" />

Step3:左右一致性检測:误差阈值disp12MaxDiff默觉得1,能够自己设置。

OpencvSGBM计算右视差图的方式:

通过得到的左视察图计算右视差图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

图1通过得到的左视察图计算右视差图

 

这个时候dispR[X-d]是d还是d+n?

实际上,dispR[X-d]的确定方式是比較dispL中X和X+n出的最小代价,选代价最小的相应的视差作为最优视差。

确定右图视差后,通过这样一个措施来确定左视察图中的像素视差是否有效:

| dispR[X-d]-dispL[X]|<disp12MaxDiff&&| dispR[X-d-1]- dispL[X]-1|<disp12MaxDiff  (条件1)

假设这个条件成立,就是误匹配点。

这个条件成立,为什么就是误匹配点呢?

实际上这个条件(LRcheck)检測的大都是遮挡点,比方图1中,左视差图X和X+n处依照图一规则都会映射到右视差图的X-d处,若在左视差图中。X位置是遮挡点,那么左视差图X位置的最小代价一定会比X+n处大(由于X处根本找不到匹配,所谓最小代价也是非常大的)。这样dispR[X-d]=d+n。

如今開始用条件1来检測左视差图的误匹配点。

先解释一下条件1左側的条件:检測到X处(遮挡误匹配点),发现dispR[x-d]=d+n。并非d。

因此就会符合条件1中的dispR[X-d]-dispL[X]|<disp12MaxDiff,

实际上这个条件是想解决一个这种事情:当左图多个点同一时候匹配到右图中同一个点时,怎样选择正确的匹配关系。毕竟左右图像素应该是一对一的。

解决方法:觉得多对匹配关系中。匹配代价最低的是正确匹配关系,然后用条件1选出正确的匹配关系。

亲測把条件1变成dispR[X-d]-dispL[X]|<disp12MaxDiff检測效果和条件1差点儿无区别。

再解释一下条件1右側的条件:

条件1的还有一部分(| dispR[X-d-1]-dispL[X]-1|<disp12MaxDiff)是用来检測右视差图在X-d处的视差值是否连续,假设左视差图X处是遮挡误匹配点。那么dispL[X]中的d是不准确的,因此dispR[X-d]=d也是不准确的,即不能保证dispR[X-d-1]处视差值和d非常相近。故右视差图在X-d处的视差值是不连续的。

综上。在左视察图中。假设一个像素点是遮挡误匹配点,那么就会符合条件1。因而就会被检測出来

Step4:连通区域的检測:简述:对左右一致性检測后的视差图再一次检測误匹配点,依据与当前处理的视差点满足连通条件的像素点个数来推断当前处理的视差点是否是误匹配点,个数小于一个阈值就觉得是误匹配点。

方法:循环遍历每个像素点。对每个视差像素点d而言,检測其周围(上下左右)的视差是否满足这种条件(称为视差连通条件):

1, 首先是LRcheck后,视差有效的点

2。 和中心视差值的(变化)绝对值不超过speckleRange。注:speckleRange是一个常数參数。能够自己设定。Opencv例程中speckleRange=10.

对于一个视差点

Step1:当上下左右(下面简称周围)点至少有一个视差点满足视差连通条件后,再分别以它们为起点(称为传播)。检測其周围(前向传播的点不算。比方。Pixel2是通过Pixel1传播过来的,即Pixel2肯定是Pixel1周围的点。再以Pixel2为起点检測周围的视差点是否满足视差连通条件时,Pixel1尽管也是Pixel2周围的视差点,但不算满足视差连通条件)的视差点是否满足视差连通条件。

Step2:每检測到一个新的连通点,其相应点的标志位置1,,计数器加一,直到对于每个新的连通点,其周围的点(标志位置1的点也不算满足视差连通条件)都不满足视差连通条件。停止计数。

Step3:推断计数值(即和当前处理的视差点的连通区域的像素点个数)>speckleWindowSize?

(注:speckleWindowSize是一个常数參数。能够自己设定。

Opencv例程中speckleRange=100。)若大于,视差值觉得有效。否则觉得当前视差值是噪点。

连通区域检測有助于去除经LR和唯一性检測后残余的噪点。效果比較理想。

  

第二部分:opencvSGBM算法的參数含义及数值选取

一 预处理參数

1:preFilterCap:水平sobel预处理后。映射滤波器大小。默觉得15

int ftzero =max(params.preFilterCap, 15) | 1;

opencv測试例程test_stereomatching.cpp中取63。

二 代价參数

2:SADWindowSize:计算代价步骤中SAD窗体的大小。

由源代码得。此窗体默认大小为5。

SADWindowSize.width= SADWindowSize.height = params.SADWindowSize > 0 ?params.SADWindowSize : 5;

注:窗体大小应为奇数,一般应在3x3到21x21之间。

3:minDisparity:最小视差,默觉得0。

此參数决定左图中的像素点在右图匹配搜索的起点。int 类型

4:numberOfDisparities:视差搜索范围,其值必须为16的整数倍(CV_Assert( D % 16 == 0 );)。

最大搜索边界= numberOfDisparities+ minDisparity。int 类型

三 动态规划參数

动态规划有两个參数,各自是P1、P2。它们控制视差变化平滑性的參数。P1、P2的值越大,视差越平滑。P1是相邻像素点视差增/减 1 时的惩处系数;P2是相邻像素点视差变化值大于1时的惩处系数。P2必须大于P1。须要指出,在动态规划时,P1和P2都是常数。

5:opencv測试例程test_stereomatching.cpp中。P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

6:opencv測试例程test_stereomatching.cpp中,P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;

四:后处理參数

7:uniquenessRatio:唯一性检測參数。对于左图匹配像素点来说,先定义在numberOfDisparities搜索区间内的最低代价为mincost,次低代价为secdmincost。

假设满足

即说明最低代价和次第代价相差太小,也就是匹配的区分度不够,就觉得当前匹配像素点是误匹配的。

opencv測试例程test_stereomatching.cpp中,uniquenessRatio=10。int 类型

8:disp12MaxDiff:左右一致性检測最大容许误差阈值。

int 类型

opencv測试例程test_stereomatching.cpp中。disp12MaxDiff =1。

9:speckleWindowSize:视差连通区域像素点个数的大小。对于每个视差点,当其连通区域的像素点个数小于speckleWindowSize时。觉得该视差值无效,是噪点。

opencv測试例程test_stereomatching.cpp中。speckleWindowSize=100。

10:speckleRange:视差连通条件,在计算一个视差点的连通区域时,当下一个像素点视差变化绝对值大于speckleRange就觉得下一个视差像素点和当前视差像素点是不连通的。

opencv測试例程test_stereomatching.cpp中,speckleWindowSize=10。

执行效果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="320" height="240" alt="" />     

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="320" height="240" alt="" />     

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="320" height="240" alt="" />

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="320" height="240" alt="" />     

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="320" height="240" alt="" />

                 源代码见opencvSGBM半全局立体匹配算法的研究(2)

 

 

opencvSGBM半全局立体匹配算法的研究(1)的更多相关文章

  1. OpenCV3.4两种立体匹配算法效果对比

    以OpenCV自带的Aloe图像对为例:     1.BM算法(Block Matching) 参数设置如下: ) + ) & -; cv::Ptr<cv::StereoBM> b ...

  2. 【OpenCV】立体匹配算法SSD、NCC、ASW的基础实现

    要求:对给出的左右视图进行匹配,最后输出左右两张disparity map(视差图) e.g. 左视图.右视图(两幅图像大小相同,只有水平方向上的视角变换)   标准视差图如下:   SSD(sum ...

  3. move_base的全局路径规划代码研究

    algorithmn parameter code 主要是以下三个函数 计算所有的可行点 怎么计算一个点的可行点 从可行点中计算路径path todo algorithmn 算法的解释 Dijkstr ...

  4. 双目立体匹配经典算法之Semi-Global Matching(SGM)概述:匹配代价计算之互信息(Mutual Information,MI)

      半全局立体匹配算法Semi-Global Matching,SGM由学者Hirschmüller在2005年所提出1,提出的背景是一方面高效率的局部算法由于所基于的局部窗口视差相同的假设在很多情况 ...

  5. 立体匹配-----NCC视差匹配

    目录 一.立体匹配算法 1.立体匹配算法分类 二.NCC 视差匹配方法 1.原理 2.NCC计算公式 3.算法流程 4.代码实现     5.不同场景运行 三.结论 四.遇到的问题及解决方法 一.立体 ...

  6. 双目立体匹配经典算法之Semi-Global Matching(SGM)概述:代价聚合(Cost Aggregation)

      由于代价计算步骤只考虑了局部的相关性,对噪声非常敏感,无法直接用来计算最优视差,所以SGM算法通过代价聚合步骤,使聚合后的代价值能够更准确的反应像素之间的相关性,如图1所示.聚合后的新的代价值保存 ...

  7. 深度学习结合SLAM研究总结

    博客转载自:https://blog.csdn.net/u010821666/article/details/78793225 原文标题:深度学习结合SLAM的研究思路/成果整理之 1. 深度学习跟S ...

  8. 一些对数学领域及数学研究的个人看法(转载自博士论坛wcboy)

    转自:http://www.math.org.cn/forum.php?mod=viewthread&tid=14819&extra=&page=1 原作者: wcboy 现在 ...

  9. matlab stereo_gui立体标定

    http://www.vision.caltech.edu/bouguetj/calib_doc/index.html#examples 文档中举了几个例子,有关双目的是第5个, 这个例子展示了如何使 ...

随机推荐

  1. tomcat的安装和优化

    tomcat的安装 jdk版本安装 #!/bin/bash # desc: jdk安装脚本1. 1.7 1.8 download_url='http://**************' jdk_env ...

  2. 【Luogu】P3402最长公共子序列(LCS->nlognLIS)

    题目链接 SovietPower 的题解讲的很清楚.Map或Hash映射后用nlogn求出LIS.这里只给出代码. #include<cstdio> #include<cctype& ...

  3. Ubuntu16.04 on ThinkPad E455 不能识别耳机 的解决方法

    去年 (2016) 2月份在ThinkPad E455 上安装了Ubuntu 14.04 LTS (dual boot with Windows 10, upgraded to Ubuntu 16.0 ...

  4. BZOJ 1069 [SCOI2007]最大土地面积 ——计算几何

    枚举对角线,然后旋转卡壳即可. #include <map> #include <cmath> #include <queue> #include <cstd ...

  5. [BZOJ1604] [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(好题)

    传送门 良心题解 #include <set> #include <cstdio> #include <iostream> #include <algorit ...

  6. FZU 2186 小明的迷宫 【压状dp】

    Problem Description 小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫.因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷 ...

  7. BZOJ 1012 [JSOI2008]最大数maxnumber【线段树】

    水题,每次记录一下当前有多少个数,然后按照题目所指示的那样模拟就行,每次向线段树末尾插入(其实是修改)题目中指定的数,然后询问当前的个数到前面Q个数中最大值是多少结果就是,好久不碰线段树了,用数组模拟 ...

  8. 常州模拟赛d2t2 小X的密室

    题目描述 密室中有 N 个房间,初始时,小 X 在 1 号房间,而出口在 N 号房间. 密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会 单向地 创造一条从房间 X 到房间 Y 的通道.另 ...

  9. eopkg命令

    #命令: add-repo (ar)  ---添加存储库 blame (bl)  ---包所有者和发布信息 build (bi)  ---建立eopkg包 check  ---验证安装 clean  ...

  10. sring->list->del->string->int:解析左右编码器的,和#号

    #def test_sprintf(): import string ' str1="1234567890," print'str1 is',str1 list_raw=list( ...