最近整理了一下这两年一直在用嘚摄像机定标与立体匹配测试程序将代码进行了重构,界面也做了调整分享出来方便有需要的朋友使用。当然我的编程能力有限程序可能还有各种bug,请大家多多包涵相关问题欢迎留言...
四、双目匹配与视差计算
立体匹配主要是通过找出每对图像间的对应关系根据三角测量原理,得到视差图;在获得了视差信息后根据投影模型很容易地可以得到原始圖像的深度信息和三维信息。立体匹配技术被普遍认为是立体视觉中最困难也是最关键的问题主要是以下因素的影响:
(1) 光学失真和噪声(亮度、色调、饱和度等失衡)
(2) 平滑表面的镜面反射
目前立体匹配算法是计算机视觉中的一个难点和热点,算法很多但是一般嘚步骤是:
匹配代价计算是整个立体匹配算法的基础,实际是对不同视差下进行灰度相似性测量常见的方法有灰度差的平方SD(squared intensity differences),灰度差的绝对值AD(absolute intensity differences)等另外,在求原始匹配代价时可以设定一个上限值来减弱叠加过程中的误匹配的影响。以AD法求匹配代价为例可用下式进行计算,其中T为设定的阈值
一般来说,全局算法基于原始匹配代价进行后续算法计算而区域算法则需要通过窗口叠加来增强匹配玳价的可靠性,根据原始匹配代价不同可分为:
对于区域算法来说,在完成匹配代价的叠加以后视差的获取就很容易了,只需在一定范围内选取叠加匹配代价最优的点(SAD和SSD取最小值NCC取最大值)作为对应匹配点,如胜者为王算法WTA(Winner-take-all)而全局算法则直接对原始匹配代价進行处理,一般会先给出一个能量评价函数然后通过不同的优化算法来求得能量的最小值,同时每个点的视差值也就计算出来了
D、视差细化(亚像素级)
大多数立体匹配算法计算出来的视差都是一些离散的特定整数值,可满足一般应用的精度要求但在一些精度要求比較高的场合,如精确的三维重构中就需要在初始视差获取后采用一些措施对视差进行细化,如匹配代价的曲线拟合、图像滤波、图像分割等
有关立体匹配的介绍和常见匹配算法的比较,推荐大家看看 的讲义 190页的ppt,讲解得非常形象详尽
(1) 新增了 SGBM 立体匹配算法(源自Heiko Hirschmuller的《》),可以获得比 BM 算法物体轮廓更清晰的视差图(但低纹理区域容易出现横/斜纹路在 GCstate->fullDP 选项使能时可消减这种异常纹路,但对应区域视差變为0且运行速度会有所下降),速度比 BM 稍慢 352*288的帧处理速度大约是 5 帧/秒;
(3) BM 算法比2.0版性能有所提升,其状态参数新增了对左右视图感兴趣區域 ROI 的支持(roi1 和 roi2由stereoRectify函数产生);
(4) BM 算法和 GC 算法的核心代码改动不大,主要是面向多线程运算方面的(由 OpenMP 转向 Intel TBB);
2. 用于立体匹配的图像可鉯是彩色的吗
在opencv生成3d模型2.1中,BM和GC算法只能对8位灰度图像计算视差SGBM算法则可以处理24位(8bits*3)彩色图像。所以在读入图像时应该根据采用嘚算法来处理图像:
3. 怎样获取与原图像有效像素区域相同的视差图?
在opencv生成3d模型2.0及以前的版本中所获取的视差图总是在左侧和右侧有奣显的黑色区域,这些区域没有有效的视差数据视差图有效像素区域与视差窗口(ndisp,一般取正值且能被16整除)和最小视差值(mindisp一般取0戓负值)相关,视差窗口越大视差图左侧的黑色区域越大,最小视差值越小视差图右侧的黑色区域越大。其原因是为了保证参考图像(一般是左视图)的像素点能在目标图像(右视图)中按照设定的视差匹配窗口匹配对应点opencv生成3d模型
这样的设置很明显是不符合实际应鼡的需求的,它相当于把摄像头的视场范围缩窄了因此,opencv生成3d模型2.1 做了明显的改进不再要求左右视图和视差图的大小(size)一致,允许對视差图进行左右边界延拓这样,虽然计算视差时还是按上面的代码思路来处理左右边界但是视差图的边界得到延拓后,有效视差的范围就能够与对应视图完全对应具体的实现代码范例如下:
“:在opencv生成3d模型2.0中BM函数得出的结果是以16位符号数的形式的存储的,出于精度需要所有的视差在输出时都扩大了16倍(2^4)。其具体代码表示如下:
可以看到原始视差在左移8位(256)并且加上一个修正值之后又右移了4位,最终的结果就是左移4位
因此,在实际求距离时cvReprojectTo3D出来的X/W,Y/W,Z/W都要乘以16 (也就是W除以16),才能得到正确的三维坐标信息”
在opencv生成3d模型2.1中,BM算法可以用 CV_16S 或者 CV_32F 嘚方式输出视差数据使用32位float格式可以得到真实的视差值,而CV_16S 格式得到的视差矩阵则需要 除以16
5. 如何设置BM、SGBM和GC算法的状态参数
在上述参数中对视差生成效果影响较大的主要参數是 SADWindowSize、numberOfDisparities 和 uniquenessRatio 三个,一般只需对这三个参数进行调整其余参数按默认设置即可。
SGBM算法的状态参数大部分与BM算法的一致下面只解释不同的部汾:
注意opencv生成3d模型2.1的SGBM算法是用C++ 语言编写的没有C实现模块。与H. Hirschmuller提出的原算法相比主要有如下变化:
在创建算法状态结构体时一次性确定,不能在循环中更新状态信息GC算法并不是一种实时算法,但可以得到物体轮廓清晰准确的视差图适用于静态环境物体的深度重构。
注意GC算法只能在C语言模式下运行并且不能对视差图进行预先的边界延拓,左右视图和左右视差矩阵的大小必须一致
6. 如何实现视差图的伪彩色显示?
首先要将16位符号整形的视差矩阵转换为8位无符号整形矩阵然后按照一定的变换關系进行伪彩色处理。我的实现代码如下:
灰度图转伪彩色图的代码主要功能是使灰度图中 亮度越高的像素点,在伪彩色图中对应的点樾趋向于 红色;亮度越低则对应的伪彩色越趋向于 蓝色;总体上按照灰度值高低,由红渐变至蓝中间色为绿色。其对应关系如下图所礻:
7. 如何将视差数据保存为 txt 数据文件以便在 Matlab 中读取分析
由于opencv生成3d模型本身只支持 xml、yml 的数据文件读写功能,并且其xml文件与构建网页数据所用的xml文件格式不一致在Matlab中无法读取。峩们可以通过以下方式将视差数据保存为txt文件再导入到Matlab中。
相应的Matlab代码为:
采用BM立体匹配算法计算TUKUBA图像的稠密视差并给出视差图 程序采用c++编写,利用opencv生成3d模型/mdeditor/
opencv生成3d模型+OpenGL利用视差图进行三维重建对于双目摄像机拍摄的经过外极线矫正的图像,進行立体匹配根据特征点进行三角剖分,纹理贴图最后进行三维重建。
这是我双目测距中的立体匹配的代码得到视差图,通过三维偅建得到视差图中的世界坐标系的坐标使用的是opencv生成3d模型//a_simple_camer…ram_mfc_opencv生成3d模型/
调用opencv生成3d模型库提供的BM以及SGBM算法获得效果较好的视差图。其中算法具体参数详解见/this_is_chris/article/details/SAD算法参考网上自己实现,效果不是很好
程序完全是由python3+opencv生成3d模型实现的,包括标定板图像采集单目相机标定,双目相機标定立体矫正,SGBM立体匹配生成视差图像。测距并非采用opencv生成3d模型传统三维函数通过记录实验数据,对实验数据进行多项式拟合通过...
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。