OpenCV实现立体视觉的经验

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV实现立体视觉的经验相关的知识,希望对你有一定的参考价值。

来源网址:http://blog.lehu.shu.edu.cn/byman/A263366.html

2010/11/12 15:17:14 | 分享一些OpenCV实现立体视觉的经验

 尝试用OpenCV来实现立体视觉也有一段时间了,主要的参考资料就是Learning OpenCV十一、十二章和OpenCV论坛上一些前辈的讨论。过程中磕磕碰碰,走了不少弯路,终于在前不久解决了最头大的问题,把整个标定、校准、匹配的流程调试成功。(虽然还有一些问题至今尚未搞清)

在这里写这篇文章,第一方面是给自己一个总结,第二方面是感觉OpenCV立体视觉方面的资料还是相当零散和不完整,新手入门需要花很长时间才能摸索出来,第三方面,也是自己在过程中有些问题仍旧迷迷糊糊,希望可以抛砖引玉。

 

1. 摄像头

我用的摄像头是淘宝上买的三维摄像头,两个USB Camera加一个可调节的支架。实物照片如下

 

1.1 三维摄像头实物图

 

 

USB摄像头的OpenCV驱动可以参考以下链接

http://www.opencv.org.cn/index.php/使用DirectShow采集图像

 

将上面代码复制到自己的工程之后还需要对工程或者编译环境做一下设置

 

VC6下的详尽设置可以见代码的注释(修改工程的属性)

VS2008中的设置也可以参照代码注释中VC++2005的设置(修改编译环境)

 

 

2. 标定

由于OpenCVcvStereoCalibrate总是会得到很夸张的结果(见下文5.1问题描述),所以最后还是决定用BouguetMatlab标定工具箱立体标定,再将标定的结果读入OpenCV,来进行后续图像校准和匹配。

Matlab标定工具箱的参考链接如下:

http://www.vision.caltech.edu/bouguetj/calib_doc/

上面有详细的使用步骤,用起来相当的方便。

 

以下是我个人用Matlab工具箱进行立体标定的步骤,供参考,如果需要更详细步骤的话还是参照上面的链接

 

 

Matlab工具箱的文件copy到对应目录下,把所要标定的棋盘图也放到.m文件所在的目录下,然后在Matlab命令行窗口中打入calib_gui,选择Standard之后便出现以下窗口

 

2.1. calilb_gui面板

 

我们先对右摄像头的标定,所以先把从右摄像头上采集到的棋盘图复制到工具箱目录下。

点击Image names, 命令行窗口会提示你输入图片的basename以及图片的格式(比如你图片文件名是right1, right2, , right10basename就是right),然后Matlab会自动帮你读入这些图片,如下图所示,可以看到,读入了10幅右摄像头的棋盘图。

 

采集棋盘图的时候要注意,尽量让棋盘占据尽可能多的画面,这样可以得到更多有关摄像头畸变方面的信息

 

 

2.2. 图像basename读入

 

 

2.3. 读入的棋盘图

 

 

 

 

然后再回到主控制界面,点击Extract grid corners,提取每幅图的角点

 

 

2.4. calib_gui面板

 

 

点击完后,命令行会出现如下提示,主要是让你输入棋盘角点搜索窗口的大小。窗口定的大一点的话提取角点会比较方便点(即便点得偏离了也能找到),但也要注意不能大过一个方格的大小。剩下的两个选项,只要回车选用默认设置就可以了

 

2.5. 选择窗口大小

 

 

然后就开始了角点的提取工作,按一定顺序分别提取棋盘的最边上的角点,程序会自动帮你找到所有对应的角点

 

2.6. 提取角点

 

 

2.7. 提取角点2

 

 

 

在提取第一幅图的时候命令行窗口可能会提示你输入方格大小,这里输入你方格的实际大小就行,比如我方格是27mm,就输入27。这步事实上相当关键,它定义了空间的尺度,如果要对物体进行测量的话,这步是必须的。

 

按相同的方法提取完10幅图后,点击Calibration,开始摄像头标定

 

 

