从摄像机中实时获取图片

从摄像机中实时获取图片

转载请说明出处

作者邮箱: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应用程序,即用于窗口过程函数的调用,在这里就不说明了,毕竟一般的图像视频处理程序是有一个对话框界面的,而不是纯粹的一个窗口,如果想了解那几个函数的用法,也可以邮件我。

获取USB摄像头的1080p的JPEG格式的图片20180608_1806.7z 电脑上的系统:ubuntu14.04 // http://www.linuxidc.com/Linux/2011-03/33020.htm // V4L2摄像头获取单幅图片测试程序(MMAP模式) // [日期:2011-03-06] 来源:Linux社区 作者:aokikyon [字体:大 小] // // #加了点注释 // // #Rockie Cheng // printf #include #include // memset #include #include #include #include // close write usleep read #include #include #include #include #include #include // mmap #include #include #include #include // pthread_create pthread_join #include #define CLEAR(x) memset (&(x), 0, sizeof (x)) #define REQ_COUNT 6 #define uchar unsigned char struct buffer { void * start; size_t length; }; static char * dev_name = "/dev/video0";//摄像头设备名 static int fd = -1; struct buffer * buffers = NULL; // static unsigned int n_buffers = 0; // 2012-7-13 11:33 camera flag // static int iFlagCamera = 0; volatile int iFlagCamera = 0; // 函数名称:thread1 // 函数功能:用于接受键盘的输入,之后通知thread2抓图 // 参数列表: // 返回值 : void thread1(void) { char ch; printf("\n !!!!Warning!!!!\n Max 1000 color bmp\n Input the char: \n"); printf("\n !!!!press o an capture 1 frame picture! \n"); printf("\n !!!!press t an capture 10 frame picture! \n"); printf("\n !!!!press h an capture 100 frame picture! \n"); while(1) { while((ch=getchar()) != '\n') { printf("%c\n", ch); if('o'==ch) { iFlagCamera = 1; printf("thread1=%d\n", iFlagCamera); } else if('t'==ch) { iFlagCamera = 10; printf("thread1=%d\n", iFlagCamera); } else if('h'==ch) { iFlagCamera = 101; printf("thread1=%d\n", iFlagCamera); } else if('q'==ch) { iFlagCamera = 10001; printf("thread1=%d\n", iFlagCamera
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值