原创 GUI界面的制作-"cvcam.h"视讯函式库(1)

2009-2-21 22:45 5568 8 9 分类: 软件与OS

GUI界面的制作-"cvcam.h"视讯函式库(1) <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


这边介绍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" />7b5fc57e-7a1c-4b8d-aab5-336188a26cda.JPG
(2)
视讯装置设定
0a41d693-12ee-442b-808a-6c0fe758d0a1.JPG
(3)
播放
567c8a21-1122-4aa7-b987-909d1c8731d7.JPG

上面的程序代码,属于cvcam重新开启的win32窗口,而非OpenCV自己的窗口程序,所以不支持cvSetMouseCallback()cvCreateTrackbar()的呼叫,因此,不能制作鼠标及Trackbar事件,不过它可以用键盘阻断,以及他程序内部本身的呼叫,CaptureCallback()就是他的呼叫方法,,它可以藉由HWND去嵌入窗口程序(Visual C++,C++ Builder)做更强大的应用.上面的程序代码给了一个HWNDNULL的窗口代号,让她重新开启了一个非Opencv的窗口,接着侦测视讯装置数量cvcamGetCamerasCount(),注意,这是程序代码必要的,如果不做侦测就找不到视讯装置,接着是视讯描述数据结构,cvcamSetProperty()是视讯属性设立,第一个功能CVCAM_PROP_ENABLE是将视讯设成Enable,CVCAM_PROP_RENDER则是交付视讯,CVCAM_PROP_WINDOW则是选定视讯开启窗口,CVCAM_PROP_CALLBACK就是视讯的呼叫,可以自行定义子程序来修改视讯显示画面的内容,CVCAM_RNDWIDTHCVCAM_RNDHEIGHT可以自由修改画面的宽跟高.接着是用cvcamGetProperty()取得信息,CVCAM_VIDEOFORMATCVCAM_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)
选择想要用的装置
a5f3f66d-ead1-404c-b986-da00010762b6.JPG

(2)
选择e2eSoft VCam出现的挂载画面
6b4963c8-ed02-4edb-a53c-08886bddac9e.JPG

(2)
装置播放
23bbc1e8-d9d8-4024-9e51-c226f4cc6b6d.JPG

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
70dd46af-b784-4852-b3ae-58ff9de041eb.JPG

要注意的是,被挂载的装置会造成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);


 


 

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户213576 2009-7-26 16:57

错误 9 error C2065: “CameraDescription1”: 未声明的标识符 c:\users\leon\desktop\36\cvcam.c 36 cvcam CameraDescription1代表什么含义,谢谢!
相关推荐阅读
用户51033 2013-12-17 22:53
使用宏命令FormatDataLibsvm.xls将数据转成LIBSVM格式
http://blog.sina.com.cn/s/blog_5980835e0100dioo.html 毕业设计做的是svm,虽然不是很新的东西,但是能把它弄懂也是好的。要加一点技术含量无非...
用户51033 2013-12-17 22:50
LIBSVM做回归预测--终于弄通
http://blog.sina.com.cn/s/blog_5980835e0100dp52.html 看了网上很多帖子和博客,自己琢磨了很久到现在才弄明白怎么用libsvm来做预测。因为网上的帖子...
用户51033 2013-12-17 22:43
LIBSVM回归详细操作步骤
原文地址:LIBSVM回归详细操作步骤(附图)--更新至20090806作者:梦在继续 P.S. 多谢“三月未央”网友的提醒,本文中的一些错误得到改正,原先的第五幅图中路径有错(估计那晚太困了,稀里糊...
用户51033 2012-03-10 21:06
关于RS232/RS422/RS485总线的抗干扰的措施
2011-07-27 21:48 原文:http://hi.baidu.com/%B5%E7%D7%D3%C2%F8%CD%B7/blog/item/2b9d2c8e51bfd72466096e4...
用户51033 2012-02-18 22:06
高边和低边电流检测技术分析
当代电子系统中的电源管理可以通过高效的电源分配优化系统效率。电流检测是电源管理的关键技术之一,它不仅有助于保持理想的电压等级,而且能通过提供伺服调整保持电子系统处于正常状态,同时还能防止发生...
用户51033 2012-02-18 20:20
TVS二极管的选型和应用测试计算实例
    很多工程师在电路设计时都会考虑到EMC,但是在ESD方面却是很少考虑或甚至不考虑。个人认为有些是产品特性或是成本原因不考虑防雷防静电,但据了解, 相当多的工程师特别是比较年轻的工程师...
EE直播间
更多
我要评论
1
8
关闭 站长推荐上一条 /3 下一条