2.8. calib_gui面板

 

 

经过多次迭代后,程序会最终得到摄像头的内外参数,如下图所示(图中符号由于字体关系没有完全显示,中间的问号是表示误差的加减号)

 

 

 

2.9. Calibration迭代过程及结果

 

 

可以通过面板上的Show Extrinsic查看一下标定结果,可以验证一下标定外参数的结果

 

2.10. 外部参数图示

 

 

 

验证标定结果无误之后,就点击面板上的Save按钮,程序会把标定结果放在一个叫Calib_Result.mat中,为了方便后续立体标定,把这个文件名改为Calib_Result_right.mat

 

左摄像头标定的方法与右摄像头相同,生成的Calib_Result.mat之后,将其改名为Calib_Result_left.mat就可以了

 

左右摄像头都标定完成之后,就可以开始立体标定了。

 

 

Matlab命令行中键入stereo_gui启动立体标定面板,如下图所示

 

 

2.11. stereo_gui面板

 

 

点击Load left and right calibration files并在命令行中选择默认的文件名(Calib_Result_left.matCalib_Result_right.mat)之后就可以开始Run stereo calibration了,run之后的结果如下图所示,左右摄像头的参数都做了修正,并且也求出了两个摄像头之间的旋转和平移关系向量(omT)

 

2.12. 立体标定结果

 

 

在面板上点击Show Extrinsics of stereo rig,可以看到如下图所示的双摄像头关系图,可以看到,两个摄像头基本是前向平行的

 

 

2.13. 双摄像头与定标棋盘间的位置关系

 

 

得到了立体标定参数之后,就可以把参数放入xml文件,然后用cvLoad读入OpenCV了。具体的方法可以参照Learning OpenCV11章的例子,上面就是用cvSave保存标定结果,然后再用cvLoad把之前的标定结果读入矩阵的

 

2.14. xml文件示例

 

 

这里需要注意的是Matlab标定结果中的om向量,这个向量是旋转矩阵通过Rodrigues变换之后得出的结果,如果要在cvStereoRectify中使用的话,需要首先将这个向量用cvRodrigues转换成旋转矩阵。关于Rodrigues变换,Learning OpenCV的第11章也有说明。

 

 

2.15. 旋转矩阵的Rodrigues形式表示

 

 

 

 

 

 

3. 立体校准和匹配

有了标定参数,校准的过程就很简单了。

我使用的是OpenCV中的cvStereoRectify,得出校准参数之后用cvRemap来校准输入的左右图像。这部分的代码参考的是Learning OpenCV 十二章的例子。

 

校准之后,就可以立体匹配了。立体匹配OpenCV里面有两种方法,一种是Block Matching,一种是Graph CutBlock Matching用的是SAD方法,速度比较快,但效果一般。Graph Cut可以参考Kolmogrov03的那篇博士论文,效果不错,但是运行速度实在是慢到不能忍。所以还是选择BM

 

以下是我用BM进行立体匹配的参数设置

 

 

view plaincopy to clipboardprint?

1 BMState = cvCreateStereoBMState(CV_STEREO_BM_BASIC,0);  

2 assert(BMState != 0);  

3 BMState->preFilterSize=13;  

4 BMState->preFilterCap=13;  

5 BMState->SADWindowSize=19;  

6 BMState->minDisparity=0;  

7 BMState->numberOfDisparities=unitDisparity*16;  

8 BMState->textureThreshold=10;  

9 BMState->uniquenessRatio=20;  

10 BMState->speckleWindowSize=13;  

  

 

其中minDisparity这个参数我设置为0是由于我的两个摄像头是前向平行放置,相同的物体在左图中一定比在右图中偏右,如下图3.1所示。所以没有必要设置回搜的参数。

如果为了追求更大的双目重合区域而将两个摄像头向内偏转的话,这个参数是需要考虑的。

 

 

3.1. 校正后的左右视图

 

 

