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. 标定

由于OpenCV中cvStereoCalibrate总是会得到很夸张的结果(见下文5.1问题描述),所以最后还是决定用Bouguet的Matlab标定工具箱立体标定,再将标定的结果读入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, …, right10,basename就是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.mat和Calib_Result_right.mat)之后就可以开始Run stereo calibration了,run之后的结果如下图所示,左右摄像头的参数都做了修正,并且也求出了两个摄像头之间的旋转和平移关系向量(om和T)

2.12. 立体标定结果

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

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

得到了立体标定参数之后,就可以把参数放入xml文件,然后用cvLoad读入OpenCV了。具体的方法可以参照Learning OpenCV第11章的例子,上面就是用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 Cut。Block 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. UniquenessRatio为0时的匹配图,可以看到大片的误匹配区域

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

3.4. UniquenessRatio为20时的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 map,disparity窗口中是实际的点云,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-255的normalize,所以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感觉不怎么好用,用这个函数求出的内参外参和旋转平移矩阵进行校准,往往无法达到行对准,有时甚至会出现比较可怕的畸变。在看了piao的http://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中对于Translation和Rotation的图示是这样的

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所对应的角度或者直线为基准,二者旋转一个小角度,使得完全平行。

发表于 @ 2010年04月02日 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,但是偶数格的时候好像就不是了。。。

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

你的两个摄像头画面的读入是用DirectShow吗?我使用DirectShow、摄像头画面设置为640*480大小时,程序就会出错,所以就只用 352*288 的大小。

scyscyao 发表于Thu Apr 29 2010 00:45:34 GMT+0800 (China Standard Time)  举报回复

回复 chenyusiyuan:哇 惊现大牛~~ 我就用的那个。。。640X480好像没出什么问题

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

回复 chenyusiyuan: 嗯,使用OpenCV.org.cn的那个CCameraDS类,在640X480时,基本上没什么大的问题,就是占用资源多了很多。

匿名用户 发表于Tue May 18 2010 09:40:40 GMT+0800 (China Standard Time)  举报回复

你好,我才学OPENCV不久,想问你个问题,在用MATLAB立体标定后得出的结果中,好像已经提供了R矩阵,那我是不是不用将OM向量转换了再用呢?

scyscyao 发表于Fri May 28 2010 01:42:11 GMT+0800 (China Standard Time)  举报回复

回复 匿名用户:两个是等价的吧,有R的话就不用OM了

wind_beneath_wings 发表于Tue May 25 2010 15:29:40 GMT+0800 (China Standard Time)  举报回复

你好,能告诉我你的 stereo camera是在哪家店买的吗?

scyscyao 发表于Fri May 28 2010 01:43:30 GMT+0800 (China Standard Time)  举报回复

回复 wind_beneath_wings:http://item.taobao.com/item.htm?id=4271696156

xuxianri1983 发表于Wed May 26 2010 14:24:29 GMT+0800 (China Standard Time)  举报回复

好文章,我是个初学者,有几个问题向您请教下? 1、我用一个普通的摄像头,在不同的位置拍了两张图片,没有进去校正,直接用opencv的cvFindStereoCorrespondence进行匹配,结果很差,根本匹配不出来?但是我从网上下的立体图片拿来做实验,效果就很好,不知道为什么?校正主要用来做什么的? 2、你有没有一些立体图片,能不能发给我一些,有校正和没校正的都可以。[email protected],谢谢!

scyscyao 发表于Fri May 28 2010 01:45:45 GMT+0800 (China Standard Time)  举报回复

回复 xuxianri1983:校正主要是让两幅图行对准,详见我后一篇文章,随便拍的两幅图片肯定是不行的。标准立体图片详见http://vision.middlebury.edu/stereo/data/

xuxianri1983 发表于Mon Jun 07 2010 14:16:31 GMT+0800 (China Standard Time)  举报回复

