目标:最近在做双目测距的东西,其中遇到获取摄像头内外参数的问题,就学习了相关的一些东西,做了下简单的记录,本文的目标是获取任意一款摄像头的-内外参数
开发环境:opencv2.4.9+Visual Studio 2013、opencv3.0.0-rc1+Ubuntu 14.04
本文在windows下和linux下都进行的配置,但是发现linux下14.04这个版本的v4l2好像有问题,提示不能对摄像头的分辨率进行操作,我的摄像头是微软的一款普通usb摄像头,型号是VX-800,现在还没时间去解决这个问题,有人也遇到希望多交流。
一、开发环境的配置
主要是PC环境变量的设置和vs2013库的配置。
博客上拥有丰富的资源,我阅读了浅墨大神的【【OpenCV】入门教程】,第一篇便是讲解开发环境的配置,她的这部分博客非常有利于初学opencv的童鞋。附链接-点击打开链接
另介绍一篇ubuntu下的配置,附链接-点击打开链接
二、标定
关于双目测距和摄像头标定我找了两篇写的比较好的博客。附链接-点击打开链接、点击打开链接
标定一般有两种方式去标定,一个是实时的从摄像机获取拍摄到的棋盘进行标定,一个是已经获得了一些棋盘的图片来标定。
首先找到opencv自带的一些demo,我的是下面的目录 E:\Opencv\opencv\sources\samples\cpp,找到这两个文件calibration.cpp和calibration_artificial.cpp。
calibration.cpp 是通过用户输入可选参数进行摄像机标定的程序。
calibration_artificial.cpp 是程序模拟模拟摄像机标定的过程,即程序创建棋盘然后自主标定。

本在在windows和linux下都进行了测试,(1)为linux下的测试情况,(2)是在windows下进行的。

(1)、用已获得的棋盘图片进行标定--calibration.cpp

在运行calibration.cpp之前应先通过OpenCV自带的imagelist_creator.cpp 产生一个xml或者yaml格式的图像列表。

1、首先利用imagelist_creator.cpp输入命令imagelist.yaml *.jpg生产imagelist.yaml文件,形成的yaml文件如下:


2、在calibratetion.cpp工程下,输入如下的命令行参数:./cpp-example-calibration -w 6 -h 7 imagelist.yaml

标定完成后,会输出一个输出的out_camera_data文件:


(2)、利用实时流进行相机标定

首先在windows中vs下建立一个工程,加入calibration_artificial.cpp,编译,生成方案。然后调整好摄像头,按g开始捕捉,旋转,平移棋盘获取不同的视场,输出结果标定结果与上图应保持一致。

三、如何在window下打开摄像头。

范例:

<span style="font-size:12px;">#include <cv.h>    
#include <cxcore.h>    
#include <highgui.h>    
     
int main( int argc, char** argv )    
{    
  IplImage* pFrame = NULL;  //声明IplImage指针  </span>  
  
  CvCapture* pCapture = cvCreateCameraCapture(1); //获取摄像头  </span><span style="font-family: Arial, Helvetica, sans-serif;"> </span>  
     
  cvNamedWindow("video", 1);  //创建窗口  </span>  
     
  //显示    
  while(1)    
  {    
      pFrame=cvQueryFrame( pCapture );    
      if(!pFrame)break;    
      cvShowImage("video",pFrame);    
      char c=cvWaitKey(33);    
      if(c==27)break;    
  }    
  cvReleaseCapture(&pCapture);    
  cvDestroyWindow("video");    
}     </span>
说明:

(1)、cvCreateCameraCapture
初始化从摄像头中获取视频

CvCapture* cvCreateCameraCapture( int index );
index
要使用的摄像头索引。如果只有一个摄像头或者用哪个摄像头也无所谓,那使用参数-1应该便可以。
函数cvCreateCameraCapture给从摄像头的视频流分配和初始化CvCapture结构。目前在Windows下可使用两种接口:Video for Windows(VFW)和Matrox Imaging Library(MIL); Linux下也有两种接口:V4L和FireWire(IEEE1394)。

释放这个结构,使用函数cvReleaseCapture。 

(2)、CvCapture
视频获取结构

typedef struct CvCapture CvCapture;
结构CvCapture 没有公共接口,它只能被用来作为视频获取函数的一个参数。   

(3)、cvQueryFrame
从摄像头或者文件中抓取并返回一帧

IplImage* cvQueryFrame( CvCapture* capture );
capture
视频获取结构。
函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。返回的图像不可以被用户释放或者修改。
(4)、cvShowImage
在指定窗口中显示图像

void cvShowImage( const char* name, const CvArr* image );
name
窗口的名字。
image
被显示的图像。
函数cvShowImage 在指定窗口中显示图像。如果窗口创建的时候被设定标志CV_WINDOW_AUTOSIZE,那么图像将以原始尺寸显示;否则,图像将被伸缩以适合窗口大小。

四、总结

之所以利用实时流进行相机标定是在windows下完成是因为,这个版本的ubuntu中V4L2好像有问题,提示一直说无法对摄像头的分辨率进行ioctl,我不知道是否是因为在linux下我的摄像头驱动的问题,或者是因为什么原因,而在windows下是完全正常的,需要说明的是我的摄像头是微软的VX-800。最近一直在忙没时间去深入去找原因,有相同问题可以一起研究。

Logo

更多推荐