另外需要提的参数是uniquenessRatio,实验下来,我感觉这个参数对于最后的匹配结果是有很大的影响。uniquenessRatio主要可以防止误匹配,其主要作用从下面三幅图的disparity效果比对就可以看出。在立体匹配中,我们宁愿区域无法匹配,也不要误匹配。如果有误匹配的话,碰到障碍检测这种应用,就会很麻烦。

 

3.2. UniquenessRatio0时的匹配图,可以看到大片的误匹配区域

 

 

3.3. UniquenessRatio10时的disparity map, 可以看到误匹配被大量减少了但还是有噪点

 

 

3.4. UniquenessRatio20时的disparity map, 可以看到误匹配基本被去除了点云干净了很多

 

关于cvFindStereoCorrespondenceBM这个函数的源代码,曾经做过比较详细的研究,过一段时间也会把之前写的代码注释整理一下,发篇博文。

4. 实际距离的测量

在用cvFindStereoCorrespondenceBM得出disparity map之后,还需要通过cvReprojectImageTo3D这个函数将单通道Disparity Map转换成三通道的实际坐标矩阵。

具体的数学原理可以参考下面这个公式(from chenyusiyuan http://blog.csdn.net/chenyusiyuan/archive/2009/12/25/5072597.aspx,实际深度的一些问题这篇博文中也有提到)

 

4.1 距离转换公式

 

 

但是在实际操作过程中,用cvReprojectImageTo3D得到的数据并未如实际所想,生成深度矩阵所定义的世界坐标系我就一直没弄清楚。这在下面的例子中会详细说明,希望这方面的专家能帮忙解答一下:

 

 

4.2是测量时的实际场景图,场景中主要测量的三个物体就是最前面的利乐包装盒、中间的纸杯、和最远的塑料瓶。

 

 

4.2. 实际场景中三个待测物体的位置

 

 

4.3是校准后的左右图和匹配出来的disparity mapdisparity窗口中是实际的点云,object窗口是给disparity map加了个阈值之后得到的二值图,主要是为了分割前景和背景。可以看到要测的三个物体基本被正确地分割出来了

 

 

4.3. 双目摄像头得到的disparity map

 

4.4是在disparity窗口中选取一个点后然后在实际坐标矩阵中得到的对应三维信息,在这里,我在三个物体的点云上各选一个点来代表一个物体实际的坐标信息。(这里通过鼠标获取一点坐标信息的方法参考的是opencv sample里的watershed.cpp)

 

 

4.4. 对应点的三维坐标

 

 

在这里可以看到,(265, 156)也就是利乐包装盒的坐标是(13, 12, -157)(137, 142)纸杯的坐标是(77, 30, -312)(95, 115)塑料瓶的坐标是(144, 63, -482)

补充一下:为了方便显示,所以视差图出来之后进行了一个0-255normalize,所以value值的前一个是normalize之后点的灰度值,后一个是normalize之前点的实际视差图。

cvFindStereoCorrespondenceBM算法的源代码:

 

dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*128/d : 0) + 15) >> 4);

其中

ndisp是ndisp = state->numberOfDisparities;

mindisp是mindisp = state->minDisparity;

mind就是sad得出的视差

实际视差大约是(64-mind-1)*256=1163, 基本是对的, 后面一项修正值在通常情况下可以忽略

 

 

目前我还是不是很清楚立体坐标系原点和尺度,但是从这三个点的z坐标可以大致看出这三个物体的距离差大概是1:2:3,基本与实际场景中物体的位置一致。因此,可以通过这种方法确定出物体的大致距离信息。

 

但是,如果就从摄像头参数本身来测量距离的话,就不是很明白了,还求这方面的大牛解答。

 

 

5.  一些问题

5.1 关于StereoCalibrate

OpenCV自带的cvStereoCalibrate感觉不怎么好用,用这个函数求出的内参外参和旋转平移矩阵进行校准,往往无法达到行对准,有时甚至会出现比较可怕的畸变。在看了piaohttp://www.opencv.org.cn/forum/viewtopic.php?f=1&t=4603帖子之后,也曾经尝试过现用cvCalibrateCamera2单独标定(左右各20幅图),得出的结果基本和Matlab单独标定的相同,然后再在cvStereoCalibrate中将参数设成CV_CALIB_USE_INTRINSIC_GUESS,用来细化内参数和畸变参数,结果得出的标定结果就又走样了。