回复 scyscyao: 谢谢您的回复。 我还有个问题,我直接运行learning opencv的12-3的例子,发现参数按照StereoCalib("ch12_list.txt", 9, 6, 1);这设置是可以运行的,但我把他改为StereoCalib("ch12_list.txt", 9, 6, 0);就运行出错了。 我跟踪代码后发现StereoCalib("ch12_list.txt", 9, 6, 0)摄像机标定是采用cvStereoRectify这个函数,StereoCalib("ch12_list.txt", 9, 6, 1)时摄像机标定采用cvStereoRectifyUncalibrated()这个函数, cvStereoRectify采用这种标定方法为什么会错呢?你们时怎么用这个函数的?有没有出现这种情况?

beyondabcd789 发表于Mon Jul 26 2010 19:19:23 GMT+0800 (China Standard Time)  举报回复

看了你的这篇文章对我帮助很大,我现在正在学这方面的,专了很长时间感觉也没入门,看了一些理论知识始终不清楚这个过程, scyscyao 朋友,要是方便的话,能不能把opencv实现的源码给我传一份 [email protected] 谢谢啦 !!!!!!!!

scyscyao 发表于Sun Aug 01 2010 10:53:16 GMT+0800 (China Standard Time)  举报回复

回复 beyondabcd789:可以看下opencv2.0里关于三维标定的例程,我的代码基本就是按照上面的来的

angela575 发表于Thu Jul 29 2010 15:41:02 GMT+0800 (China Standard Time)  举报回复

您好,从4月份做三维恢复到现在,你的这篇文章对我帮助很大。想知道你的摄像头在哪里买的,我在淘宝上找不到这样的摄像头。现在我是用两个单目做的,标定之后用久了还是会产生相对位移,所以非常想买一个像你这样的摄像头。期待你的答复,万分感谢

scyscyao 发表于Sun Aug 01 2010 10:52:38 GMT+0800 (China Standard Time)  举报回复

回复 angela575:http://item.taobao.com/item.htm?id=4271696156,你可以打个电话过去直接联系。关于标定久了之后产生相对位移的问题,这个摄像头也会存在的

beyondabcd789 发表于Thu Aug 05 2010 07:06:00 GMT+0800 (China Standard Time)  举报回复

你好:我在用VC2005,上用opencv2.0为什么我 选择Solution Explorer里的opencvhello项目,点击鼠标右键,选择Properties; 为项目的Debug配置增加依赖的库:cxcore200d.lib cv200d.lib highgui200d.lib 为项目的Release配置增加依赖的库:cxcore200.lib cv200.lib highgui200.lib 这样设置后,建立windows窗体应用程序、MFC应用程序后,运行程序就出错。 而建立win32控制台应用程序后,运行就可以呢?困惑我很长时间了,帮帮忙,谢谢啦 !!

scyscyao 发表于Fri Aug 06 2010 00:41:24 GMT+0800 (China Standard Time)  举报回复

回复 beyondabcd789:额 这个。。。最好到opencv中文网论坛问一下吧。。另外记得把编译的输出结果附一下~

angela575 发表于Fri Aug 06 2010 09:46:37 GMT+0800 (China Standard Time)  举报回复

你好,还想请教一个问题,用OpenCV和Matlab做标定后,XYZ轴向的单位分别是什么?现在求解出来的三维坐标感觉xy轴是z轴的一百分之一的样子,但是搞不清单位是什么

scyscyao 发表于Tue Aug 17 2010 14:16:17 GMT+0800 (China Standard Time)  举报回复

回复 angela575:http://blog.csdn.net/scyscyao/archive/2010/05/06/5562024.aspx里面的Q1可以看一下

beyondabcd789 发表于Mon Aug 09 2010 09:50:05 GMT+0800 (China Standard Time)  举报回复

你好,请教一下,我看上文章曾写了“关于cvFindStereoCorrespondenceBM这个函数的源代码,曾经做过比较详细的研究,”opencv的源码在什么目录里面,我找了半天也没找到,能不能告知一下,谢谢了!

