从摄像机中实时获取图片
转载请说明出处
作者邮箱:jiangzezhi@163.com
现在很多的图片应用程序都需要从摄像机中获取图片,这篇文章参考DirectShow的SDK自带例程,构造了一个类用于从摄像机中实时取图。本文由2部分组成,第一部分讲述怎样用DirectShow从摄像机实时取图;第二部分讲述怎样在你的程序中使用这个类。如果你不想了解的那么仔细,而只想知道怎么用的话,可以跳过第一部分,直接看第二部分;该类的完整的源代码将在本文的后面给出。
第一部分:
(1).DirectShow基本概念:
Filter: DirectShow的基本软件构件,能执行某种功能,比如读文件,从视频采集设备获取视频,对不同的流格式进行译码,传送数据到图形卡或声卡。
Filter graph: 由不同的filter连接而成,一个功能模块对应一个filter graph,我们编写程序的目的就是构造filter graph以达到某种功能。
Filter graph manager: 建立,管理程序中的filtergraph,它的接口是IGraphBuilder
DirectShow应用程序基本架构如下图所示:
说明:
1. 应用程序创建一个Filter Graph Manager的实例
2. 应用程序用Filter Graph Manager实例创建一个filter graph
3. 应用程序用实例去控制filter graph和在filters的数据流,同时,应用程序也要对来自Filter Graph Manager的消息作出响应。
注意:当所有上述过程结束后,应用程序应该释放Filter Graph Manager和它所有的filters.
(2).图像采集filter graph
说明:
Sample grabber filter 不对capturefilter传来的数据流做任何处理,而仅仅是在内存中保留一个最新的缓存帧。capture filter 每接收到一帧图像,就向下传递,直到在显示屏上绘制出来。
第二部分:
类定义如下:
class ImageCapture
{
private:
HWNDm_App; //窗口句柄
IVideoWindow * m_pVW; //控制视频窗口接口
IMediaControl* m_pMC; //控制流的接口
IMediaEventEx* m_pME; //控制filter graph和应用程序事件交互的接口
IGraphBuilder* m_pGraph; //filter graph manager接口
ICaptureGraphBuilder2* m_pCapture; //capture filter graph接口
PLAYSTATEm_psCurrent; //记录当前filter graph的状态
ISampleGrabber*m_pSG; //用于采样图像数据的接口
LPWSTRm_fileName; //采集的图片保存的完整路径名
public:
ImageCapture(HWNDg_App,LPWSTR fileName); //构造函数
~ImageCapture(); //析构函数
public:// 外调函数
HRESULTCaptureVideo(); //视频采集
HRESULTChangePreviewState(int nShow); //改变预览状态
HRESULTHandleGraphEvent(void); //获取filter graph的事件
voidResizeVideoWindow(void); //重置视频窗口
HRESULTCaptureImage(); //采集图像
voidRewrite_NotifyOwnerMessage(long hwnd, long uMsg, long wParam, long lParam );
voidStopReview();
public:// 内调函数
HRESULTGetInterfaces(void); //得到并初始化各个接口
HRESULTFindCaptureDevice(IBaseFilter **ppSrcFilter); //枚举视频采集设备,并得到capture filter
HRESULTSetupVideoWindow(void); //设置视频窗口
voidMsg(TCHAR *szFormat, ...); //输出提示消息
};
每个函数的功能都有详细的注释,这里我们选出几个重要的外调函数来讲解一下:
构造函数:ImageCapture(HWND g_App,LPWSTR fileName);
参数 1:是视频窗口的句柄,这里需要说明一下,视频窗口可以是任何一种继承自CWnd类的控件;
参数 2:文件绝对路径名,用来存放所截取的图片(包括文件名)
HRESULT CaptureVideo()
说明:该函数完成了上述filter graph的整个过程,即只要调用这个函数,你的摄像头所拍的实时视频就能在你所指定的控件上显示出来。
HRESULT CaptureImage();
说明:该函数用于读出存在内存中的最新的图像,并写进一个新的bmp文件
void StopReview();
说明:停止filter graph的整个流程此时,sample grabber filter还保存着最新的图片,视频窗口也渲染着最新的图片,由于数据流已经停止,故最新图片不会改变。
总结:
使用这个类,就是使用上述4个函数,其他的外调函数用于win32应用程序,即用于窗口过程函数的调用,在这里就不说明了,毕竟一般的图像视频处理程序是有一个对话框界面的,而不是纯粹的一个窗口,如果想了解那几个函数的用法,也可以邮件我。