【opencv学习】使用opencv与两个摄像头实现双目标定与测距

目录

  • 目录
  • 说明
  • 之前文章中的双目测距代码
  • 效果更好的双目视觉代码
  • 效果更好的双目视觉代码的实现
    • 1 标定过程
    • 2 测距过程
  • 一些问题以及解决方法
  • 要说的

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

视频中的原代码地址:https://www.dropbox.com/s/hiiq2unwttutbd8/Source%20code.rar

我修改了部分代码并运行了一下,代码中实现标定过程实现的很简单,很容易上手,测距功能也可以使用,而且最终测距的效果也很准确,比之前的代码好太多了。

这个文章我就写一下修改后代码的具体实现和运行过程中出现的一些问题。

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/9514872

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上实现一下这个代码,到时候会在博客里贴出代码。

本文如果有错误的地方请评论指正,多谢!

时间: 2024-10-20 09:53:13

【opencv学习】使用opencv与两个摄像头实现双目标定与测距的相关文章

OpenCV学习:OpenCV源码编译(vc9)

安装后的OpenCV程序下的build文件夹中,只找到了vc10.vc11和vc12三种编译版本的dll和lib文件,需要VS2010及以上的IDE版本,而没有我们常用的VS2008版本. 于是,需要的小伙伴们可以自己动手,丰衣足食! 1). 安装CMake cmake-2.8.8-win32-x86.exe (http://www.cmake.org/cmake/resources/software.html) 百度云盘:http://pan.baidu.com/s/1dEYbx77  密码:

OpenCV学习3-----利用鼠标、键盘回调函数实现标定人体关节点

最近做实验,需要一些人体关节点的ground truth,需要自己手动标定,于是尝试使用OpenCV的鼠标键盘回调函数实现. 期间遇到不少问题,记录一下. 首先就是鼠标回调函数注册, namedWindow("calibration"); setMouseCallback("calibration", onMouse, &photo); 其中onMouse为处理鼠标事件的函数.里面需要用的一个索引selectIndex来标记当前鼠标选择的关节点是哪一个.然后

OpenCV show two cameras 同时显示两个摄像头

用OpenCV同时显示两个摄像头的内容的代码如下: #include <iostream> #include <stdio.h> #include <tchar.h> #include <cv.h> #include <cvaux.h> #include <highgui.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { CvCapture* cam0 = c

OpenCV&amp;Qt学习之四——OpenCV 实现人脸检测与相关知识整理

开发配置 OpenCV的例程中已经带有了人脸检测的例程,位置在:OpenCV\samples\facedetect.cpp文件,OpenCV的安装与这个例子的测试可以参考我之前的博文Linux 下编译安装OpenCV. 网上能够找到关于OpenCV人脸检测的例子也比较多,大多也都是基于这个例程来更改,只是多数使用的是OpenCV 1.0的版本,而OpenCV2.0以后由于模块结构的更改,很多人并没有将例程运行起来.如果是新版的OpenCV跑旧的例程,编译运行出错的话,需要确保: #include

Opencv学习笔记(六)SURF学习笔记

原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/7392345 本人挺菜的,肯定有非常多错误纰漏之处 ,希望大家不吝指正. 看了harris角点检測之后,開始研究SURF角点检測,发现挺复杂的,一时也仅仅了解了大概,把了解的东西总结下,以便下次深入学习. SURF角点检測算法是对SIFT的一种改进,主要体如今速度上,效率更高.它和SIFT的主要差别是图像多尺度空间的构建方法不同. 在计算视觉领域,尺度空间被象征性的表述

OpenCV学习笔记[3]Java Demo人脸识别

OpenCV学习笔记:Java Demo人脸识别 [简介] 我记得在很久以前,CSDN似乎搞过一个活动,给一个橘子林的照片,让程序计算相片里有多少个橘子.之所以对这个问题记忆犹新,是因为在专业学习初期,相比于排序遍历搜索等简单算法而言,"图像识别"算法一直是难以理解的东西,而我偏偏又痴迷于此,不管自己多么无知,对于令我迷惑的问题总是充满着解决的渴望. 通过对OpenCV的初步了解,我发现图像识别的很多问题都可以用它方便的解决,本次将是一个来自官方的人脸识别的实例,我们提供图像,使用内置

OpenCV学习(20) grabcut分割算法

http://www.cnblogs.com/mikewolf2002/p/3330390.html OpenCV学习(20) grabcut分割算法 在OpenCV中,实现了grabcut分割算法,该算法可以方便的分割出前景图像,操作简单,而且分割的效果很好.算法的原理参见papaer:“GrabCut” — Interactive Foreground Extraction using Iterated Graph Cuts 比如下面的一副图,我们只要选定一个四边形框,把框中的图像作为gra

OpenCV 学习笔记(模板匹配)

OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够高时,就认为找到了我们的目标. 在 OpenCV 中,提供了相应的函数完成这个操作. matchTemplate 函数:在模板和输入图像之间寻找匹配,获得匹配结果图像 minMaxLoc 函数:在给定的矩阵中寻找最大和最小值,并给出它们的位置 在具体介绍这两个函数之前呢,我们还要介绍一个概念,就是如何来评价两

OpenCV 学习(像素操作 Manipuating the Pixels)

OpenCV 学习(像素操作 Manipuating the Pixels) OpenCV 虽然提供了许多类型的图像处理函数,可以对图像进行各种常见的处理,但是总会有些操作时没有的,这时我们就需要自己来操纵像素,实现我们需要的功能.今天就来讲讲 OpenCV 进行像素级操作的几种方法,并做个比较. 在 OpenCV 中,图像用矩阵来表示,对应的数据类型为 cv::Mat . cv::Mat 功能很强大,矩阵的元素可以为字节.字.浮点数.数组等多种形式.对于灰度图像,每个像素用一个 8 bit 字