摘要 在VC++6.0中利用VFW技术实现视频数据实时获取的过程中,针对回调函数的处理中所碰到的问题、图像采集中原始数据的获取以及捕获窗口的建立的问题进行了详细的讨论,并给出了具体的解决办法。
关键词 VFW 图像采集 回调函数
引言
以光学为基础,融光电子学、计算机技术、激光技术、图像处理技术等现代科学技术为一体的图像测量技术在测量领域中形成了新的测量技术,基于数字图像处理技术的图像测量系统目前已广泛应用于几何量的测量、航空等遥感测量、精密复杂零件的微尺寸测量和外观测量,以及光波干涉图、应力应变场状态分布等和图像有关的技术领域中。在基于数字图像处理技术的图像测量系统中,必须解决的问题就是图像采集,即图像数据的获取,采集的图像数据用于后期的图像处理。
视频图像捕获一般来讲有两种方法,一种是利用视频捕获卡所附带的SDK开发工具,这种捕获方法的实现是与设备有关的,依赖于视频捕获卡与摄像头的类型,不利于灵活应用;另外一种捕获方法是Microsoft的Visual C++自从4.0版就开始支持Video for Windows(简称VFW),这给视频捕获编程带来了很大的方便,利用VFW技术的可以提高视频捕获的灵活性,减少了对视频设备的依赖。在VC++6.0中,含有MCIAVI、DRAWDIB、AVIFILE和AVICAP等组件。通过它们之间的协调工作,可以完成播放、编辑、文件管理和视频捕获等功能,为视频图像处理和分析带来非常大的便利,本文就利用VFW进行视频数据的实时采集中的碰到的几个实际问题进行探讨。
VFW库函数简介
视频数据的实时采集主要是通过调用AVICap32.dll创建AVICap窗口类 ,由AVICap窗口类中的消息、宏函数、结构以及回调函数来完成。 AVICap在捕获视频方面具有明显的优势,它能直接访问视频缓冲区,不需要生成中间文件,实时性很高,它也可将数字视频保存到事先建好的文件中。实际应用表明,通过这种方法,提高了视频采集的效果和程序运行的效率,同时也减少了对硬件的依赖性,提高了程序的兼容性和移植性。
VFW的视频采集功能主要包括捕获视频流至AVI文件(capCaptureSequence)、捕获视频流至缓存(capCaptureSequenceNofile)、捕获视频流至AVI文件(capCaptureSingleFrame)、本地预览(capPreview/capOverlay)和捕获单帧预览(capGrabFrame/capGrabFrameNoStop)等。VFW还提供了回调函数 ,允许应用程序精确控制视频流的捕获、检测错误、监控状态变化 ,以及在捕获两帧数据的空隙和每捕获新帧时对实时数据进行处理。
几个实际问题的探讨
1、回调函数处理的问题
回调函数是至今为止最有用的编程机制之一。在Windows中,回调函数更是窗口过程、钩子过程、异步过程调用所必需的,在整个回调过程中自始至终地使用回调方法。人们可以注册回调方法以获得加载/卸载通知,未处理异常通知,数据库/窗口状态修改通知,文件系统修改通知,菜单项选择,完成的异步操作通知,过滤一组条目等等。在VFW中有几条这样的宏函数,如用于设置在发生某事件后能作出反应的回调函数的宏函数,它和中断服务机制很相似,条件一满足,程序会自动进入相应的回调函数体中,该函数究竟要做些什么,全由开发者借助其参数自行编制程序来确定。利用VFW获取实时视频数据通常可以运用视频处理的回调机制(call-backmechanism) 获得实时数据缓冲区的首址和长度并对图像数据进行处理,同时也可以进行视频数据的直接传输,在这一方面很多文章都作了具体的介绍。但是按照大多数文章的介绍,在具体的应用过程中,对回调函数作如下定义时,程序总是无法通过编译:
{ LRESULT CALLBACK FrameCallbackProc(HWND ghWnd,LPVIDEOHDR lpVData) unsigned char *data; data=lpVData->lpData;//获得视频数据首地址,并将数据存入data数组中以便处理 } |
static LRESULT CALLBACK FrameCallbackProc(HWND ghWnd,LPVIDEOHDR lpVData) { unsigned char *data; data=lpVData->lpData;//获得视频数据首地址,并将数据存入data数组中以便处理 } |
//获得capEditCopy( )拷贝到剪贴板中的图像数据句柄,通过CF_DIB参数指定数据 HANDLE hData; ::GlobalFree ((HGLOBAL)hData); hData=(HANDLE)CopyHandle(::GetCliPBoardData(CF_DIB)); |
(2) 利用capFileSaveDIB将缓冲区中的图像数据转化为DIB位图直接保存为文件,需要处理时,再读取位图中的图像数据到内存进行后续的处理。这种方式因为有一个文件存储和读取的延迟,对于实时的图像处理来说,响应速度比前者要稍慢,经过多次实验证明,只要图像处理算法的计算量不是很大,仍然可以保证比较好的实时性。
3、图像采集窗口建立的问题
在视频捕获之前需要创建一个捕获窗,所有的捕获操作及其设置都以它为基础。一个AVICap视窗口句柄描述了声频与视频流的细节,这样就使程序员的应用程序从AVI文件格式,声频视频缓冲管理,低层声频视频驱动访问等解脱出来。AVICap即是预定义的Windows窗口类,利用该窗口类创建的子窗口可以与视频采集设备的驱动程序相联系,该子窗口的客户区用来显示采集设备捕获的实时视频图像。
但是在实际应用过程中,应用程序可能会基于单文档(SDI)、多文档或者是基于对话框的界面,由于三种类型的不同,捕获窗的具体创建应根据具体要求而有所区别。不管是采用哪种类型,根据实时视频的显示的具体要求,关键是如何获取捕获窗口的父窗口句柄。通常捕获窗口的创建可以如下两种方式:
(1)获取动态创建的父窗口的句柄,动态的创建捕获窗口。具体的代码片段如下:
CFrameWnd m_wndSource; if(!m_wndSource.CreateEx(WS_EX_TOPMOST,NULL,"source",WS_CAPTION,CRect(100,100,150,180),NULL,0)) return -1; m_wndSource.ShowWindow(SW_HIDE); m_WndCap=capCreateCaptureWindow((LPSTR)" 视频捕捉测试程 |
m_hCapWnd = capCreateCaptureWindow((LPSTR)TEXT("视频捕捉测试程序"),WS_CHILD|WS_VISIBLE, 0,0,768,576,this->m_hWnd,0); |
结束语
利用VFW技术实现视频数据实时获取,提高了视频采集的效果和程序运行的效率,同时也减少了对硬件的依赖性,提高了程序的兼容性和移植性。在很多基于数字图像处理技术的图像测量系统中都使用了这种方法。本文就具体应用中所碰到的实际问题进行了详细的讨论,并给出了具体的解决办法。