声明:欢迎任何人和组织转载本blog中文章,但必须标记文章原始链接和作者信息。

本文链接:http://blog.csdn.net/li_007/archive/2009/12/17/5024675.aspx

开拓进取的小乌龟------->CSDN点滴点点滴滴Blog

最近因为项目需要,需要在ccv中使用多摄像头。在官方的ccv 1.3中是直接支持两个Sony PlayStation 3 Eye Camera的,但是经过测试发现PS 3摄像头达不到我们要求,所以只有还是采用以前一直用的PGR Firefly@MV摄像头,自己来改写代码支持多个。

现在将代码贴出来,大家互相学习交流讨论,希望大虾不吝赐教。

// // PGRFireFlyMultiCamera.h // // // Written by Leezhm, 15th Dec, 2009 // Contact : Leezhm@126.com // Last Modified by Leezhm, 16th Dec, 2009 // Copyright(c) Leezhm All rights reserved // #ifndef __h_PGRFireflyMultiCamera__ #define __h_PGRFireflyMultiCamera__ #include "../PGRSDK/include/PGRFlyCapture.h" #include "../PGRSDK/include/PGRFlyCapturePlus.h" #include <iostream> using std::cout; using std::endl; const unsigned int MAX_CAMERA_COUNT = 2; class PGRFireflyMultiCamera { private: static unsigned int camCount; int camHeight; int camWidth; FlyCaptureContext context[MAX_CAMERA_COUNT]; public: FlyCaptureImagePlus * fcImagePlus; public: PGRFireflyMultiCamera(); ~PGRFireflyMultiCamera(); public: static unsigned int getCameraCount(); inline void showErrorMessage(FlyCaptureError & err, char * pFun) { if (FLYCAPTURE_OK != err) { cout<<"Error : "<<*pFun<<" --> "<<flycaptureErrorToString(err)<<endl; } } public: void initFireflyCamera(int width,int height, int framerate); int getCamWidth(); int getCamHeight(); void listDevices(); void grabFrame(); }; #endif // __h_PGRFireflyMultiCamera__

下面是CPP文件

