vfw控制摄像头采集图像

基于VFW的摄像头视频捕捉程序

 

#include

#pragma comment(lib, "Vfw32.lib")

初始化操作

1、创建捕获窗口

函数 capCreateCaptureWindow() 返回视频捕获窗口,它是所有捕获工作及设置的基础,其主要功能包括:

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

设置视频捕获速率;

提供视频源、视频格式以及是否采用视频压缩的对话框;

设置视频采集的显示模式为Overlay或为Preview;

实时获取每一帧视频数据;

将一视频流和音频流捕获并保存到一个AVI文件中;

捕获某一帧数字视频数据,并将单帧图像以DIB格式保存;

指定捕获数据的文件名,并能将捕获的内容拷贝到另一文件。

HWND m_hCapWnd = capCreateCaptureWindow("Capture",WS_POPUP,0,0,1,1,0,0);

2、关联窗体到本程序实例

capSetUserData(m_hCapWnd, this);

m_hCapWnd窗口句柄相当于vfw捕获活动的基础,他就代表了这个捕获。

3、登记回调函数

登记回调函数用来实现用户的一些特殊需要。在以一些实时监控系统或视频会议系统中,需要将数据流在写入磁盘以前就必须加以处理,达到实时功效。应用程序可用捕获窗来登记回调函数,以便及时处理以下情况:捕获窗状态改变、出错、使用视频或音频缓存、放弃控制权等,相应的回调函数分别为 capStatusCallback(), capErrorCallback(), capVideoStreamCallback(), capWaveStreamCallback(),capYieldCallback()

例如,设置回调函数:

capSetCallbackOnVideoStream(m_hCapWnd, OnCaptureVideo);

4、获得安装的捕获驱动程序的名称和版本

capGetDriverDescription(iIndex, szDevName, MAX_PATH, szDevVersion, MAX_PATH);

szDevNameszDevVersion返回当前第iIndex个设备的设备名称和版本。

5、连接捕获窗口与视频捕获卡

capDriverConnect(m_hCapWnd, iIndex);

6、获取捕获窗口的缺省参数

CAPTUREPARMS CapParms = {0};

capCaptureGetSetup(m_hCapWnd, &CapParms, sizeof(CapParms));

7、修改刚刚获得的参数

CapParms.fAbortLeftMouse = FALSE;   // 退出鼠标设置

CapParms.fAbortRightMouse = FALSE;   // ...

CapParms.fYield = TRUE;     // 使用背景作业

CapParms.fCaptureAudio = FALSE;         // 不获取声音

CapParms.wPercentDropForError = 50;   // 允许遗失的百分比

8、设置捕获窗口的相关参数

capCaptureSetSetup(m_hCapWnd, &CapParms, sizeof(CapParms));

9、获得视频的格式、大小

capGetVideoFormat(m_hCapWnd, &m_BmpInfo, sizeof(m_BmpInfo));

10、更改视频的尺寸

m_BmpInfo.bmiHeader.biWidth = 176;

m_BmpInfo.bmiHeader.biHeight = 144;

11、设置新的视频属性

capSetVideoFormat(m_hCapWnd, &m_BmpInfo, sizeof(m_BmpInfo))

(不更改视频尺寸或者设置属性不正确运行时会出错!)

开始捕获(不使用磁盘存储的捕获)

12、初始化Dib

HDRAWDIB m_hDib = ::DrawDibOpen();

13、开始绘制Dib

::DrawDibBegin(m_hDib,

               m_hDC,

               -1,       // don't stretch

               -1,       // don't stretch

               &m_BmpInfo.bmiHeader,

               IMAGE_WIDTH,         // width of image

               IMAGE_HEIGHT,        // height of image

               0);

14、开始捕获

capCaptureSequenceNoFile(m_hCapWnd);

结束退出

15、结束绘制Dib,关闭Dib

::DrawDibEnd(m_hDib);

::DrawDibClose(m_hDib);

清除采集过程

16、停止采集过程

capCaptureAbort(m_hCapWnd);

17、使回调函数无效

capSetCallbackOnVideoStream(m_hCapWnd, NULL);

18、断开与设备的连接

capDriverDisconnect(m_hCapWnd);

在回调函数中的操作

19、关联数据到一个捕获窗体

CVideoCapture *vidcap=(CVideoCapture *)capGetUserData(hwnd);

注意其返回一个当前实例指针!因为其参数是通过回调函数参数传递而来的m_hCapWnd

20、回放

::DrawDibDraw(m_hDib,

              m_hDC,

              m_szLocalOffset.cx, // dest : left pos

              m_szLocalOffset.cy, // dest : top pos

              m_szLocalView.cx, // don't zoom x

              m_szLocalView.cy, // don't zoom y

              &m_BmpInfo.bmiHeader, // bmp header info

              data,    // bmp data

              0,    // src :left

              0,    // src :top

              IMAGE_WIDTH,   // src : width

              IMAGE_HEIGHT,   // src : height

              DDF_SAME_DRAW);   // use prev params....

    