scyscyao 发表于Tue Aug 17 2010 15:16:04 GMT+0800 (China Standard Time)  举报回复

回复 beyondabcd789:利用一下window的文本内容搜索功能找一下吧,一般在opencv目录的src下

beyondabcd789 发表于Tue Aug 17 2010 19:14:43 GMT+0800 (China Standard Time)  举报回复

回复 scyscyao: 我找了有src的目录,但没有cvFindStereoCorrespondenceBM源代码呀

scyscyao 发表于Fri Aug 20 2010 22:01:23 GMT+0800 (China Standard Time)  举报回复

回复 beyondabcd789:- -|||你用的是不是OpenCV1.0

beyondabcd789 发表于Thu Aug 26 2010 14:23:06 GMT+0800 (China Standard Time)  举报回复

回复 scyscyao:我现在1.0和2.0都按了

mailang2008 发表于Fri Aug 20 2010 16:19:46 GMT+0800 (China Standard Time)  举报回复

谢谢 谢谢

mailang2008 发表于Thu Aug 26 2010 16:05:52 GMT+0800 (China Standard Time)  举报回复

您好,我按您的方法在校正的时候遇到一个问题,提示cvStereoRectify函数Formats of input arguments do not match,不知道怎么解决?

yousuoqidai 发表于Tue Oct 12 2010 11:20:27 GMT+0800 (China Standard Time)  举报回复

为什么我这样标定之后fc=[600多,1200多],两个方向上的焦距不一样啊?我怀疑dx,dy输入有误,它们应该是什么值?是照片中一个方格的长宽,还是实际的方格长宽?

yousuoqidai 发表于Tue Oct 12 2010 11:22:11 GMT+0800 (China Standard Time)  举报回复

另外,用鼠标点击划定焦点范围时,需要按怎样的顺序?因为顺序不同,x轴、y轴方向是对调的。

beibpig 发表于Mon Oct 18 2010 17:40:35 GMT+0800 (China Standard Time)  举报回复

楼主你好,关于你的问题“摄像头参数本身来测量距离”,我可以为你解答,你可以加我qq 232290433,请注明CSDN 我也有一些问题需要向你请教,希望能qq详谈。

转自

http://blog.csdn.net/scyscyao/archive/2010/04/02/5443341.aspx

时间: 2024-07-29 10:09:01

OpenCV实现立体视觉的经验的相关文章

[收藏夹整理]OpenCV部分

OpenCV中文论坛 OpenCV论坛 opencv视频教程目录(初级) OpenCV 教程 Opencv感想和一些分享 tornadomeet 超牛的大神 [数字图像处理]C++读取.旋转和保存bmp图像文件编程实现 混合高斯模型算法 图像处理中的拉普拉斯算子 神经网络编程入门 bp神经网络及matlab实现 图像处理之图像快速旋转算法 BMP文件结构 各学科领域入门书籍推荐 基于双目视觉和三维重构的三维书写系统 图像分析:二值图像连通域标记 图像处理之计算二值连通区域的质心 数字图像处理的就

