因项目需要采集2个摄像头的数据进行双目检测,一开始采用以下代码来测试:
#include "stdafx.h" #include <cv.h> #include <cxcore.h> #include <highgui.h> int main(int argc, _TCHAR* argv[]) { CvCapture* capture1 = cvCreateCameraCapture( 0 ); CvCapture* capture2 = cvCreateCameraCapture( 1 ); double w = 320, h = 240; cvSetCaptureProperty ( capture1, CV_CAP_PROP_FRAME_WIDTH, w ); cvSetCaptureProperty ( capture1, CV_CAP_PROP_FRAME_HEIGHT, h ); cvSetCaptureProperty ( capture2, CV_CAP_PROP_FRAME_WIDTH, w ); cvSetCaptureProperty ( capture2, CV_CAP_PROP_FRAME_HEIGHT, h ); cvNamedWindow( "Camera_1", CV_WINDOW_AUTOSIZE ); cvNamedWindow( "Camera_2", CV_WINDOW_AUTOSIZE ); IplImage* frame1; IplImage* frame2; int n = 2; while(1) { frame1 = cvQueryFrame( capture1 ); if( !frame1 ) break; cvShowImage( "Camera_1", frame1 ); frame2 = cvQueryFrame( capture2 ); if( !frame2 ) break; cvShowImage( "Camera_2", frame2 ); int key = cvWaitKey(30); if( key == 27 ) break; } cvReleaseCapture( &capture1 ); cvReleaseCapture( &capture2 ); cvDestroyWindow( "Camera_1" ); cvDestroyWindow( "Camera_2" ); return 0; }
这个程序在使用不同类型的摄像头时,例如我使用一个普通的网络摄像头,另外一个是手机上的摄像头(这款手机具有网络摄像头功能),这样的话程序就能正常运行;但如果摄像头是相同类型时,就只能读取其中一个摄像头的数据了,第二个窗口则是一片灰色。查阅开发文档资料得知 cvCreateCameraCapture(int index) 函数可以选择摄像头,但实际测试发现 cvCreateCameraCapture 只接受 –1 和 0 两种参数,其他值,如1,2,101,102,201,202...全都无法正确的切换到第二个接入的摄像头。如果两个 capture 都使用 cvCreateCameraCapture(-1),是可以切换到第二个摄像头,但当第二次执行 cvCreateCameraCapture() 函数时,会强行弹出选择摄像头的对话框要你手动选择,而且以后再添加摄像头的话,还得修改代码重新build,实际项目中肯定不能这样处理。在OpenCV中文论坛上找到的解释是,如果摄像头的名称是“USB视频设备 #*”,则 OpenCV 只能读取其中一个的数据。
查阅opencv的cvcam官方文档,找到一些资料:
/* Begin work with cvcam, you can select single or multiple cameras in 2 ways. The first is using a camera selection dialog with cvcamSelectCamera. See an example below: */ //Prototype /* Pops up a camera(s) selection dialog Return value - number of cameras selected (0,1 or 2); Argument: an array of selected cameras numbers NULL if none selected. Should be released with free() when not needed. if NULL passed, not used. */ CVCAM_API int cvcamSelectCamera(int** out); Function ThatSelectsCamera() { int* out; int nselected = cvcamSelectCamera(&out); if(nselected>0) printf("the 1-st selected camera is camera number %d", out[0]); if(nselected == 2) printf("the 2-nd selected camera is camera number %d", out[1]); free(out); return; } /* Note: if you don’t need selected cameras numbers, simply call cvcamSelectCamera(NULL) Note2: Linux version of cvcam currently has no implementation of cvcamSelectCamera. */ //The second, non-dialog way is to use CVCAM_PROP_ENABLE property like this: int desiredcamera