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

转自:http://blog.csdn.net/laolei1986/archive/2010/07/13/5730241.aspx

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

#include <vfw.h>

#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);

szDevName和szDevVersion返回当前第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_CapDrvCap,sizeof(CAPDRIVERCAPS))来获取视频设备的能力,通过宏capGetStatus(hWndCap,&m_CapStatus,sizeof(m_CapStatus))来获取视频设备的状态。

示例程序代码:http://download.csdn.net/source/2940975

VFW的详细使用说明请参考:

谈谈使用VFW在windows下编程控制摄像头http://blog.csdn.net/suntaoznz/archive/2005/08/06/447067.aspx

二、AVICap回调函数

回调函数示例: LRESULT CALLBACK FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr) {...}

LPVIDEOHDR 是结构体VIDEOHDR的指针,而在MSDN中察看结构体VIDEOHDR,我们就可以找到桢数据的存贮位置指针了。

VIDEOHDR定义如下:
typedef struct videohdr_tag {
LPBYTE lpData;
DWORD dwBufferLength;
DWORD dwBytesUsed;
DWORD dwTimeCaptured;
DWORD dwUser;
DWORD dwFlags;
DWORD_PTR dwReserved[4];
} VIDEOHDR, NEAR *PVIDEOHDR, FAR * LPVIDEOHDR;
看到结构体中第一个参数了么?这个就是我们想要的桢数据的指针!后面参数,包括缓冲区长度等。

你的应用程序可以为一个捕获窗口注册一些回调函数,它们可以告诉你的应用程序一些变化。比如捕获状态发生变化了,或者有错误发生了,音视频缓存区可使用了。下面的消息设置回调函数。

消 息
说 明

WM_CAP_SET_CALLBACK_CAPCONTROL

CapSetCallbackOnCapControl 宏

在应用程序中指定回调函数用于控制捕获的开始和结束。

WM_CAP_SET_CALLBACK_ERROR

CapSetCallbackOnError 宏

在应用程序中指定回调函数,当出错的时候就调用它。

WM_CAP_SET_CALLBACK_FRAME

CapSetCallbackOnFrame 宏
在应用程序中指定回调函数,当预览图像帧被捕获了的时候就调用它。

WM_CAP_SET_CALLBACK_STATUS

CapSetCallbackOnStatus 宏

在应用程序中指定回调函数,当状态(status)改变的时候就调用它。

WM_CAP_SET_CALLBACK_VIDEOSTREAM

CapSetCallbackOnVideoStream 宏
在应用程序中指定回调函数,在流捕获期间,当一个新的视频缓存区可用的时候就调用它。

WM_CAP_SET_CALLBACK_WAVESTREAM

CapSetCallbackOnWaveStream 宏

在应用程序中指定回调函数,在流捕获期间,当一个新的音频缓存区可用的时候就调用它。

WM_CAP_SET_CALLBACK_YIELD

CapSetCallbackOnYield 宏
在应用程序中指定回调函数,在流捕获期间Yielding(产生?)

三、预览模式的流程:

m_hVideo=::capCreateCaptureWindow("Me",WS_CHILD | WS_VISIBLE,
0,0,500,500,m_hWnd,0); //参数m_hWnd是你的工程中对话框的句柄,窗口类中都有这个成员变量,而对话框的类是窗口类的子类
//capSetCallbackOnFrame(m_hVideo, FrameCallbackProc); //回调函数
capDriverConnect(m_hVideo,0); //连接设备0
capPreviewRate(m_hVideo, 40); // 设置Preview模式的显示速率
capPreview(m_hVideo, TRUE); //启动Preview模式

capPreview(hVideo, FALSE); // 屏蔽预览

capDriverDisconnect(hVideo);//将捕获窗同驱动器断开

四、保存为文件

下例使用capFileSetCaptureFile宏来指定一个要命名的文件名(mycap.avi),使用capFileAlloc宏去预分配5MB的文件。
char szCaptureFile[] = "MYCAP.AVI";
capFileSetCaptureFile( m_capwnd, szCaptureFile);
capFileAlloc( m_capwnd, (1024L * 1024L * 5));*/

或者使用capCaptureSequence宏开始视频捕获,使用capFileSaveAs宏从捕获文件拷贝数据到其他文件NEWFILE.AVI中。
char szNewName[] = "NEWFILE.AVI";
// Set up the capture operation.
capCaptureSequence(hWndC);
// Capture.
capFileSaveAs(hWndC, szNewName);

Powered by Zoundry Raven

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值