不知道有谁在这方面有过成功经验的,可以出来分享一下。毕竟用Matlab工具箱还是麻烦了些。

 

 

 

5.2 Translation向量以及立体匹配得出的世界坐标系

Learning OpenCV中对于TranslationRotation的图示是这样的

 

5.1. Learning OpenCV中的图示

 

可是在实验过程中发现,如果将Translation向量按尺度缩放,对于StereoRectify之后的左右视图不会有变化,比如将T = [ -226.73817   -0.62302  8.93984 ] ,变成T = [ -22.673817   -0.062302  0.893984 ],在OpenCV中显示的结果不会有任何变化。而且我如果修改其中的一个参量的话,左右视图发生的变化也不是图5.1中所示的那种变化(比如把x缩小,那么视图发生的变化不是往x轴方向的平移)

 

因此又回到了老问题,这里这些坐标的尺度究竟是什么?通过ReprojectTo3D那个函数得到的三维坐标又是以哪个点为原点,那三个方向为x,y,z轴的? 

 

补充对这个问题的解答来自于和maxwellsdemon的讨论

他的解释如下:rotation是两者的旋转角度的关系,但是你要把它矫正平行,也是需要translation matrix的。你可以设想,两个看似已经平行了的摄像头,但是深度上放置的有差距,那么在矫正的时候会议translation matrix所对应的角度或者直线为基准,二者旋转一个小角度,使得完全平行。

 

发表于 @ 20100402日 00:16:00 | 评论( 57 ) 举报收藏

旧一篇:zz GDB概述(LINUX下的跟踪调试) | 新一篇:OpenCV下肤色检测代码

 

查看最新精华文章 请访问博客首页相关文章

maxwellsdemon 发表于Sat Apr 03 2010 11:52:06 GMT+0800 (China Standard Time)  举报回复

 

相当好的文章! 关于StereoCalibrate,我发现,当左右视图标定出来的点的顺序(或者说是cvDrawChessboardCorners出来的折线的形状,我也不知道怎么说)不一样的时候,参数标定出来会差的离谱,不知道楼主是不是也是这个原因?如果样图中没有一副图出现上述情况,参数和cvCalibrateCamera2相差不大。 我最近也碰巧在做这个,而且剩下的疑问也是cvReprojectImageTo3D的问题

maxwellsdemon 发表于Sat Apr 03 2010 11:53:22 GMT+0800 (China Standard Time)  举报回复

 

另外对文章开头的三个方面也很有感触

匿名用户 发表于Wed Apr 07 2010 22:50:19 GMT+0800 (China Standard Time)  举报回复

 

 

sundaelovzengxi 发表于Fri Apr 09 2010 21:21:23 GMT+0800 (China Standard Time)  举报回复

 

如果想用这个方法绘制植物 难吗?

scyscyao 发表于Wed Apr 14 2010 02:03:46 GMT+0800 (China Standard Time)  举报回复

 

回复 sundaelovzengxi:如果对于实时性要求不高的话 可以用Graph Cut的方法,效果可以可以看下我当年在opencv论坛上发的算法比较贴 下面是链接 http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=9301

jdshj 发表于Sat Apr 10 2010 21:31:17 GMT+0800 (China Standard Time)  举报回复

 

太赞了,立体视觉新手感谢楼主……

wobject 发表于Tue Apr 13 2010 04:45:37 GMT+0800 (China Standard Time)  举报回复

 

我也是正在做类似应用,LZ写的很详细,很有参考价值。但我觉得LZ有个地方讲的不太正确,就是在Matlab Calibration时,LZ讲到“在提取第一幅图的时候命令行窗口可能会提示你输入方格大小,这个对于标定结果没有太大的影响,选择默认100mm就行。” 这是不正确的,应该正确输入标定格的大小,否则会影响T的大小的。T在cvStereoRectify中用到,并输出Q,这个Q在cvReprojectImageTo3D中被用到,会明显改变输出结果。因此会产生,LZ说的,比例正确,但结果不对的问题。 因为正在做这个,希望有机会跟LZ继续讨论这方面的问题。

