基于VFW的视频捕获方法的研究与应用

时间:2022-09-10 08:15:59

基于VFW的视频捕获方法的研究与应用

摘要:鉴于视频捕获技术在各行业中得以越来越广泛地应用,文中针对于微软公司提供的专门用于视频捕获开发的工具包VFW,介绍了如何利用VFW技术实现视频捕获,并且结合具体的实例,在VC++环境下实现了实时视频捕获、单帧捕获等多种捕获方法。

关键词:VFW;VC++;单帧捕获;实时视频捕获

中图分类号:TP39文献标识码:A文章编号:1009-3044(2009)31-pppp-0c

Research and Application of Video Capture Based on VFW

MA Lian-feng1,TANG Sai-nan2

(1.Jiangsu Province Special Equipment Safety Supervision Inspection Institute Wuxi Branch, Wuxi 214122, China; 2.Wuxi Zhongwei Microchips Co.,Ltd. Wuxi 214122, China)

Abstract: In view of the fact that the video capture technology has been more and more widely used in various professions. In the paper, how to realize the video capture with VFW technology, which is provided by Microsoft Corporation for the video capture development, is presented. Many capture ways, such as real-time video capturing, single frame capturing and so on, have been realized with Visual C++ in an example.

Key words: VFW; VC++; single frame capture; real-time video capture

近年来,随着科学技术的发展,像人脸检测、车牌号码检测、光学字符识别等技术已经逐渐地进入人们的生活,所带来的便利更是有目共睹。而作为其关键技术之一的实时视频捕获技术更是得到众多研究人员的青睐,应用的范围也在不断地得以扩展。

当前,在Windows平台下实现视频捕获一般采用两种方法:一种是利用视频采集卡所附带的SDK开发工具,此方法的实现依赖于采集卡和摄像头等硬件的类型,不利于灵活应用;另一种就是利用VFW(Video For Windows)实现视频捕获,此方法不仅与硬件设备无关,而且有Visual C++6.0的支持,易于编程实现。那么,如何利用VFW实现视频捕获呢? 本文不仅对此作出了回答,而且在VC++环境下编程实现了实时捕获、单帧捕获等多种捕获方法。

1 VFW

1.1 VFW简介

VFW是由Microsoft公司1992年推出的专门用于实时视频捕获开发的工具包,它能使应用程序数字化并播放从传统模拟视频源得到的视频剪辑。VFW的一个关键思想是播放时不需要专用硬件,为了解决数字视频数据量大的问题,需要对数据进行压缩。它引进了一种叫AVI的文件标准,该标准未规定如何对视频进行捕获、压缩和播放,仅规定视频和音频该如何存储在硬盘上,在AVI文件中交替存储视频帧和与之相匹配的音频数据。VFW给程序员提供.VBX和AVICap窗口类的高级编程工具,使程序员能通过发送消息或设置属性来捕获、播放和编辑视频剪辑。用户不必专门安装VFW,Window95本身包括了Video for Windows1.1,当用户在安装Windows时,安装程序会自动地安装配置视频所需地组件,如设备驱动程序、视频压缩程序等。

Visual C++在支持VFW方面提供有vfw32..lib、msacm32.lib、winmm.lib等类似的库。特别是它提供了功能强大、简单易行、类似于MCIWnd的窗口类AVICap。AVICap为应用程序提供了一个简单的、基于消息的接口,使之能访问视频和波形音频硬件,并能在将视频流捕获到硬盘上的过程中进行控制。

1.2 AVICap编程简介

AVICap支持实时的视频流捕获和单帧捕获并提供对视频源的控制。w在视频捕获之前需要创建一个捕获窗,所有的捕获操作及其设置都以它为基础。用AVICap窗口类创建的窗口(通过capCreateCaptureWindow函数创建)被称为“捕获窗”,其风格一般为WS_CHILD和WS_VISIBLE。在概念上,捕获窗类似于标准控件(如按钮、列表框等)。捕获窗的功能如下:

1) 将一视频流和音频流捕获到一个AVI文件中;

2) 动态地同视频和音频输入器件连接和断开;

3) 以Overlay或Preview模式对输入的视频流进行实时显示;

