这边介绍OpenCV另一个跟视讯有关的函式库"cvcam.h",它也包括AVI文件的存取跟视讯播放,不同的是,它具有控制视讯相关功能的子程序
cvcamInit()
cvcamStart()
cvcamPause()
cvcamResume()
cvcamStop()
cvcamExit()
及两个设定视讯相关的GUI接口.而且它是支持HWND,也就是他可以支持其它窗口接口程序设计,直接整合在它们的Form里,如Visual C++或C++ Builder窗口接口程序设计,只要给它窗口接口的ID,就可以整合操作,且一次可以开启多个视讯.
cvcam.h的视讯使用
#include <cvcam.h>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <windows.h>
void CaptureCallback(IplImage *frame1);
int main()
{
HWND CaptureWindow=0;
int width=640;
int height=480;
int CamerasCount= cvcamGetCamerasCount();
printf("视讯装置总数量: %d\n",CamerasCount);
CameraDescription CameraDescription1;
cvcamSetProperty(0,CVCAM_PROP_ENABLE,CVCAMTRUE);
cvcamSetProperty(0,CVCAM_PROP_RENDER,CVCAMTRUE);
cvcamSetProperty(0,CVCAM_PROP_WINDOW,&
CaptureWindow);
cvcamSetProperty(0,CVCAM_PROP_CALLBACK,(void *)&
CaptureCallback);
cvcamSetProperty(0,CVCAM_RNDWIDTH,&
width);
cvcamSetProperty(0,CVCAM_RNDHEIGHT,&
height);
cvcamGetProperty(0,CVCAM_VIDEOFORMAT,NULL);
cvcamGetProperty(0,CVCAM_CAMERAPROPS,NULL);
cvcamGetProperty(0,CVCAM_DESCRIPTION,&
CameraDescription1);
cvcamInit();
cvcamStart();
printf("===============================\n");
printf("选择编号0的装置\n");
printf("装置名称:\n%d\n",CameraDescription1.device);
printf("装置描述:\n%s\n",CameraDescription1.DeviceDescription);
printf("装置信道数:\n%d\n",CameraDescription1.channel);
printf("装置信道描述:\n%s\n",CameraDescription1.ChannelDescription);
printf("最大宽上限:\n%d\n",CameraDescription1.maxwidth);
printf("最大高上限:\n%d\n",CameraDescription1.maxheight);
printf("最小宽上限:\n%d\n",CameraDescription1.minwidth);
printf("最小高上限:\n%d\n",CameraDescription1.minheight);
cvWaitKey(0);
cvcamStop();
cvcamExit();
}
void CaptureCallback(IplImage *frame1)
{
int i,j;
for(i=0;i<frame1->height;i+=20)
{
for(j=0;j<frame1->widthStep;j+=frame1->nChannels)
{
frame1->imageData[i*j] =0;
frame1->imageData[i*j+1]=0;
frame1->imageData[i*j+2]=255;
}
}
}
执行结果:
(1)Frame格式修改
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
(2)视讯装置设定
(3)播放
上面的程序代码,属于cvcam重新开启的win32窗口,而非OpenCV自己的窗口程序,所以不支持cvSetMouseCallback()及cvCreateTrackbar()的呼叫,因此,不能制作鼠标及Trackbar事件,不过它可以用键盘阻断,以及他程序内部本身的呼叫,CaptureCallback()就是他的呼叫方法,,它可以藉由HWND去嵌入窗口程序(Visual C++,C++ Builder)做更强大的应用.上面的程序代码给了一个HWND为NULL的窗口代号,让她重新开启了一个非Opencv的窗口,接着侦测视讯装置数量cvcamGetCamerasCount(),注意,这是程序代码必要的,如果不做侦测就找不到视讯装置,接着是视讯描述数据结构,cvcamSetProperty()是视讯属性设立,第一个功能CVCAM_PROP_ENABLE是将视讯设成Enable,CVCAM_PROP_RENDER则是交付视讯,CVCAM_PROP_WINDOW则是选定视讯开启窗口,CVCAM_PROP_CALLBACK就是视讯的呼叫,可以自行定义子程序来修改视讯显示画面的内容,CVCAM_RNDWIDTH跟CVCAM_RNDHEIGHT可以自由修改画面的宽跟高.接着是用cvcamGetProperty()取得信息,CVCAM_VIDEOFORMAT及CVCAM_CAMERAPROPS为开启GUI接口视讯功能设定,CVCAM_DESCRIPTION是取得视讯详细描述.这边显示的执行结果是变成红色直线条,而CameraDescription数据结构获取的讯息有些也不一定正确.
下面这一段程序代码就是要做到视讯的选择,以及两台视讯的功能设定,使用的是cvcamSelectCamera()的函式,"cvcam.h"具有一个窗口接口一次可以自己选择两台想要用的视讯功能,以及二择一的视讯装置,但是对于不同厂商的视讯装置会造成无法同步播放的问题,可以用视讯仿真器的软件解决,以下为多台视讯操控程序代码
cvcam.h的视讯二择一,或是两台操作
#include <cvcam.h>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <windows.h>
void CaptureCallback(IplImage *frame1);
void StereoCallback(IplImage frame1,IplImage *frame2);
int main()
{
HWND CaptureWindow1=0;
HWND CaptureWindow2=0;
int *CameraNumber;
int nSelected = cvcamSelectCamera(&
CameraNumber);
if(nSelected==1)
{
cvcamSetProperty(CameraNumber[0], CVCAM_PROP_ENABLE, CVCAMTRUE);
cvcamSetProperty(CameraNumber[0], CVCAM_PROP_RENDER, CVCAMTRUE);
cvcamSetProperty(CameraNumber[0], CVCAM_STEREO_CALLBACK,(void *)&
CaptureCallback);
cvcamSetProperty(CameraNumber[0], CVCAM_PROP_WINDOW, &
CaptureWindow1);
}
else if(nSelected==2)
{
cvNamedWindow("cvcam1 Window",1);
CaptureWindow1=(HWND)cvGetWindowHandle("cvcam1 Window");
cvcamSetProperty(CameraNumber[0], CVCAM_PROP_ENABLE, CVCAMTRUE);
cvcamSetProperty(CameraNumber[0], CVCAM_PROP_RENDER, CVCAMTRUE);
cvcamSetProperty(CameraNumber[0], CVCAM_STEREO_CALLBACK,(void *)&
StereoCallback);
cvcamSetProperty(CameraNumber[0], CVCAM_PROP_WINDOW, &
CaptureWindow1);
cvNamedWindow("cvcam2 Window",1);
CaptureWindow2=(HWND)cvGetWindowHandle("cvcam2 Window");
cvcamSetProperty(CameraNumber[1], CVCAM_PROP_ENABLE, CVCAMTRUE);
cvcamSetProperty(CameraNumber[1], CVCAM_PROP_RENDER, CVCAMTRUE);
cvcamSetProperty(CameraNumber[1], CVCAM_STEREO_CALLBACK,(void *)&
StereoCallback);
cvcamSetProperty(CameraNumber[1], CVCAM_PROP_WINDOW, &
CaptureWindow2);
}
cvcamInit();
cvcamStart();
cvWaitKey(0);
cvcamStop();
cvcamExit();
free(CameraNumber);
cvDestroyWindow("cvcam1 Window");
cvDestroyWindow("cvcam2 Window");
}
void CaptureCallback(IplImage *frame1)
{}
void StereoCallback(IplImage frame1,IplImage *frame2)
{}
执行结果:
(1)选择想要用的装置
(2)选择e2eSoft VCam出现的挂载画面
(2)装置播放
cvcamSelectCamera()这个函式会自动侦测视讯装置的数量,并且开启一个GUI界面,让使用者可以选定想使用的装置,因而取代了cvcamGetCamerasCount()的功能,而他最多可以选定两台装置同步播放,当cvcamSelectCamera()的回传值nSelected==1时,表示只选定一台装置,被选定的装置代号被放在CameraNumber[0]里面,而当nSelected==2时,表示选定了两台装置,装置代号分别被放在CameraNumber[0]及CameraNumber[1]里,而要做到同步播放,那就一定要用cvcamSetProperty()里面CVCAM_STEREO_CALLBACK的参数啦,这个参数只能处理两台视讯同步播放,并且可以在StereoCallback()这个函式处理两台视讯播放的画面内容,也就是写算法进去一次处理两台画面,也是因为这个函式的问题,造成了不同厂商的视讯装置会互冲,会出现的问题是"找不到中介筛选器的组合,所以无法连接。",这个问题就只能用视讯仿真器来解决啦,把其中一台会冲到的装置挂载到视讯仿真器上面,视讯仿真器的下载网址
http://www.e2esoft.cn/vcam/index.asp
VCam
要注意的是,被挂载的装置会造成OpenCV的任何一个视讯函式都无法播放,如果是做单一的视讯播放,而该装置又被挂载,则无法使用该装置,而只能使用视讯仿真器所提供的虚拟装置名称.
cvcamGetCamerasCount()
侦测所有视讯装置数量,是一定要做的第一步.
int cvcamGetCamerasCount()
cvcamSelectCamera()
开启选择视讯装置的GUI界面,内部具有侦测视讯装置数量cvcamGetCamerasCount()的功能,cvcamSelectCamera()的回传值为被选定的视讯数,这边只能选定两个装置,因此回传值不是0就是1,2,而它的第一个自变量为被选定的视讯代号数组,数组的最大长度为2,分别放入的是第一视讯装置代号跟第二视讯装置代号.
cvcamSelectCamera(被选定的int *型别视讯数组)
cvcamSetProperty()
设立视讯装置属性,这边他的参数方式是用字符串的形式去设计,如下定义
static const char CVCAM_PROP_ENABLE[] = "enable"; Enable视讯
static const char CVCAM_PROP_RENDER[] = "render"; 启用视讯
static const char CVCAM_PROP_WINDOW[] = "window"; 选定画面在哪个窗口开启
static const char CVCAM_PROP_CALLBACK[] = "callback"; 设定Capture方法呼叫
static const char CVCAM_STEREO_CALLBACK[] = "stereo_callback"; 设定两个装置同步播放及StereoCallback函式
static const char CVCAM_STEREO3_CALLBACK[] = "stereo3_callback"; 设定三个装置同步播放及Stereo3Callback
static const char CVCAM_STEREO4_CALLBACK[] = "stereo4_callback"; 设定四个装置同步播放及Stereo4Callback
static const char CVCAM_RNDWIDTH[] = "rendering_width"; 修改画面宽度
static const char CVCAM_RNDHEIGHT[] = "rendering_height"; 修改画面高度
因此,它的参数是字符串,而非之前的用代号表示,CVCAM_PROP_WINDOW需要给它HWND型别,CVCAM_PROP_CALLBACK则需要给它自行定义的子程序名称,CVCAMTRUE则是用代号表示如下
#define CVCAMTRUE (void*)1
#define CVCAMFALSE (void*)0
cvcamSetProperty(装置代号,参数或字符串,属性设定参数);
cvcamGetProperty()
取得视讯装置属性,用法跟上面类似,可取得的参数为
static const char CVCAM_VIDEOFORMAT[] = "video_pp"; GUI接口的视讯格式设定
static const char CVCAM_CAMERAPROPS[] = "camera_pp"; GUI接口的视讯装置设定
static const char CVCAM_DESCRIPTION[] = "description"; 详细信息描述
CVCAM_DESCRIPTION要用CameraDescription数据结构接.
cvcamSetProperty(装置代号,参数或字符串,属性设定参数);
cvcamInit();
初始化视讯
cvcamStart();
启动视讯
cvcamStop();
停止视讯
cvcamExit();
关闭视讯
CaptureCallback()
修改播放Frame的呼叫,接收的格式是IplImage数据结构.
CaptureCallback(IplImage *frame1);
StereoCallback()
修改两个视讯装置Frame播放的呼叫,接收的格式是IplImage数据结构.
CaptureCallback(IplImage *frame1,IplImage *frame2);
用户213576 2009-7-26 16:57