scyscyao 发表于Wed Apr 14 2010 02:09:37 GMT+0800 (China Standard Time)  举报回复

 

回复 wobject:恩 当时对这部分没有彻底理解 后来在跟maxwellsdemon的讨论中也发现这个尺寸对于实际标定得出的距离是有影响的,如果这里的边长是实际尺寸的话那么得出的Tx就是两个摄像头之间的中心距了。。。但是现在还是有一个问题,就是即使是这个中心距是对的,在用ReprojectTo3D这个函数生成的三维坐标矩阵中得到的物体距离还是不对的,貌似用Q矩阵计算的时候d和Tx以及f的量纲都不一样 d的量纲是像素点乘以256,Tx的量纲是毫米,f的量纲也就不知道什么东西了。。。。所以到最后还是无法直接得出深度信息

wobject 发表于Thu Apr 15 2010 18:36:59 GMT+0800 (China Standard Time)  举报回复

 

回复 scyscyao: 关于 f 的纲量,我在 chenyusiyuan的博客中,回复过: 怎么把焦距数值换算为实际的物理量?假设像素点的大小为k x l,单位为mm, fx = f / k, fy = f / (l * sinA), A 一般假设为 90° , 是指摄像机坐标系的偏斜度(就是镜头坐标和CCD是否垂直)。 摄像机矩阵(内参)的目的是把图像的点从图像坐标转换成实际物理的三维坐标。因此其中的fx, fy, cx, cy 都是使用类似上面的纲量。同样,Q 中的变量 f,cx, cy 也应该是一样的。 Tx的量纲是毫米,无错。但我对d的量纲,理解为一个比例系数。你的说法,是像素点乘以256,我仍然不太能理解。网上有一个说法是该值要除以16,才能得到真正的值(http://altruisticrobot.tistory.com/219)。按照这个说法,cvReprojectImageTo3D之后得出的数值乘以16后基本能得出接近实际值,当然这是disparity图像是以16S为格式的图像, 在OpenCV2.0以前,都只能用这个格式。而在OpenCV2.1中,disparity图像新增一个图像格式32F。该格式的值,直接cvReprojectImageTo3D之后得出的数值,就是实际值,所以建议你们直接使用2.1版好了。 还有就是调用cvStereoRectify函数时,必需使用CV_CALIB_ZERO_DISPARITY,才能用cvReprojectImageTo3D函数算值,否则不准确。而这个就对两个摄像机的布置有限制了,有可能引起cvStereoRectify函数出错。 我至今还没搞明白,Q这个矩阵是如何搞出来的,不知你是否有这方面的了解?

scyscyao 发表于Sat Apr 17 2010 14:31:23 GMT+0800 (China Standard Time)  举报回复

 

回复 wobject:恩 那个我看到了 但是对于像素的说法 我不是很理解 你这里的意思是不是在像平面上 一个像素点的大小为k x l 呢? 的确我也觉得,焦距和偏移也是以像素为单位的,因为它不会随着我们定义棋盘尺度的变化而变化,但是这个k和l,是怎么求出来的? 关于像素点是乘以256这个说法 我是看源代码推测的 你可以看下我博文上新补充的代码dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*128/d : 0) + 15) >> 4); 我不知道那个韩国人乘以16是怎么得出的。。。不过reprojectTo3D那个函数出来的值应该不是除以16,我实验测过,稍后我会把视频附在博文后。 关于Q的那个问题,我不是很理解,Q这个矩阵应该就是把一些disparity转depth所要计算的量提取出来,根据式子造的一个矩阵吧

匿名用户 发表于Mon Apr 19 2010 21:20:17 GMT+0800 (China Standard Time)  举报回复

 

