关于一些立体视觉的总结

这两天一直在研究有关立体视觉方面的东西,用的是OpenCV2.0+VS2005的组合。OpenCV不愧是计算机视觉的一个相当强大的库,有了它,很多复杂的算法都可以通过简单的几句函数来实现。当然,前提是你要会配置好函数需要调用的各种变量和矩阵。调用一些复杂的OpenCV函数需要准备的变量太多了,很多时候占了程序的一半或者更多。在这里,我感到只是简单的学会调用函数是不够的,我们还需要研究透彻其中的原理,不求把函数源程序看懂(这个实在太大了,估计只有大牛们才看得懂),但至少要把算法看懂,OpenCV的很多函数都是基于一些优秀论文中的算法,利用Google学术搜一下这些文章还是有所收获的。

讲了这么多废话,现在总结下这两天研究的一些成果。OpenCV2.0有一个函数cvStereoCalibrate就是用来标定两个摄像头相对位置,旋转角的。当然,要调用这个函数需要事先要准备很多东西。首先OpenCV标定摄像头用的是张正友的那篇论文里的方法,因此需要一个黑白相间的棋盘,这个只要自己打印一个,然后贴在平面上就可以使用了。我自己用的就是OpenCV安装目录下的一个棋盘,是7*7的大小的。OpenCV提供了cvFindChessboardCorners和这个函数来得到图片中棋盘的角点位置来用于下一步标定。实际应用中我发现棋盘最好是用长和宽不同的比较好,OpenCV的cvFindChessboardCorners函数有时会把x轴和y轴的方向搞错,从而导致后面的标定结果一团糟。所以后来我使用了一个matlab工具箱来标定摄像头。这里我参考了不少大牛们的研究成果,主要是参考了http://blog.csdn.net/scyscyao/archive/2010/04/02/5443341.aspx这个网址上的方法,具体使用就直接看这个网址里的东西好了。在利用matlab工具箱把两个摄像头标定好后,可以得到两个摄像头的内参数,畸变参数,两个摄像头之间的平移向量和旋转向量,结果如图所示。

matlab工具箱标定得到的结果

这里的Foucal Length是摄像头的x,y方向的焦距,即学习OpenCV书上第11章值的fx和fy;Principal point指的是摄像头的偏移,即cx和cy;Skew这里没有用到;Distortion指的就是摄像头的径向和切向畸变,即k1,k2,p1,p2,k3这5个参数,顺序也是按照OpenCV描述的顺序记录的。这里的fx fy cx xy四个参数就构成了cvStereoRectify这个函数前面两个参数(当然,是分左摄像头和右摄像头的),具体结构如下图。

k1,k2,p1,p2,k3这5个参数构成了cvStereoRectify这个函数的第三个和第四个参数。这里指出一点的是利用matlab工具箱标定得到的是一个om向量,这个是旋转矩阵通过Rodrigues变换之后得出的结果,因此需要首先将这个向量用cvRodrigues转换成旋转矩阵。而Translation vertor即右摄像头相对于左摄像头的位移矩阵,这个也只要直接拷贝到OpenCV的xml文件里去就可以了。这样,就可以调用cvStereoRectify这个函数的所有需要准备的参数都有了,接下来利用这个函数和cvInitUndistortRectifyMap和cvRemap着三个函数来得到将左右两幅图进行极线上对准了。

接下来,只需要利用cvFindStereoCorrespondenceBM这个函数就可以得到深度信息了。这里需要注意的是这个函数除了需要两幅极线对准的左右图像外,还需要一个CvStereoBMState的结构体作为预处理滤波参数。具体的配置可以参考http://blog.csdn.net/chenyusiyuan/archive/2010/10/26/5967291.aspx这个网址上的内容。在调用cvFindStereoCorrespondenceBM后,将深度信息Normalize成0~255后就可以显示了,这里我也利用了chenyusiyuan这位大牛的一个利用伪彩色图像来显示深度信息的函数。最后得到的深度图片如图所示。

左右两幅图片极线对准的结果

伪彩色显示的深度信息

这里可以看到,还是有不少噪点和无匹配的地方的,但是总体看来,还是基本上恢复出了障碍物的深度信息。这里我用的CvStereoBMState的参数是

BMState->preFilterSize=13;   
BMState->preFilterCap=13;   
BMState->SADWindowSize=19;   
BMState->minDisparity=-32;   
BMState->numberOfDisparities=128;   
BMState->textureThreshold=10;   
BMState->uniquenessRatio=20;   
BMState->speckleWindowSize=13; 

总结一下,OpenCV自带的标定函数虽然比较方便调用,但是智能性较差,容易出现角点寻找错误的情况。而利用matlab工具箱虽然麻烦点,但是它的可以由人工指定一些查找的位置,因此标定成功率较高,利用它标定后的参数在接下来的深度信息恢复中容易得到较为满意的结果。因此,我还是比较喜欢利用matlab工具箱来对两个摄像头进行标定。同时,matlab工具箱还有另外一些其他的功能,因此灵活性也比较好。

先总结到这里,有新的想法再补充。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值