opencvSGBM半全局立体匹配算法的研究(1)
转载请说明出处: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)的更多相关文章
- OpenCV3.4两种立体匹配算法效果对比
以OpenCV自带的Aloe图像对为例: 1.BM算法(Block Matching) 参数设置如下: ) + ) & -; cv::Ptr<cv::StereoBM> b ...
- 【OpenCV】立体匹配算法SSD、NCC、ASW的基础实现
要求:对给出的左右视图进行匹配,最后输出左右两张disparity map(视差图) e.g. 左视图.右视图(两幅图像大小相同,只有水平方向上的视角变换) 标准视差图如下: SSD(sum ...
- move_base的全局路径规划代码研究
algorithmn parameter code 主要是以下三个函数 计算所有的可行点 怎么计算一个点的可行点 从可行点中计算路径path todo algorithmn 算法的解释 Dijkstr ...
- 双目立体匹配经典算法之Semi-Global Matching(SGM)概述:匹配代价计算之互信息(Mutual Information,MI)
半全局立体匹配算法Semi-Global Matching,SGM由学者Hirschmüller在2005年所提出1,提出的背景是一方面高效率的局部算法由于所基于的局部窗口视差相同的假设在很多情况 ...
- 立体匹配-----NCC视差匹配
目录 一.立体匹配算法 1.立体匹配算法分类 二.NCC 视差匹配方法 1.原理 2.NCC计算公式 3.算法流程 4.代码实现 5.不同场景运行 三.结论 四.遇到的问题及解决方法 一.立体 ...
- 双目立体匹配经典算法之Semi-Global Matching(SGM)概述:代价聚合(Cost Aggregation)
由于代价计算步骤只考虑了局部的相关性,对噪声非常敏感,无法直接用来计算最优视差,所以SGM算法通过代价聚合步骤,使聚合后的代价值能够更准确的反应像素之间的相关性,如图1所示.聚合后的新的代价值保存 ...
- 深度学习结合SLAM研究总结
博客转载自:https://blog.csdn.net/u010821666/article/details/78793225 原文标题:深度学习结合SLAM的研究思路/成果整理之 1. 深度学习跟S ...
- 一些对数学领域及数学研究的个人看法(转载自博士论坛wcboy)
转自:http://www.math.org.cn/forum.php?mod=viewthread&tid=14819&extra=&page=1 原作者: wcboy 现在 ...
- matlab stereo_gui立体标定
http://www.vision.caltech.edu/bouguetj/calib_doc/index.html#examples 文档中举了几个例子,有关双目的是第5个, 这个例子展示了如何使 ...
随机推荐
- 浅谈 HTTP 协议
一. HTTP简介 超文本传输协议 Hyper Text Transfer Protocol 是一种用于分布式.协作式和超媒体信息系统的应用层协议 HTTP是万维网的数据通信的基础 HTTP有很多应用 ...
- go 和make的用法 区别
Doand Make are two verbs which frequently confuse students of English. Learn the Difference between ...
- linux下防火墙iptables原理及使用
iptables简介 netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火 ...
- unittest和pytest对比
一.用例编写规则 1.unittest提供了test cases.test suites.test fixtures.test runner相关的类,让测试更加明确.方便.可控.使用unittest编 ...
- SQL server游标基本结构
简单游标遍历数据: BEGIN DECLARE QZ_cursor CURSOR SCROLL FOR /*创建游标*/ SELECT NAME FROM USERINFO/*要遍历的数据*/ OPE ...
- x86 idt
Interrupt/trap gate
- windows和ubuntu14.04双系统设置默认启动项
首先开机或者重启,在启动项选择菜单处记住win7对应的序号,从上至下的序号从0开始计数,我的win7系统选项处于第5个,那么序号就应该是4,记住后,打开ubuntu系统. 2 按下Ctrl+alt+T ...
- 九度oj 题目1347:孤岛连通工程
题目描述: 现在有孤岛n个,孤岛从1开始标序一直到n,有道路m条(道路是双向的,如果有多条道路连通岛屿i,j则选择最短的那条),请你求出能够让所有孤岛都连通的最小道路总长度. 输入: 数据有多组输入. ...
- Mysql 主外键与索引之间的区别和联系
系数据库依赖于主键,它是数据库物理模式的基石.主键在物理层面上只有两个用途: 惟一地标识一行. 作为一个可以被外键有效引用的对象. 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部 ...
- 算法复习——拓展欧几里得(poj1061)
题目: Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很 ...