回复 scyscyao:那个韩国人乘以16是数据表达方式的意思,并不是说那个值错了,或者说估计被乘以了16。在DSP运算里面,为了减少运算量和存储空间,常把浮点小数表示成整数,至于小数点的位置,就人为记住。在cvFindStereoCorrespondenceBM函数中,其输入被定义成两种方式,如果是16S即16位整形的话,就默认为输入了一个16位的整数,但是它表示的disparity其实是这个整数的值除以16。在应用时,因为cvReprojectImageTo3D同样默认了这个设置,所以不用除以16。你看那个韩国人也没有除以16。 但是我做了下来发现自己输出的三维坐标也有问题,感觉单位不是毫米,而是米。。。。jiakun(at)jiakunliu.com

scyscyao 发表于Sat Apr 24 2010 11:29:09 GMT+0800 (China Standard Time)  举报回复

 

回复 匿名用户:嗯 后来wobject跟我说了我就理解了。。。现在出来的结果总算对了

wobject 发表于Tue Apr 13 2010 05:06:29 GMT+0800 (China Standard Time)  举报回复

 

cvReprojectImageTo3D函数得到的三维坐标应该是以左边摄像头的镜头中心点为坐标原点的,Learning OpenCV 那本书中说过这个。但妈妈咪的,像chenyusiyuan的博文中提到一样,好像出来的Z轴的方向好像是错的。就算是刚出来的OpenCV 2.1版,结果也是符号相反。应该是cvStereoRectify函数输出Q的问题,对比了2.0 的源代码,虽然2.1版加了一大段看得不太明白的东东,但应该对Q的结果,涉及到Z轴的代码好像没有改变。 

scyscyao 发表于Wed Apr 14 2010 02:23:06 GMT+0800 (China Standard Time)  举报回复

 

回复 wobject:其实不仅z轴的方向是错的,x,y轴的方向也反了个符号(Learning OpenCV的12章开始几张插图上x的正方向是向右,y的正方向是向下的)。其实这个问题跟maxwellsdemon也讨论过,我们试验下来是这样子的。Matlab工具箱和stereocalibrate出来的T向量Tx一般都是负的,也就是从右摄像头指向左摄像头,而在实际表达式和图示中,T一般都是由左到右的。因此为了纠正这个问题,Learning OpenCV书上Q的那个公式1/Tx前面加了一个负号。但是公式里面加了貌似代码里面忘了这一点。。。所以求出来的W都是反号的,然后X,Y,Z的符号也都反了了过来。当然,这也只是我们比对了代码运行结果之后的推测

wobject 发表于Wed May 05 2010 18:50:55 GMT+0800 (China Standard Time)  举报回复

 

回复 scyscyao: 今天发现了为什么X,Y,Z的符号都相反的原因了。因为我们在做cvStereoCalibrate时得出的结果是基于右边的镜头作为坐标原点的。这个可以通过T数值的符号发现。而现在cvReprojectImageTo3D要用基于左边镜头中心点的R和T,因此要转换。但由于R无论基于左边或右边都是一致的,所以不用变化。只要把T的符号反转就可以了。这样就不用每次都求出X,Y,Z后再变化符号。

wobject 发表于Wed May 05 2010 19:28:15 GMT+0800 (China Standard Time)  举报回复

 

回复 wobject: 好像说错了, R 也要变?

wobject 发表于Wed May 05 2010 20:24:06 GMT+0800 (China Standard Time)  举报回复

 

回复 scyscyao: 头脑有些晕了,上面说的错了。按LeaningOpenCV 第428页脚注写的"R and T are the rotation and translation that bring the right-camera coordinate system into the left. " 是我搞错了,的确是cvStereoRectify中的Q的1/Tx少了个负号。

wobject 发表于Tue Apr 13 2010 05:37:22 GMT+0800 (China Standard Time)  举报回复

 

关于rotation matirx (om) 和 translation matrix (T) 的理解,可能这样会更清晰一些。 标定时,左右镜头以各自的镜头中心点为原点,以得出相应的内参(摄像机坐标)和外参(标定板相对于各自原点的坐标)。 现在要使得右边的镜头以左边镜头的原点为原点,如果只是使用translation matrix的话,在三维空间中只是把两个原点重叠在一起,并不总能保证两坐标的方向是一致的。因此,应先用rotation matirx 保证两坐标的方向是一致的,即使的图像面平行,然后用translation matrix把原点重叠在一起。