双目测距的基本原理(转http://blog.csdn.net/chenyusiyuan/article/details/5961769)

双目测距的基本原理 如上图所示,双目测距主要是利用了目标点在左右两幅视图上成像的横向坐标直接存在的差异(即视差)与目标点到成像平面的距离Z存在着反比例的关系:Z=fT/d.“@scyscyao :在OpenCV中,f的量纲是像素点,T的量纲由定标板棋盘格的实际尺寸和用户输入值确定,一般是以毫米为单位(当然为了精度提高也可以设置为0.1毫米量级),d=xl-xr的量纲也是像素点.因此分子分母约去,Z的量纲与T相同. ” 假设目标点在左视图中的坐标为(x,y),在左右视图上形成的视差为d,目标点在以

基于OpenCV立体视觉标定和校正

这几天学习双目视觉标定,分别使用了两种工具:OpenCV和Matlab.Matlab的效果非常稳定,但是一开始OpenCV的效果很糟糕,要不是出现中断就是标定出来的结果数值很大.经过了几天的不断调试和更改,终于把OpenCV的立体视觉标定和校正的程序写出来了.立体标定时计算空间上的两台摄像机几何关系的过程,立体校正则是对个体图像进行纠正,保证这些图像可以从平面对准的两幅图像获得.程序的框架如下: 1.读取左右相机图片序列 双目相机的图片序列放在Demon的路径下,左右相机的图像的名字分别存放在两

如何开始学习OpenCV?

OpenCV是什么,相信搞机器视觉的朋友都清楚.但是很多搞机器视觉的朋友却是对他又爱又恨.爱它因为它是免费的,如果能够好好掌握它,并运用到自己的机器视觉项目中,还是可以一定程度上降低项目成本.恨它是因为它不太好学习.原因有以下几个:1.国内有关OpenCV的中文著作太少了,就2本,而且还是1.1版本的,已经和现在最新版本2.4.3差别太大,就算是学习了,过渡到最新版也要花一定的时间和精力.2.直接学习较高版本,可是没有相应的教程可以参考.直接看英文版本的帮助文档吧,对于英文不好的朋友,难度很大.

OpenCV3编程入门_毛星云编著pdf高清版免费下载

下载地址:网盘下载 备用地址:网盘下载 内容提要OpenCV在计算机视觉领域扮演着重要的角色.作为一个基于开源发行的跨平台计算机视觉库,OpenCV实现了图像处理和计算机视觉方面的很多通用算法.<OpenCV3编程入门>以当前最新版本的OpenCV最常用最核心的组件模块为索引,深入浅出地介绍了OpenCV2和OpenCV3中的强大功能.性能,以及新特性.书本配套的OpenCV2和OpenCV3双版本的示例代码包中,含有总计两百多个详细注释的程序源代码与思路说明.读者可以按图索骥,按技术方向进行

OpenCV3编程入门_毛星云编著_电子工业出版下载 &#348453;

下载地址: http://www.gqylpy.com/di/17 <OpenCV3编程入门>毛星云编著PDF高清完整版-下载 内容提要 OpenCV在计算机视觉领域扮演着重要的角色.作为一个基于开源发行的跨平台计算机视觉库,OpenCV实现了图像处理和计算机视觉方面的很多通用算法.<OpenCV3编程入门>以当前最新版本的OpenCV最常用最核心的组件模块为索引,深入浅出地介绍了OpenCV2和OpenCV3中的强大功能.性能,以及新特性.书本配套的OpenCV2和OpenCV3

立体视觉-opencv中立体匹配相关代码

三种匹配算法比较 BM算法: 该算法代码: view plaincopy to clipboardprint? CvStereoBMState *BMState = cvCreateStereoBMState(); int SADWindowSize=15;    BMState->SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 9;   BMState->minDisparity = 0;   BMState->number

写一下自己一个星期玩树莓派的经验,如何安装系统,如何在树莓派中安装opencv,如何运行代码。

在树莓派上安装opencv最简单的方法是: sudo apt-get update sudo apt-get install libopencv-dev sudo apt-get install python-opencv 如果你还想了解更多,下面提供的那么多链接中你一定找到方法的,饭都送到你面前你不会吃,那么你活该饿着. 平时自己习惯用vim 所以在树莓派上安装了vim编辑器 安装命令  sudo apt-get  install  vim 就可以了. 好了,可以运行一个opencv的例子来检

OpenCV中Adaboost训练的经验总结

以OpenCV训练级联Adaboost为例进行说明 numPos: 12000 numNeg: 120000 numStages: 15 precalcValBufSize[Mb] : 1000 precalcIdxBufSize[Mb] : 800 stageType: BOOST featureType: HOG sampleWidth: 40 sampleHeight: 40 boostType: DAB minHitRate: 0.999 maxFalseAlarmRate: 0.7 w