没用到的:

获取采集设备的功能和状态:

通过宏capDriverGetCaps(hWndCap,&m_CapDrvCapsizeof(CAPDRIVERCAPS))来获取视频设备的能力,通过宏capGetStatus(hWndCap,&m_CapStatus,sizeof(m_CapStatus))来获取视频设备的状态。

 

在许多关于视频的软件(如视频会议、可视电话等)开发中,都应用了视频捕获技术。微软为软件开发人员提供了一个专门用于视频捕获的VFW   (Video   for   Windows)   SDKVFW   SDK为在Windows系统中实现视频捕获提供了标准的接口,从而大大降低了程序的开发难度。由于VFW   SDK只有VCVB版,没有Delphi版,因此需要在Delphi中一一声明DLL中的各个函数和变量(可以参考MSDN中的VC的函数声明以及变量定义)。本文分3部分介绍如何利用VFWDelphi中开发视频捕获程序。  
VFW
简介    
VFW
是微软公司1992年推出的关于数字视频的一个软件包,它能使应用程序通过数字化设备从传统的模拟视频源得到数字化的视频剪辑。VFW的一个关键思想是播放时不需要专用硬件,为了解决数字视频数据量大的问题,需要对数据进行压缩。它引进了一种叫AVI的文件标准,该标准未规定如何对视频进行捕获、压缩及播放,仅规定视频和音频该如何存储在硬盘上,以及在AVI文件中交替存储视频帧和与之相匹配的音频数据。VFW使程序员能通过发送消息或设置属性来捕获、播放和编辑视频剪辑。在Windows   9x系统中,当用户在安装VFW时,安装程序会自动地安装配置视频所需要的组件,如设备驱动程序、视频压缩程序等。    
VFW
主要由以下6个模块组成:    
●AVICAP.DLL
:包含执行视频捕获的函数,它给AVI文件的I/O处理和视频、音频设备驱动程序提供一个高级接口;    
●MSVIDEO.DLL
:包含一套特殊的DrawDib函数,用来处理屏幕上的视频操作;    
●MCIAVI.DRV
:包括对VFWMCI命令解释器的驱动程序;    
●AVIFILE.DLL
:包含由标准多媒体I/Ommio)函数提供的更高的命令,用来访问.AVI文件;    
压缩管理器(ICM):用于管理的视频压缩/解压缩的编译码器(Codec);    
音频压缩管理器ACM:提供与ICM相似的服务,适用于波形音频。    
开发步骤  
AVICap
窗口类支持实时的视频流捕获和单帧捕获,并提供对视频源的控制。虽然MCI也提供数字视频服务(比如它为显示.AVI文件的视频提供了AVI   VIDEO命令集),为视频叠加提供了Overlay命令集,但这些命令主要是基于文件的操作,它们不能满足实时地从视频缓存中取数据的要求,   对于使用没有视频叠加能力的捕获卡的PC机来说,   MCI提供的命令集是无法捕获视频流的。而AVICap窗口类在捕获视频方面具有一定的优势,它能直接访问视频缓冲区,不需要生成中间文件,实时性很强,效率很高。而且,它还可将数字视频捕获到一个文件中。    
1.
创建捕获窗”  
在进行视频捕获之前必需要先创建一个捕获窗,并以它为基础进行所有的捕获及设置操作。捕获窗AVICap窗口类的“CapCreateCaptureWindow”函数来创建,其窗口风格一般为WS_CHILDWS_VISIBLE  
捕获窗类似于标准控件(如按钮、列表框等),并具有下列功能:    
将视频流和音频流捕获到一个AVI文件中;    
动态地同视频和音频输入器件连接或断开;    
OverlayPreview模式对输入的视频流进行实时显示;    
在捕获时,可指定所用的文件名并能将捕获文件的内容拷贝到另一个文件;    
设置捕获速率;    
显示控制视频源、视频格式、视频压缩的对话框;    
创建、保存或载入调色板;    
将图像和相关的调色板拷贝到剪贴板;    
将捕获的单帧图像保存为DIB格式的文件。    
2
.关联捕获窗和驱动程序  
单独定义的一个捕获窗是不能工作的,它必需与一个设备相关联,这样才能取得视频信号。用函数CapDriverConnect可使一个捕获窗与一个设备驱动程序相关联。  
3
.设置视频设备的属性  
通过设置TcaptureParms结构变量的各个成员变量,可以控制设备的采样频率、中断采样按键、状态行为等等。设置好TCaptureParms结构变量后,可以用函数CapCaptureSetSetup使设置生效。之后还可以用CapPreviewScaleCapPreviewRate来设置预览的比例与速度,也可以直接使用设备的默认值。  
4
.打开预览  
利用函数CapOverlay选择是否采用叠加模式预览,这样占用系统资源小,并且视频显示速度快。然后用CapPreview启动预览功能,这时就可以在屏幕上看到来自摄像机的图像了。  
通过以上4步就可以建立一个基本的视频捕获程序。但如果想自已处理从设备捕获到的视频数据,则要使用捕获窗回调函数来处理,比如一帧一帧地获得视频数据或以流的方式获得视频数据等等。  
实例编程  
下面以一个一帧一帧地从视频设备上捕获视频数据的Delphi程序为例,来说明每个函数的作用以及开发过程。  
该程序的功能是可以在屏幕上显视捕获到的视频,并可以获得每一帧的图像数据。  
新建一个工程,并将AVICAP32.PAS包含到USES中。  
Form1上放置一个TPanel控件,设Name“gCapVideoArea”,该控件用于显示视频。再放置两个TButton控件,一个Name“Openvideo”,另一个Name“Closevideo”  
定义全局变量:  
var  
//
定义捕获窗句柄  
ghCapWnd:   THandle;    
//
可以得到视频数据指针的结构变量,用于回调函数中  
VideoStr:   LPVIDEOHDR;    
//
用于设置设备属性的结构变量  
CapParms:   TCaptureParms;    
Name“Openvideo”TButton   Click事件中写入以下代码:  
procedure   TForm1.OpenvideoClick(Sender:   TObject);  
begin  
//
使用Tpanel控件来创建捕获窗口  
ghCapWnd   :=   CapCreateCaptureWindow  
(   PChar(‘KruwoSoft '),   //
捕获窗口的名字  
WS_CHILD   or   WS_VISIBLE,//
窗口样式  
0,   //X
坐标  
0,   //Y
坐标  
gCapVideoArea.Width,   //
窗口宽  
gCapVideoArea.Height,   //
窗口高  
gCapVideoArea.Handle,   //
窗口句柄  
0);   //
一般为0  
{
为了能够捕获视频帧,要启动一个捕获帧回调函数VideoStreamCallBack。捕获一个视频流或当前设备状态时分别使用以下函数:  
//
捕获一个视频流  
CapSetCallbackOnVideoStream;    
//
得到一个设备错误  
CapSetCallbackOnError;    
//
得到一个设备状态  
CapSetCallbackOnStatus    
}  
//
定义一个帧捕获回调函数  
CapSetCallbackOnFrame   (ghCapWnd,LongInt(@VideoStreamCallBack));    
//
将一个捕获窗口与一个设备驱程相关联,第二个参数是个序号,当系统中装有多个显视驱动程序时,其值分别依次为0到总个数  
CapDriverConnect(ghCapWnd,   0);    
//
设置设备属性的结构变量  
CapParms.dwRequestMicroSecPerFrame:=40000;  
CapParms.fLimitEnabled   :=   FALSE;  
CapParms.fCaptureAudio   :=   FALSE;   //   NO   Audio  
CapParms.fMCIControl   :=   FALSE;  
CapParms.fYield   :=   TRUE;  
CapParms.vKeyAbort   :=   VK_ESCAPE;  
CapParms.fAbortLeftMouse   :=   FALSE;  
CapParms.fAbortRightMouse   :=   FALSE;  
//
使设置生效  
CapCaptureSetSetup(ghCapWnd,LongInt(@CapParms),sizeof(TCAPTUREPARMS));    
//
设置预览时的比例  
CapPreviewScale(ghCapWnd,   1);  
//
设置预览时的帧频率  
CapPreviewRate(ghCapWnd,66);  
//
如果要捕获视频流,则要使用函数指定不生成文件。否则将会自动生成AVI文件  
CapCaptureSequenceNoFile(ghCapWnd);  
//
指定是否使用叠加模式,使用为1,否则为0  
CapOverlay(ghCapWnd,   1);  
//
打开预览  
CapPreview(ghCapWnd,   1);  
end;  
Name“Closevideo”TButton   Click事件中写入以下代码:  
procedure   TForm1.ClosevideoClick(Sender:   TObject);  
begin    
//
停止捕获  
capCaptureAbort(ghCapWnd);    
//
将捕获窗同驱动器断开  
capDriverDisconnect(ghCapWnd);    
end;  
定义捕获帧回调函数:  
function   FrameCallBack(hWnd:HWND;   lpVHdr:LongInt)   :LongInt;   stdcall;  
var    
DataPoint:^byte;    
DibLen,RectWidth,RectHeight:integer;  
begin    
//
转换从回调函数中得到的指针  
VideoStr:=LPVIDEOHDR(lpVHdr);  
//
得到返回的数据大小    
DibLen:=VideoStr^.dwBufferLength;    
GetMem(DataPoint,64000);  
//
将帧数据COPY到一个内存中,注意DATAPOINT要先分配空间  
CopyMemory(DataPoint,VideoStr^.lpData,Diblen);    
//
一些其他处理  
……  
end;  
灵活地使用AVICap窗口类的回调函数可以满足各种不同的需求,但要注意从视频卡中捕获的视频数据的格式和图像的长宽要参考视频卡的参数。而且有些视频卡通过设置可支持多种的格式和图像长宽,所以在还原图像时要注意参考所用的视频卡的参数。  

你可能感兴趣的:(vfw控制摄像头采集图像)