龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > VC开发 >

VC++6.0实现视频数据实时获取的探讨(2)

时间:2009-12-30 15:42来源:未知 作者:admin 点击:
分享到:
(2) 使用静态成员函数,静态成员函数不使用this指针作为隐含参数,这样就可以作为回调函数了。静态成员函数具有两大特点:其一,可以在没有类实例的

  (2) 使用静态成员函数,静态成员函数不使用this指针作为隐含参数,这样就可以作为回调函数了。静态成员函数具有两大特点:其一,可以在没有类实例的情况下使用;其二,只能访问静态成员变量和静态成员函数,不能访问非静态成员变量和非静态成员函数。由于在C++中使用类成员函数作为回调函数的目的就是为了访问所有的成员变量和成员函数,如果作不到这一点将不具有实际意义。解决的办法也很简单,就是使用一个静态类指针作为类成员,通过在类创建时初始化该静态指针,如pThis=this,然后在回调函数中通过该静态指针就可以访问所有成员变量和成员函数了。这种处理办法适用于只有一个类实例的情况,因为多个类实例将共享静态类成员和静态成员函数,这就导致静态指针指向最后创建的类实例。为了避免这种情况,可以使用回调函数的一个参数来传递this指针,从而实现数据成员共享。这种方法稍稍麻烦,这里就不再赘述。

  因此,可以对回调函数作如下定义:

static LRESULT CALLBACK FrameCallbackProc(HWND ghWnd,LPVIDEOHDR lpVData)
{
 unsigned char *data;
 data=lpVData->lpData;//获得视频数据首地址,并将数据存入data数组中以便处理
}
2、图像采集中的问题

  视频数据的采集是整个应用的关键,根据应用的不同可以将视频帧采集到的文件或采集的缓存直接加以处理。利用VFW获取实时视频数据通常可以运用视频处理的回调机制(call-backmechanism) 获得实时数据缓冲区的首址和长度并对图像数据进行实时处理,但是在这个过程中图像处理程序不能太长,否则视频显示不流畅。另外,在实际采集过程中,有些图像采集卡驱动程序对通过回调机制所获取的数据进行了压缩,比如DC10,而在图像测量系统高精度的要求,压缩后的图像数据直接影响以后的图像处理工作。通过采用以下两种典型技术可以实现将没有压缩的视频帧的图像数据的采集。

  (1) 通过研究发现,尽管图像采集卡驱动程序对通过回调机制所获取的数据进行了压缩,但是利用VFW中的capEditCopy( )宏函数将帧图像缓冲区中的图像数据拷贝到剪贴板上时,并没有压缩图像数据,因此可以不采用回调机制而直接利用capGrabFrameNoStop()捕获一帧图像,然后将数据拷贝拷贝到剪贴板上,再通过DIB(Device Independent Bitmap)操作获取内存中图像数据首地址,进行后续的图像数据处理。具体的代码片段如下:

//获得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)" 视频捕捉测试程序",WS_CHILD|WS_VISIBLE,0,0,300,240,m_wndSource.m_hWnd ,0);

  (2)获取显示的实时视频窗口的句柄,静态的创建捕获窗口。具体的代码片段如下:

m_hCapWnd = capCreateCaptureWindow((LPSTR)TEXT("视频捕捉测试程序"),WS_CHILD|WS_VISIBLE,
0,0,768,576,this->m_hWnd,0);

  结束语

  利用VFW技术实现视频数据实时获取,提高了视频采集的效果和程序运行的效率,同时也减少了对硬件的依赖性,提高了程序的兼容性和移植性。在很多基于数字图像处理技术的图像测量系统中都使用了这种方法。本文就具体应用中所碰到的实际问题进行了详细的讨论,并给出了具体的解决办法。

精彩图集

赞助商链接