机器视觉学习笔记(2)——基于DirectShow的多摄像头视频采集
2015-12-03 11:09
513 查看
机器视觉学习笔记(2)——基于DirectShow的多摄像头视频采集
标签: 机器视觉1.为什么使用DirectShow
笔者使用的是两个USB摄像头,单摄像头视频采集使用OpenCV的VideoCapture类没有问题,但是双摄像头就有问题,一个正常,另外一个采集不到信息,显示一片灰色。网上有种解决方法是逆序打开摄像头,结果两个窗口是可以采集到视频信息,但是竟然是同一个摄像头的视频信息,无奈的只能使用DirectShow采集多摄像头视频信息。
先看看什么是DirectShow:
DirectShow 是 DirectX 的组件之一, DirectX 软件开发包是 Microsoft 提供的一套在 Windows平台上开发高性能图形、声音、输入、输出和网络游戏的编程接口。这其中,DirectShow提供了应用程序从适当的硬件中捕捉和预览音、视频的能力。数据源包括: VCR、 Camera、 TV Tuner、 Microphone 或其他的数据源。应用程序可以立刻显示捕捉的数据(预览),或是保存到一个文件中。
摄像头采集信息常用的软件AMCap就是基于DirectShow SDK编写的。查阅一下官方文档,感觉好难的样子,难道要新学一门“快过时”的技术吗?幸好于仕琪老师写了一个
CCameraDS类,可直接返回IplImage,使用方便。
2.在VS2010中配置DirectShow并采集双目摄像头视频
下载DirectShow相关文件,我已经共享在百度云盘,点击下载。解压以后copy到D:\opencv里(放在这里为了管理方便)
在解决资源管理器中的项目名称处右键\属性\配置属性\VC++目录,引用目录中添加DirectShow的include文件夹,我添加的是
D:\opencv\DirectShow\Include
在引用目录下面有一个库目录,添加DirectShow的Lib文件夹,我添加的是
D:\opencv\DirectShow\Lib;
下载
CCameraDS类相关文件,点击下载。解压以后把CameraDS.h,CameraDS.cpp复制到已经配置好OpenCV库的工程中,并添加到工程中。在解决资源管理器中,头文件和源文件分别右键\添加\现有项,把
CCameraDS的头文件和源文件添加进去
main函数写入如下内容
#include "stdafx.h" #include <iostream> #include <cv.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <math.h> #include <highgui.h> #include "CameraDS.h" using namespace cv; int main() { int cam_count; //仅仅获取摄像头数目 cam_count = CCameraDS::CameraCount(); printf("There are %d cameras.\n", cam_count); }
编译,error,一个一个解决
fatal error C1083: 无法打开包括文件:”dxtrans.h”: No such file or directory
下载的DirectShow包里面没有该头文件,全盘搜索Windows也没有,后来发现使用该头文件的是
qedit.h,估计这个文件有问题。直接在网上重新down了一个
qedit.h(点击下载),替代了DirectShow自带的
qedit.h,路径如下
D:\opencv\DirectShow\Include\qedit.h。其它解决方法参考这里,也有效果
fatal error C1010:在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include “StdAfx.h””?
在
CameraDS.cpp最上面一行添加
#include "StdAfx.h"即可
运行,结果如下:
改写main函数,显示两个摄像头内容
int main() { int cam_count; //仅仅获取摄像头数目 cam_count = CCameraDS::CameraCount(); printf("There are %d cameras.\n", cam_count); //获取所有摄像头的名称 for(int i=0; i < cam_count; i++) { char camera_name[1024]; int retval = CCameraDS::CameraName(i, camera_name, sizeof(camera_name) ); if(retval >0) printf("Camera #%d's Name is '%s'.\n", i, camera_name); else printf("Can not get Camera #%d's name.\n", i); } if(cam_count==0) return -1; CCameraDS camera1, camera2; //手动打开摄像头 // if(! camera1.OpenCamera(0, true)) //弹出属性选择窗口 // { // fprintf(stderr, "Can not open camera1.\n"); // return -1; // } // if(! camera2.OpenCamera(1, true)) //弹出属性选择窗口 // { // fprintf(stderr, "Can not open camera2.\n"); // return -1; // } //自动打开摄像头 if(! camera1.OpenCamera(0, false, 320, 240)) //不弹出属性选择窗口,用代码制定图像宽和高 { fprintf(stderr, "Can not open camera1.\n"); return -1; } if(! camera2.OpenCamera(1, false, 320, 240))//不弹出属性选择窗口,用代码制定图像宽和高 { fprintf(stderr, "Can not open camera2.\n"); return -1; } while(1) { //获取一帧 IplImage *pFrame1 = camera1.QueryFrame(); IplImage *pFrame2 = camera2.QueryFrame(); //显示 cvShowImage("camera1", pFrame1); cvShowImage("camera2", pFrame2); if (cvWaitKey(20) == 'q') break; } camera1.CloseCamera(); //可不调用此函数,CCameraDS析构时会自动关闭摄像头 cvDestroyWindow("camera1"); camera2.CloseCamera(); cvDestroyWindow("camera2"); return 0; }
运行结果如下:
3.总结
想要顺利的读取出双摄像头的视频,必须明确地知道自己的摄像头输出的压缩格式。比如我的双目是用一根USB读取两个摄像头的数据,双目同时工作只支持yuy2的320*240分辨率,或者mjpg的1280*720和640*360分辨率CCameraDS默认是yuy2格式,如果出现运行时错误八成是格式不匹配,可以下载AMCap软件自己尝试自己摄像头支持的压缩格式和分辨率
如果想要手动设置输出格式和分辨率,将手动打开摄像头的代码注释取消,再注释自动打开摄像头的代码
如果自动打开摄像头想要设置为mjpg格式,在OpenCamera函数中设置分辨率的语句后加上
pmt->subtype = MEDIASUBTYPE_MJPG;
CCameraDSAPI查询,点击转到
相关文章推荐
- linux命令学习(5):rmdir命令(删除空目录)
- ubuntu 下使用aptitude 安装 pandas
- Linux——安装AndroidStudio错误
- git mv -f File file (git改名)
- 三国杀源码学习
- jarsigner命令详解
- CXF开发webservice(2):利用spring开发webservice接口
- gitlab傻瓜式安装
- Fragment和Activity之间的传参
- Android开发之如何保证Service不被杀掉(broadcast+system/app)
- iOS 类别中使用属性
- 移动端图片格式调研
- 转载:《TypeScript 中文入门教程》 4、类
- Java中public,private,final,static等概念的解读
- django-mvc
- JNDI 在 J2EE 中的角色
- Linux下文件共享(NFS)的简单应用
- 什么是线程安全
- android 实现类似个人中心的界面设计
- MongoDB shell插入数据