wobject 发表于Tue Apr 13 2010 05:41:56 GMT+0800 (China Standard Time)  举报回复

 

不好意思,上面写错了一些,现在更正。 关于rotation matirx (om) 和 translation matrix (T) 的理解,可能这样会更清晰一些。 标定时,左右镜头以各自的镜头中心点为原点,以得出相应的内参(摄像机矩阵)和外参(标定板相对于镜头各自坐标原点的坐标)。 现在要使得右边的镜头以左边镜头的原点为原点,如果只是使用translation matrix的话,在三维空间中只是把两个原点重叠在一起,并不总能保证两坐标的方向是一致的。因此,应先用rotation matirx 保证两坐标的方向是一致的,然后用translation matrix把原点重叠在一起

scyscyao 发表于Wed Apr 14 2010 02:27:26 GMT+0800 (China Standard Time)  举报回复

 

回复 wobject:嗯 基本是这个意思 但其实为了使得左右图像重合区域最大化,两个摄像头都作了一定的旋转,然后再将右边的原点移到左边。另外 在StereoRectify过程中,其实两摄像头之间的中心偏移量cx cy也有所改变。这从Q矩阵输出的几个数据里就可以发现

andylida 发表于Sat Apr 24 2010 22:08:13 GMT+0800 (China Standard Time)  举报回复

 

好文章,我用的是接网卡的摄像机,前期到标定那块基本相同,我在匹配那块卡住了,我是在matlab上做的,自己用POC的方法做了下,效果很差,还有些别人的MATLAB代码做出来的效果也不好,看来也要学习一下OPENCV了。以后多指教了

scyscyao 发表于Sat Apr 24 2010 22:18:11 GMT+0800 (China Standard Time)  举报回复

 

回复 andylida:http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=9301 上面我放了个效果比较。。。GC的方法我感觉不止4秒。。。一般640X480的图我跑下来总要20到30秒左右。。效果是绝对好

andylida 发表于Sun Apr 25 2010 01:15:30 GMT+0800 (China Standard Time)  举报回复

 

回复 scyscyao:我还挺期待你的GC的代码的。。。期待博文更新

chenyusiyuan 发表于Tue Apr 27 2010 23:34:53 GMT+0800 (China Standard Time)  举报回复

 

回复 scyscyao:嗨,你做的相当不错啊,给我启发很大,最近我在尝试用OpenCV2.1来做,希望有更好的效果。关于GC方法,我当时是352*288的图,所以耗时4、5秒左右,用640*480,估计得花 2^2 倍的时间,所以要20、30秒左右应该是正常的。

andylida 发表于Sat Apr 24 2010 22:10:07 GMT+0800 (China Standard Time)  举报回复

 

还有,我想了解下Graph Cut的效果到底怎样,在邹宇华博文看也就4秒多一附图

andylida 发表于Sat Apr 24 2010 22:13:34 GMT+0800 (China Standard Time)  举报回复

 

还有,再选定窗口大小的时候,那个wintx和y应该是窗口数除二再下取整

scyscyao 发表于Sat Apr 24 2010 22:20:01 GMT+0800 (China Standard Time)  举报回复

 

回复 andylida:恩 真正窗口大小是2*n+1

andylida 发表于Sat Apr 24 2010 22:39:23 GMT+0800 (China Standard Time)  举报回复

 

回复 scyscyao:我一开始也觉得是2n+1,但是偶数格的时候好像就不是了。。。

以上是关于OpenCV实现立体视觉的经验的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenCV 进行立体视觉

OpenCV - 立体视觉的倾斜相机和三角测量地标

使用 OpenCV 来自 2 个摄像头(用于立体视觉)的视频,但其中一个摄像头滞后

双目立体视觉摄像头的标定矫正世界坐标计算(opencv)

基于HALCON的双目立体视觉系统实现

如何使用立体视觉对室内环境进行准确的 3D 重建?