// // PGRFireFlyMultiCamera.cpp // // // Written by Leezhm, 15th Dec, 2009 // Contact : Leezhm@126.com // Last Modified by Leezhm, 16th Dec, 2009 // Copyright(c) Leezhm All rights reserved // #include "PGRFireFlyMultiCamera.h" unsigned int PGRFireflyMultiCamera::camCount = MAX_CAMERA_COUNT; PGRFireflyMultiCamera::PGRFireflyMultiCamera() { fcImagePlus = NULL; } PGRFireflyMultiCamera::~PGRFireflyMultiCamera() { FlyCaptureError err; unsigned int uiCamera = 0; if (NULL != fcImagePlus->image.pData) { delete [] fcImagePlus->image.pData; } if (NULL != fcImagePlus) { delete fcImagePlus; } // // Stop all cameras from grabbing and destroy their contexts. // for( uiCamera = 0; uiCamera < camCount; uiCamera++ ) { err = ::flycaptureStop(context[uiCamera] ); showErrorMessage(err, "flycaptureStop()"); err = ::flycaptureDestroyContext(context[uiCamera]); showErrorMessage(err, "flycaptureBusEnumerateCameras()"); } } void PGRFireflyMultiCamera::listDevices() { FlyCaptureError err; FlyCaptureInfoEx info[MAX_CAMERA_COUNT]; // // Enumerate the bus and get the count of camera // err = ::flycaptureBusEnumerateCamerasEx(info, &camCount); if (FLYCAPTURE_OK != err) { cout<<"PGRFireflyMultiCamera::flycaptureBusEnumerateCamerasEx() : " <<flycaptureErrorToString(err)<<endl; } else { for( unsigned int uiBusIndex = 0; uiBusIndex < camCount; uiBusIndex++ ) { FlyCaptureInfoEx* pinfo = &info[uiBusIndex]; cout<<"Index "<<uiBusIndex<<": "<<pinfo->pszModelName <<", SerialNumber: "<<pinfo->SerialNumber<<endl; } cout<<"end of listing FFMV/n/n"; } } unsigned int PGRFireflyMultiCamera::getCameraCount() { if (0 == camCount) { ::flycaptureBusCameraCount(&camCount); } return camCount; } void PGRFireflyMultiCamera::initFireflyCamera(int width,int height, int framerate) { FlyCaptureError err; unsigned int uiCamera = 0; // // Create a context for and initialize every camera on the bus. // for( uiCamera = 0; uiCamera < camCount; uiCamera++ ) { err = ::flycaptureCreateContext(&context[uiCamera]); showErrorMessage(err, "flycaptureCreateContext()"); cout<<"Initializing camera "<<uiCamera<<endl; err = ::flycaptureInitialize(context[uiCamera], uiCamera); showErrorMessage(err, "flycaptureInitializePlus()"); } FlyCaptureFrameRate setFrameRate; if (60 == framerate) { setFrameRate = FLYCAPTURE_FRAMERATE_60; } else if (30 == framerate) { setFrameRate = FLYCAPTURE_FRAMERATE_30; } else if (15 == framerate) { setFrameRate = FLYCAPTURE_FRAMERATE_15; } // // Start all of the cameras grabbing // for( uiCamera = 0; uiCamera < camCount; uiCamera++ ) { cout<<"Starting camera./n/n"; err = ::flycaptureStartLockNext(context[uiCamera], FLYCAPTURE_VIDEOMODE_640x480Y8, setFrameRate); showErrorMessage(err, "flycaptureStart()"); } // // Having started all of the cameras synchronize all of their buffers. // Please note that cameras running at the same frame rate on the same // bus will automatically synchronize to each other. This call is for // purposes of synchronizing the buffers. // err = ::flycaptureSyncForLockNext(context, camCount); showErrorMessage(err, "flycaptureSyncForLockNext()"); if (2 == camCount) { if (NULL == fcImagePlus) { fcImagePlus = new FlyCaptureImagePlus(); } fcImagePlus->image.iCols = camCount * width; fcImagePlus->image.iRows = height; if (NULL == fcImagePlus->image.pData) { fcImagePlus->image.pData = new unsigned char[fcImagePlus->image.iRows * fcImagePlus->image.iCols]; memset(fcImagePlus->image.pData, 0, fcImagePlus->image.iRows * fcImagePlus->image.iCols); } } else { cout<<"there are more than 2 cameras!/n"; getchar(); return ; } } int PGRFireflyMultiCamera::getCamWidth() { camWidth = fcImagePlus->image.iCols; return camWidth; } int PGRFireflyMultiCamera::getCamHeight() { camHeight = fcImagePlus->image.iRows; return camHeight; } void PGRFireflyMultiCamera::grabFrame() { unsigned int uiCamera = 0; FlyCaptureError err; FlyCaptureImagePlus tmpImage[MAX_CAMERA_COUNT]; // // Lock images. // for (uiCamera = 0; uiCamera < camCount; uiCamera ++) { err = flycaptureLockNext(context[uiCamera], &tmpImage[uiCamera]); if( err != FLYCAPTURE_OK ) { cout<<"flycaptureLockNext(): "<<flycaptureErrorToString(err)<<endl; return ; } } for (int row = 0; row < camHeight; row ++) { memcpy((fcImagePlus->image.pData + (row * camWidth)), (tmpImage[0].image.pData + (row * camWidth / 2)), camWidth / 2); memcpy((fcImagePlus->image.pData + (row * camWidth) + camWidth / 2), (tmpImage[1].image.pData + (row * camWidth / 2)), camWidth / 2); } // // Unlock all of the images effectively handing them back to the buffer pool. // for( uiCamera = 0; uiCamera < camCount; uiCamera++ ) { err = ::flycaptureUnlock(context[uiCamera], tmpImage[uiCamera].uiBufferIndex ); if( err != FLYCAPTURE_OK ) { cout<<"flycaptureUnlock(): "<<flycaptureErrorToString(err)<<endl; return ; } } }

以上是整个class的实现。下面是我的测试工程代码

// PGRMultiCameraTest.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "cv.h" #include "highgui.h" #include "./MyClass/ofxffmv.h" #include "./MyClass/PGRFireFlyMultiCamera.h" PGRFireflyMultiCamera * camera = new PGRFireflyMultiCamera(); const char * pTitle = "Capture Video From PGR Camera"; int cHeight = 0; int cWidth = 0; bool running = true; DWORD WINAPI Capture(LPVOID) { IplImage * pImage = cvCreateImage(cvSize(cWidth, cHeight), IPL_DEPTH_8U, 1); while(running) { pImage->imageData = (char *)(((camera->fcImagePlus)->image).pData); camera->grabFrame(); cvShowImage(pTitle, pImage); } cvReleaseImage(&pImage); return 0; } int _tmain(int argc, _TCHAR* argv[]) { camera->listDevices(); camera->initFireflyCamera(640, 480, 30); cHeight = camera->getCamHeight(); cWidth = camera->getCamWidth(); cvNamedWindow(pTitle, CV_WINDOW_AUTOSIZE); HANDLE handle = CreateThread(NULL, 0, Capture, NULL, 0, 0); while(running) { int key = cvWaitKey(0); switch(key) { case 0x1b: { printf("Exiting.../n"); // Stop the capture thread running = false; // Wait for thread to exit WaitForSingleObject(handle, 3000); printf("Thread exited/n"); delete camera; camera = NULL; break; } } } if (NULL != camera) { delete camera; camera = NULL; } return 0; }

下面是测试截图

欢迎有兴趣的朋友来测试修改讨论。我放到ccv中去测试,发现视频有点延时,估计是因为线程问题。我会继续将grabFrame创建成独立线程后再在ccv中测试,然后结果和大家分享。

