目录
1 说明
我之前写过一篇文章《完全基于opencv的双目景深与测距的实现》:http://blog.csdn.net/hysteric314/article/details/50456570
但是之前文章中的双目视觉代码并不完善,所以就想再找找看有没有更好的实现方法。
然后就在youtube上找到一个视频:https://www.youtube.com/watch?v=PR9tlFay0U8
YOUKU搬运地址:http://v.youku.com/v_show/id_XMTU2Mzk0NjU3Ng==.html
视频中的原代码地址:http://download.csdn.net/detail/hysteric314/9514886
本文提到的代码(修改后的代码)下载地址:http://download.csdn.net/detail/hysteric314/9523746
我修改了部分代码并运行了一下,代码中实现标定过程实现的很简单,很容易上手,测距功能也可以使用,而且最终测距的效果也很准确,比之前的代码好太多了。
这个文章我就写一下修改后代码的具体实现和运行过程中出现的一些问题。
2 之前文章中的双目测距代码
之前的代码:http://blog.csdn.net/hysteric314/article/details/50456570
之前的代码可以实现双目测距的一些功能,不过它并不完善
这个代码有一下几个问题:
1,修改视差图效果的参数只能在代码里面修改,不能直接、直观的看到修改后的效果
2,没有标定的过程,只能从外部读取calib_paras.xml这个参数文件,标定参数的生成还需要其他的程序,很麻烦
3,双目测距的效果不是很理想,得到的距离信息不准确
实现的效果:
运行环境:
1.windows10
2.opencv 2.4.9
3.visual studio 2013
4.两颗微软HD-3000摄像头
5.i7、集显、16g、sata
3 效果更好的双目视觉代码
原来的代码完全就是按照这篇文章:
http://scholar.lib.vt.edu/theses/available/etd-12232009-222118/unrestricted/Short_NJ_T_2009.pdf
按照这篇文章中的代码改过来的,同时这篇文章详细的介绍了所有有关双目视觉的东西,有做毕设的同学可以参考这篇文章。
我修改了原来的代码:
原代码中有一个功能是检测物体,能在物体周围画一个长方形的框,并在这个框中标出物体的距离信息。
但是,这个功能是用cvblobslib这个opencv扩展库实现的,这个扩展库我按照教程(下面链接)安装后:
http://dsynflo.blogspot.com/2010/02/cvblobskib-with-opencv-installation.html,
在vs2013中也各种设置好,但是就是运行不了:源代码与cvblobs有关的部分代码各种报错,遂屏蔽相关代码,代码马上就可以运行。
所以本文的代码是我修改后的代码,好处就是,首先它就不需要装那反人类的扩展库,如果你opencv2.4.9配置好之后,可以直接运行,方便。再它依然可以实现所有主要的功能,包括标定功能以及测量深度的功能。
如果你就是想用cvblobslib这个扩展库,就是想实现那个对物体画框的功能,请自行尝试原代码。
如果你原代码配置成功了,希望你能在文章下评论你的实现过程以及配置的方法,多谢!
修改后代码的实现效果:
运行环境:
1.windows10
2.opencv 2.4.9
3.visual studio 2013
4.两颗微软HD-3000摄像头
5.i7、集显、16g、sata
本文提到的代码(修改后的代码)下载地址:
http://download.csdn.net/detail/hysteric314/9523746
4 效果更好的双目视觉代码的实现
4.1 标定过程
在进行测距之前,首先肯定是需要对摄像头进行标定,这样才能得到两个摄像头之前的标定信息,那么如何标定呢?
方法:
1,首次把代码中的“stdafx.h”文件中的代码:”#define CALIBRATION 0”改成 “#define CALIBRATION 1”,这就表示进行标定程序,在标定之后,你就可以在工程目录下的”CalibFile” 文件夹中得到标定信息的文件。
2,在标定过程中,演示视频中使用的是10*7的棋牌格,共摄录40帧来计算摄像头的各种参数,如果你想使用其他格式的棋盘格,可以在 “StereoFunctions.cpp”文件中修改相应参数(如:int nx=10, ny=7, frame = 0, n_boards =40, N;)。
3,拿着棋盘格在摄像头前移动,如果一切正常,效果应该如下图所示。
4,如果标定效果还不错,你在下次执行之前可以把代码”#define CALIBRATION ” 改成0,表示以后就不需要再标定,每次运行程序都是直接使用上一次的标定信息。
5,你还需要把”#define ANALYSIS_MODE 1”这行代码放到stdafx.h中。
标定过程:
4.2 测距过程
标定结束后就可以进行测距的过程了
1,rectified窗口:首先左右俩摄像头需要根据标定信息进行矫正,rectified窗口中显示的就是在矫正操作处理之后的图像。
2,disparity窗口:显示的是视差图。
3,stereo controls窗口:这个窗口是用来设置视差图各种参数,你可以通过调整控制窗口中各个参数的滑块,从而来得到更好的视差图。
4,要想得到距离信息,先需要在stereo controls中设置save dist参数为1,表示保存当前帧的深度信息,再用鼠标点击视差图的某一个位置,这时在另一个cmd窗口就会显示相应位置的深度信息,单位是厘米。
5,在目录下的”distance“文件夹中,有计算距离信息的matlab代码,你可以尝试运行一下。
6,我运行测距的时候俩摄像头之间的距离是6cm,如果你是其他品牌的摄像头,可以通过调整俩摄像头之间的距离,来使视差图达到最好的效果。
双目测距的设备:
5 一些问题以及解决方法
Q 视差图效果不好怎么办?
A:
1,有可能你左右摄像头插反了。。
2,标定的结果不好,视差图肯定也不会好,再重新标定
3,标定没有问题,但是标定后你俩摄像头位置有变化
距离信息的3d点云是根据视差图算出来的,视差图都不准得到的距离信息也肯定不准,不过我觉得大多数视差图不准、效果不好的情况都是因为你标定那一步没弄好,所以就反复标定一下,什么时候视差图效果最好,你就把这次的标定信息保存起来,以后就一直使用这个标定信息。
Q 在测距时,点击视差图靠右边的位置会报错,或出现”opencv error :assertion failed dims=2&&data&&()i0等错误信息
A:别点右侧边的位置,原因我也不清楚,有能解决的大神请评论方法,多谢!
6 要说的
最近在弄神经网络、图像识别有关的东西,之后有时间可能在tk1上实现一下这个代码,到时候会在博客里贴出代码。
本文如果有错误的地方请评论指正,多谢!