4) 在捕获时可指定所用的文件名并能将捕获文件的内容copy到另一个文件;

5) 设置捕获速率;

6) 显示控制视频源、视频格式、视频压缩的对话框;

7) 创建、保存或载入调色板;

8) 将图像和相关的调色板copy到剪贴板;

9) 将捕获的一个单帧图像保存为DIB格式的文件。

其中需要说明一下的是AVICap在显示视频时提供的两种模式:

① 预览(Preview)模式:该模式使用CPU资源,视频帧的显示过程如下图1示。物理上,这种模式需要通过VGA卡在监视器上显示。

图1 Preview显示流程

② 叠加(Overlay)模式:该模式使用硬件叠加进行视频显示,叠加视频的显示不经过VGA卡,叠加视频的硬件将VGA的输出信号与其自身的输出信号合并,形成组合信号显示在计算机的监视器上。只有部分视频捕获卡才具有视频叠加能力。

除了利用捕获窗的九个功能外,灵活编写AVICap提供的回调函数还可满足一些特殊需求。在以一些实时监控系统或视频会议系统中,需要将数据流写在磁盘以前就必须加以处理,达到实时功效。应用程序可用捕获窗来登记回调函数(由用户编写,而由系统调用),以便及时处理捕获窗状态改变、出错、在捕获过程中,其它应用程序处于让步(Yield)地位等情况,AVICap为此提供了七个回调函数,如capStatusCallback()、capErrorCallback()等。

与普通SDK编程一样,视频捕获编程也要用的涉及视频捕获的结构、宏、消息和函数。不同的是,发送AVICap窗口消息所能完成的功能都能调用相应的宏来完成。

在利用AVICap编程时,应该熟悉与视频捕获相关的结构,下面简要介绍一下常用的四个结构:

CAPSTATUS: 定义了捕获窗口的当前状态,如图像的宽、高等;

CAPDIVERCAPS: 定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;

CAPTUREPARMS:包含控制视频流捕获过程的参数,如捕获帧数、指定键盘或鼠标键以终止捕获、捕获时间限制等;

VIDEOHDR:定义了视频数据块的头信息,在编写回调函数时常用到其数据成员lpData(指向数据缓存的指针)和dwBufferLength(数据缓存的大小)。

2 用VC++实现视频捕获

下面以具体实例来说明如何用VC++实现捕获。在该实例中搭建的简易的实验平台如图2示,其中主要包括:

1)AK-220D(New)黑白摄像机一台;

2) CONEXANT FUSION 878A视频采集卡;

3) 三角架一个,主要用来固定CCD摄像机。

2.1 视频流显示

2.1.1 捕获窗的建立

在该程序中,捕获窗体是使用capCreateCapWindow函数来创建的。其中ghWndCap为全局变量,是捕获窗的窗口句柄。如下示:

ghWndCap=capCreateCaptureWindow(

(LPSTR)"Capture Window", // 若窗口类型为Pop-up,此为窗口名称

WS_CHILD|WS_VISIBLE, // 窗口类型

0,0,320,240,//窗口位置和尺寸

GetSafeHwnd(),0);

2.1.2 登记回调函数

根据具体要求,此处主要应用了capSetCallbackOnFrame()宏,其主要作用是每帧捕获完成后调用相应的函数完成所需的具体功能。

//声明宏

capSetCallbackOnFrame(ghWndCap,FrameCallbackProc);

其中,FrameCallbackProc回调函数函数里定义了单帧捕获完成后的具体操作。其声明如下:

LRESULT CALLBACK FrameCallbackProc(HWND ghWnd,LPVIDEOHDR lpVData);

2.1.3 捕获窗口参数的设置

若要对窗口参数进行设置,可以通过宏capCaptureGetSetup来获取捕获窗口参数的默认设置,进行相应的修改之后,通过宏capCaptureSetSetup来完成设置操作。

2.1.4 连接到一个捕获驱动器

通过使用capDriverConnect宏将捕获窗口的句柄ghWncCap连接到捕获卡的驱动程序上:

capDriverConnect(ghWndCap,0);

与之相对应的关闭连接的操作则通过capDriverDisconnect宏来完成,如下:

capDriverDisconnect(ghWndCap);

2.1.5 设置视频流的显示模式

在该程序中,考虑到后续操作而选用预览(Preview)模式进行视频流的显示,其代码如下:

//设置预览帧频

capPreviewRate(ghWndCap,66); //单位为毫秒/帧。66毫米/帧相当于15帧/秒

//开始预览

capPreview(ghWndCap,TRUE);

//屏蔽预览

capPreview(ghWndCap,FALSE);

通过以上五个步骤,视频捕获部分的显示功能就基本完成了。其界面如图3示。

2.2 几种捕获方法的实现

在捕获程序中,单帧捕获、序列帧捕获等都是经常用到的基本的捕获方法。而利用回调函数进行的捕获则可以大大提高捕获的实时性。现将本程序中实现上述几种捕获的过程简单介绍如下:

1) 单帧捕获

其主要功能是捕获一个单帧作为一个静态图像。通过宏capGrabFrameNoStop完成捕获功能,其代码如下:

capGrabFrameNoStop(ghWndCap);

如图4所示,右边的图片即为单帧捕获完成后捕获的单帧图像文件。

2) 序列帧捕获

其主要功能是连续捕获多帧,并保存为AVI文件格式。其主要实现代码如下:

//设置捕获文件的文件名

capFileSetCaptureFile(ghWndCap,szMCapFile);

//为捕获文件预先分配一定的内存

capFileAlloc(ghWndCap,(1024*1024L*5));

//开始序列帧捕获

capCaptureSequence(ghWndCap);

//停止采集

capCaptureStop(ghWndCap);

如图5中所示,右图显示的即为序列帧捕获后的AVI文件。它是通过vfw提供的MCIWnd窗口类来实现播放功能的。

3) 实时单帧捕获

通过宏capSetCallbackOnFrame可以在应用程序中指定回调函数,当预览图像帧被捕获时就调用它。在本程序中,回调函数FrameCallbackProc实现的功能主要是完成捕获单帧并且显示单帧图像,这样就可以实时的对单帧图像进行处理并将处理后的结果显示出来,这也正是整个后续程序中所需要的。此处对单帧图像进行了简单的图像处理,即先将其其转换为灰度图,然后进行了二值化处理等操作。主要程序如下:

//自定义回调函数

LRESULT CALLBACK FrameCallbackProc (HWND ghWnd ,LPVIDEOHDR lpVData)

{ …

OnBtnSCap(); //单帧捕获函数,实现捕获单帧图像操作

OnBtnSShow(); //单帧显示函数,实现单帧图像的显示

OnBtnctog(); //彩色转灰度函数,实现图像的灰度转换

OnBtnfixthreshold(); //二值化处理

OnBtnthinning(); //细化处理

OnBtncenter(); //定位中心

… }

//调用回调函数

Void CMYIRSPView::OnBtnRTCap()

{ …

capSetCallbackOnFrame(ghWndCap,FrameCallbackProc); //调用自定义的回调函数

}

其运行界面如图6所示。

3 结束语

该文详细阐述了基于VFW的视频捕获原理,并且结合具体的应用实例,在VC++环境下实现了单帧捕获、序列帧捕获和实时单帧捕获。其中实时单帧捕获利用自定义的回调函数,实现了对每一帧图像进行简单图像处理的操作,大大提高了处理的实效性,为后续程序的开发奠定了良好的基础。

参考文献:

[1] 思维科技.Visual C++视频/音频开发实用工程案例精选[M].北京:人民邮电出版社,2004.

[2] MSDN Library Visual Studio 6.0版[DB].Microsoft Corporation.

[3] 许福,舒志,张威.Visual C++ 程序设计技巧与实例[M].北京:中国铁道出版社,2003.

[4] 孙涛.谈谈使用VFW在windows下编程控制摄像头/article/74/74480.shtm.

[5] [美] Kris Jamsa, Lars Klander.C/C++程序员实用大全――C/C++最佳编程指南[M].张春晖,刘大庆,译.北京:中国水利水电出版社,2001.

上一篇:基于字符串的代码克隆检测方法的分析 下一篇:一种Agent普适机器学习分类器在Smart-It中的应...