BTW:现在已经有了PGR Firefly SDK 2.0了,我看了它自带的例子,发现代码简洁了很多,但是我在测试多摄像头的时候发现Camera::StartSyncCapture(...)这个函数在执行时死掉,程序不能继续运行也不报错。不知道为什么,大家可以试试,等有了结果,我会将上面代码更新到基于SDK 2.0的。

CCV使用两个PGR Firefly摄像头源码相关推荐

  1. 读取xml文件转成ListT对象的两种方法(附源码)

    读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最近项目中用到的读取xml文件并且转成List<T>对象的方法, ...

  2. 利用多线程爬虫搭建代理ip池的两种方法(含源码)

    搭建爬虫代理ip池的两种方法(含源码) 前言 一.ip池是什么? 二.爬取原理 三.使用步骤 方法一 爬取网站https://www.kuaidaili.com/ 验证 存取到mysql 方法二 爬取 ...

  3. 分享两款智慧物业系统源码,前后端分离,前端VUE,Uni-app框架

    分享两款智慧物业管理系统源码,源码免费分享,需要源码学习参考的小伙伴可以私信我. ▶▶▶1:Java智慧物业管理系统源码(App+业主端微信小程序+物业端H5) 智慧物业介绍: 一.技术架构 基于Sp ...

  4. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | 加固厂商在 ART 下使用的两种类加载器 | InMemoryDexClassLoader 源码 )

    文章目录 一.加固厂商在 ART 下使用的两种类加载器 ( InMemoryDexClassLoader | DexClassLoader ) 二.InMemoryDexClassLoader 源码分 ...

  5. linux usb摄像头 源码,Linux USB摄像头驱动实现源码分析

    Spac5xx的实现是按照标准的USB VIDEO设备的驱动框架编写(其具体的驱动框架可参照/usr/src/linux/drivers/usb/usbvideo.c文件),整个源程序由四个主体部分组 ...

  6. linux 下的两种软件安装方式 —— 源码(编译、安装),编译好的二进制(直接安装)

    我们以 GPG(加密工具)为例来说明两种安装方式的区别: 源码(Source code releases,名称中则会含有src等说明信息,tarball:source),先编译再安装 GPU 的源码地 ...

  7. 自己收藏的两款夹娃娃PHP源码

    微信红色抓娃娃三级分销源码加第三方支付 http://www.sucaihuo.com/php/2027.html 账号123,密码123 无需公众号(想要在微信内自动登录,必须绑定认证服务号),支付 ...

  8. C#实现的两个淘宝插件源码

    淘宝账户看门狗C#源码: http://download.csdn.net/source/1969369 淘宝账户看门狗C#源码:http://download.csdn.net/source/196 ...

  9. 【013】基于Vue的酒店客房管理系统(含管理员、普通用户两种身份(附源码数据库、课设报告)

    这里写目录标题 一.系统详细介绍 二.系统部分设计思路 三.项目获取 一.系统详细介绍 前言: 这次带来的是基于Nodejs+Vue+Mysql的酒店客房管理系统,含非常非常详细的课设报告,觉得物超所 ...

最新文章

  1. 【转】微信扫描二维码登录网页是什么原理?
  2. centos7 php安装
  3. exp ORA-01455: converting column overflows integer datatype
  4. Spire.Doc系列教程:C# 根据 Word 的标题样式获取文字
  5. Windows操作系统启动介绍(二)
  6. JavaScript 获取元素及事件
  7. 雾山五行专题高清壁纸,绝美动漫场景
  8. SVN 的安装与配置
  9. wt在matlab中什么意思,new wt.是什么意思
  10. 5工程添加emwin库_手把手教你打造专属自己的远程私有库——上
  11. 目前最快的 Java 框架居然是它?真的最快,秒射~
  12. VC利用GDI+显示透明的PNG图片
  13. 2022下半年数学建模竞赛汇总(比赛时间、出成绩时间、难易程度、含金量、竞赛官网)
  14. arcgis for android 调用公网天地图注记重影问题
  15. 经常使用的几种OCR文档扫描工具|无水印|避免智商税
  16. 有关十二个“一”的文艺创作-拓展版
  17. 股票估值法研究报告_论述股票的估值方法
  18. 状态机的编写(使用C++)
  19. 著名球星罗纳尔迪尼奥担任巴西旅游大使
  20. 【C语言】打印一个爱心

热门文章

  1. 大数据哪个省才是高考地狱_是一名数据科学家,确实是地狱附近最性感的工作...
  2. 斯密特正交化与QR分解
  3. M5A78L-M LX3 PLUS 触发不显
  4. 谷歌浏览器图片无法显示,默认https加载
  5. idea报错Shorten the command line via JAR manifest or via a classpath file and rerun.
  6. 重大计算机学院院标,计算机学院召开2021年国家自然科学基金申报动员会
  7. 2019-1-29-win10-uwp-使用-Microsoft.Graph-发送邮件
  8. html+css瞬间黑暗模式
  9. mysql数据库的两种备份方式(mysqldump,XBK)超详细
  10. 四极管 整理wince挂起和唤醒(suspend/wakeup)以及实现关机功能文章