DirectShow获取一张图片

合集下载

基于DirectShow视频及图片捕获软件的开发

基于DirectShow视频及图片捕获软件的开发

我们知道目前很多工业相机的图像数据采集都是基于DirectShow的,常见的有映美精等。

DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。

DirectShow为多媒体流的捕捉和回放提供了强有力的支持。

运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。

它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒体数据的回放变得轻而易举。

另外,DirectShow还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD的播放,视频的非线性编辑,以及与数字摄像机的数据交换。

更值得一提的是,DirectShow提供的是一种开放式的开发环境,我们可以根据自己的需要定制自己的组件。

笔者使用visual studio 2005 来开发了基于DirectShow的视频捕获软件,并用开发的软件对映美精相机进行了测试。

本软件不但可以实现对相机的视频捕获,而且还可以抓取图像帧。

软件运行时自动搜索所连接的相机,预览后可以对相机参数进行设置。

下面是软件的主界面。

预览视频后可以对视频格式和图像参数进行设置。

开始预览时,捕获的视频是黑白的,我们将颜色空间设置为UYVY即可捕获彩色视频。

下面是捕获的一帧图像,图像质量虽然没有映美精自带的软件效果好,但已经实现了所需各项基本功能,接下来的工作将会进一步提高软件性能。

另外我们还可以捕获视频,点击“捕获视频”按钮,输入要保持的文件名,注意要以.avi后缀结尾,点确定就开始捕获视频。

从我们开发的软件可以看到,映美精的相机能够很好的支持DirectShow的驱动,我们的软件对映美精相机的识别是如此的容易。

接下来我们将继续开发基于其它驱动的图像捕获软件,为最终实现在一个软件中识别各种相机而努力。

(MatLab、Labview)通过Directshow接口访问相机参数设置方法

(MatLab、Labview)通过Directshow接口访问相机参数设置方法

(MatLab、Labview)通过Directshow接⼝访问相机参数设置⽅法DirectShow接⼝访问相机参数设置⽅法本⽂档适⽤于所有适⽤directshow接⼝访问相机的程序,例如MATLAB 和Labview的ImaqDx接⼝、Halcon的Directshow接⼝等。

MATLAB中,可以通过如下界⾯设置相机参数:Labview的NIMAX中可以通过如下界⾯设置相机参数:下⾯以Labview为例,介绍Labview中如何通过ImaqDx接⼝访问迈德威视⼯业相机。

⽬前,我们提供三种⽅式,在Labview中访问我们的相机:1.GigeVision接⼝。

仅我司GigE相机⽀持该⽅式访问。

2.直接基于SDK的DLL⽂件调⽤的⽅式。

该⽅式⽀持我们所有型号相机。

例程在安装⽬录的DEMO/LABVIEW/USEDLL⽂件夹中。

3.通过ImaqDx使⽤Directshow接⼝访问相机。

该⽅式⽀持我们所有型号相机。

Directshow接⼝是windows系统上的⾳视频标准接⼝,定义了⼀些预先约定好的协议,但是由于协议定义时间⽐较早,也没有为⼯业摄像头考虑参数接⼝,所以接⼝的参数配置上,没有像使⽤我们的SDK那样灵活。

我们针对此问题,做了⼀些特殊处理,扩展了Dircetshow接⼝中Camera Atrributes的“White Balance”属性,⽬前可以该⽅式进⾏如下操作:1.设置相机⼯作模式(连续采集、软触发、硬触发)⽅法:在Camera Atrributes中,设置“White Balance”属性的Value值●为0,则相机进⼊连续⼯作模式;●设置为1,则相机进⼊软触发⼯作模式;●设置为2则相机进⼊硬触发⼯作模式。

2.执⾏⼀次软触发⽅法:在Camera Atrributes中,设置“White Balance”属性的Value 值为3,则相机进⾏⼀次软触发,如果要多次软触发,则重复设置“White Balance”属性的Value值为3即可,每设置⼀次,进⾏⼀次软触发。

DirectShow视频采集方案

DirectShow视频采集方案
2.3 DirectShow
流媒体处理技术以其复杂性和技术性一直受到人们的关注。随着网络技术的不断发展,流媒体在网络上得到了广泛地应用。如何能够简单、有效地进行流媒体处理,已成为一个焦点问题。为此,Microsoft推出了DirectShow,DirectShow是Microsoft推出的基于Windows平台的流媒体处理开发包,它与DirectX一起发布。DirectShow对流媒体的捕捉、回放提供了强大的支持,使用它还可以在基于WDM驱动的采集卡上进行数据捕捉。本节将介绍有关DirectShow的相关知识。
while (pEnumPins->Next(1,&pOutpin,NULL)==S_OK)
{
pOutpin->QueryDirection(&pDir);
if (pDir==dir)
{
return pOutpin;
}
}
return 0;
}
用户可以按下面的方式获得某个过滤器的输入、输出引脚。
IPin * pComOut,*pComIn ;
在开发DirectShow应用程序时,通常需要设计一个过滤图表(Filter Graph),向过滤图表中添加相应的过滤器,最后连接过滤器的引脚就完成了功能的设计。例如,实现一个简单的视频预览功能,需要向过滤图表中添加一个视频捕捉源过滤器和一个Video Renderer过滤器,将视频捕捉源过滤器的输出引脚与Video Renderer过滤器的输入引脚相连就可以了。而在程序中只需要按照设计过滤图表的捕捉添加过滤器并连接过滤器引脚就可以了。在连接过滤器引脚时需要注意:只能是输出过滤器引脚与输入过滤器引脚相连,两个输出过滤器或两个输入过滤器引脚是不能相连的。
为了在程序中使用DirectShow,需要单独安装DirectX,当前DirectX的最新版本为9.0,即DirectX9.0,用户可以从Microsoft的官方网站上免费下载。在安装DirectX之后,程序中需要引用“dshow.h”头文件,并导入“Strmiids.lib”库文件和“quartz.lib”库文件才可以使用DirectShow。代码如下:

工业相机安装使用说明书

工业相机安装使用说明书

工业相机安装使用说明书文件版本:V1.2目录1产品简介 (3)2程序的安装 (4)3演示软件的使用方法 (8)3.1菜单栏 (9)3.2工具栏 (9)3.3视频预览区 (11)3.4状态栏 (12)4相机DirectShow接口的使用方法 (13)5相机TWAIN接口的使用方法 (17)在Photoshop中使用TWAIN接口捕获图像 (17)在Scope photo中使用TWAIN接口捕获图像 (19)在Image-Pro Plus中使用TWAIN接口捕获图像 (21)6相机Halcon接口的使用方法 (22)7相机Labview接口的使用方法 (27)8如何使用相机SDK进行二次开发 (29)1产品简介我公司工业相机有如下特点:1,统一的SDK接口。

我公司USB2.0、USB3.0、千兆网、1394接口的CCD、CMOS相机,都使用同一套SDK、演示平台,您无需关心不同型号、接口的相机带来的差异。

2,完美支持一台电脑接多个相机。

用户或者开发人员可以在配置界面中方便修改指定相机的名称,用来区分多相机,相机名称修改后,无论接在哪台电脑、无论是使用DSHOW、TWAIN、还是SDK接口,都会显示为您修改后的名字,您无需再为一台电脑接多个相机难以区分而烦恼。

3,相机支持4组参数保存与加载,同时,支持从文件中加载参数,方便量产。

支持多种不同的参数加载模式,可以按照相机的名称、唯一序列号、或者型号来进行加载,以满足您不同的使用场合需求。

4,提供丰富的图像处理接口,算法关键部分采用硬件加速功能,有效提升图像质量的同时降低CPU占用率。

5,支持多种第三方软件接口。

目前已经支持的接口有DirectShow、TWAIN、Halcon、Labview、OpenCV、OCX。

6,所有相机均支持时间戳功能,能够准确记录图像采集的时间点,录像文件能够准确还原拍摄时的时间。

7,提供中英文两个版本,可动态切换。

8,人性化的相机配置界面。

基于DirectShow视频及图片捕获软件的开发

基于DirectShow视频及图片捕获软件的开发

基于DirectShow视频及图片捕获软件的开发我们知道目前很多工业相机的图像数据采集都是基于DirectShow的,常见的有映美精等。

DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。

DirectShow为多媒体流的捕捉和回放提供了强有力的支持。

运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。

它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒体数据的回放变得轻而易举。

另外,DirectShow还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD的播放,视频的非线性编辑,以及与数字摄像机的数据交换。

更值得一提的是,DirectShow提供的是一种开放式的开发环境,我们可以根据自己的需要定制自己的组件。

笔者使用visual studio 2005 来开发了基于DirectShow的视频捕获软件,并用开发的软件对映美精相机进行了测试。

本软件不但可以实现对相机的视频捕获,而且还可以抓取图像帧。

软件运行时自动搜索所连接的相机,预览后可以对相机参数进行设置。

下面是软件的主界面。

预览视频后可以对视频格式和图像参数进行设置。

开始预览时,捕获的视频是黑白的,我们将颜色空间设置为UYVY即可捕获彩色视频。

下面是捕获的一帧图像,图像质量虽然没有映美精自带的软件效果好,但已经实现了所需各项基本功能,接下来的工作将会进一步提高软件性能。

另外我们还可以捕获视频,点击“捕获视频”按钮,输入要保持的文件名,注意要以.avi后缀结尾,点确定就开始捕获视频。

从我们开发的软件可以看到,映美精的相机能够很好的支持DirectShow的驱动,我们的软件对映美精相机的识别是如此的容易。

接下来我们将继续开发基于其它驱动的图像捕获软件,为最终实现在一个软件中识别各种相机而努力。

directshow教程(新整理)

directshow教程(新整理)

Directshow教程0.11MSDN翻译系列作者:黄丁杰说明:如果有任何问题请联系din-je@。

是本人业余翻译的如果有错误请直接发到我邮箱我会立刻改正,directshow的其他文章我会在以后不断翻译出来。

如果觉得好请帮我作作宣传。

欢迎转载,但是禁止修改。

Directshow起步。

本章主要介绍diirectshow在编写程序时所需的基本概念。

在本章你可以总揽下directshow 技术。

你必须在总体上对本章的编程和媒体有所了解。

本章将介绍。

设置编译环境。

介绍directshow应用程序编程。

如何播放一个文件设置编译环境:你可以编译工程在命令行模式下或者在vs集成环境中头文件所有的directshow应用程序都使用下面的头文件。

Dshow。

H部分directshow接口需要附加的头文件。

这些文件会在接口的注意中给出。

所需的库文件directshow需要如下的库文件strmiidl。

Lib 该库包含CLSIDs和IIDs的接口。

所有的directshow都需要该库。

Quartz。

Lib 该库包含AMGetErrorText函数。

如果你没有调用该函数,该库没有用。

记住在你的编译环境中必须把directx SDK 的头文件库和连接库的目录作为vs优先搜索的路径。

这样可以保证编译的时候用的是最新版本的文件。

介绍directshow应用程序编程本章介绍编写一个directshow程序的基本技术和概念,读完本章你就可以写个你自己的directshow的应用程序了。

滤镜和图像滤镜directshow是由被称作滤镜的东西构成的。

滤镜是一个软件包用来执行对多媒体流的一些操作。

比如directshow的滤镜可以读出一个文件从视频捕捉设备获取视频流解码各种各样的多媒体格式,比如MPEG-1S视频。

传输视频和音频到屏幕和声卡。

滤镜几乎完成视频播放所需要的从输入到输出的所有功能。

比如一个MPEG-1的滤镜。

它可以输入MPEG码流然后输出图像帧用于后续显示在directshow程序中只要执行把滤镜连接在一起就可以了。

directshow中利用samplegrabber捕获摄像头每一帧图像并转为bmp文件

directshow中利用samplegrabber捕获摄像头每一帧图像并转为bmp文件

directshow中利用samplegrabber捕获摄像头每一帧图像并转为bmp文件关于怎样枚举设备、建立Filter Graph等问题,我就不多说了,说也说不清楚,因为我也是才接触DirectShow。

网上这类资料还是很多,百度知道的比我多多了。

这里主要介绍一下自己在学习了StillCap例子之后,实现利用SampleGrabber捕获摄像头每一帧图像的过程。

过程中遇到的印象深刻的问题会在下一篇博文中介绍。

废话不说了,开门见山吧。

大致思路与代码如下:1、从ISampleGrabber实例化一个sample grabber,充当一个Transform Filter[cpp] viewplaincopy?CComPtr<ISampleGrabber>m_pSampleGrabber;2、设置相关参数,将Grabber注册并且加入到m_pGB这个Filter Graph中[cpp] viewplaincopy?//////////////////////////////////////////////////////////////////////////Add SampleGrabber // create a sample grabber // hr =m_pSampleGrabber.CoCreateInstance( CLSID_SampleGrabber ); if( !m_pSampleGrabber ) { MessageBox(NULL, L"Could not create SampleGrabber (is qedit.dll registered?)", L"", MB_OK); return hr; } CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pSampleGrabber ); // force it to connect to video, 24 bit // CMediaType VideoType;VideoType.SetType( &MEDIATYPE_Video ); VideoType.SetSubtype( &MEDIASUBTYPE_RGB24 ); VideoType.SetFormatType(&FORMAT_VideoInfo); hr = m_pSampleGrabber->SetMediaType( &VideoType ); // shouldn't fail if (FAILED(hr)) { MessageBox(NULL, L"不能初始化SampleGrabber媒体类型。

(MatLab、Labview)通过Directshow接口访问相机参数设置方法

(MatLab、Labview)通过Directshow接口访问相机参数设置方法

DirectShow接口访问相机参数设置方法本文档适用于所有适用directshow接口访问相机的程序,例如MATLAB 和Labview的ImaqDx接口、Halcon的Directshow接口等。

MATLAB中,可以通过如下界面设置相机参数:Labview的NIMAX中可以通过如下界面设置相机参数:下面以Labview为例,介绍Labview中如何通过ImaqDx接口访问迈德威视工业相机。

目前,我们提供三种方式,在Labview中访问我们的相机:1.GigeVision接口。

仅我司GigE相机支持该方式访问。

2.直接基于SDK的DLL文件调用的方式。

该方式支持我们所有型号相机。

例程在安装目录的DEMO/LABVIEW/USEDLL文件夹中。

3.通过ImaqDx使用Directshow接口访问相机。

该方式支持我们所有型号相机。

Directshow接口是windows系统上的音视频标准接口,定义了一些预先约定好的协议,但是由于协议定义时间比较早,也没有为工业摄像头考虑参数接口,所以接口的参数配置上,没有像使用我们的SDK那样灵活。

我们针对此问题,做了一些特殊处理,扩展了Dircetshow接口中Camera Atrributes的“White Balance”属性,目前可以该方式进行如下操作:1.设置相机工作模式(连续采集、软触发、硬触发)方法:在Camera Atrributes中,设置“White Balance”属性的Value值●为0,则相机进入连续工作模式;●设置为1,则相机进入软触发工作模式;●设置为2则相机进入硬触发工作模式。

2.执行一次软触发方法:在Camera Atrributes中,设置“White Balance”属性的Value 值为3,则相机进行一次软触发,如果要多次软触发,则重复设置“White Balance”属性的Value值为3即可,每设置一次,进行一次软触发。

C#DirectShow预览摄像头并截图

C#DirectShow预览摄像头并截图

C#DirectShow预览摄像头并截图C# DirectShow预览摄像头并截图,供⼤家参考,具体内容如下本事例通过Windows DirectX Filtergraph ⼀些列管道将电脑所接⼊视频采集设备的视频流播放到制定区域,通过ISampleGrabberCB接⼝的BufferCB回调函数截取图⽚。

⽤此⽅法预览图像cpu占⽤率极低,⽐其其他事件绑定并逐帧显⽰图像性能更佳。

UI布局:代码如下:using System;using System.Drawing;using System.Windows.Forms;using DirectShowLib;using System.Runtime.InteropServices;using Types;using System.Drawing.Imaging;namespace Test{public partial class FormDirect : Form, ISampleGrabberCB{private int _previewWidth = 640;private int _previewHeight = 480;private int _previewStride = 0;private int _previewFPS = 30;private volatile bool isGrab = false;IVideoWindow videoWindow = null;IMediaControl mediaControl = null;IFilterGraph2 graphBuilder = null;ICaptureGraphBuilder2 captureGraphBuilder = null;DsROTEntry rot = null;public FormDirect(){InitializeComponent();}private void button2_Click(object sender, EventArgs e){//截图isGrab = true;}private void button3_Click(object sender, EventArgs e){string button_text = button3.Text;if (button_text.Equals("Start Webcam")){button3.Text = "Stop Webcam";StartCamera();}else{button3.Text = "Start Webcam";StopCamera();}}private void StartCamera(){DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);if (devices.Length == 0){MessageBox.Show("No USB webcam connected");button3.Text = "Start Webcam";return;}else{CaptureVideo(devices[0]);}}private void StopCamera(){button3.Text = "Start Webcam";CloseInterfaces();}public void CaptureVideo(DsDevice device){pictureBox1.Image = null;int hr = 0;IBaseFilter sourceFilter = null;ISampleGrabber sampleGrabber = null;try{// Get DirectShow interfacesGetInterfaces();// Attach the filter graph to the capture graphhr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);DsError.ThrowExceptionForHR(hr);// Use the system device enumerator and class enumerator to find// a video capture/preview device, such as a desktop USB video camera.sourceFilter = SelectCaptureDevice(device);// Add Capture filter to graph.hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");DsError.ThrowExceptionForHR(hr);// Initialize SampleGrabber.sampleGrabber = new SampleGrabber() as ISampleGrabber;// Configure SampleGrabber. Add preview callback.ConfigureSampleGrabber(sampleGrabber);// Add SampleGrabber to graph.hr = this.graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "Frame Callback");DsError.ThrowExceptionForHR(hr);// Configure preview settings.SetConfigParams(this.captureGraphBuilder, sourceFilter, _previewFPS, _previewWidth, _previewHeight);// Render the previewhr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, (sampleGrabber as IBaseFilter),null);DsError.ThrowExceptionForHR(hr);SaveSizeInfo(sampleGrabber);// Set video window style and positionSetupVideoWindow();// Add our graph to the running object table, which will allow// the GraphEdit application to "spy" on our graphrot = new DsROTEntry(this.graphBuilder);// Start previewing video datahr = this.mediaControl.Run();DsError.ThrowExceptionForHR(hr);}catch{MessageBox.Show("An unrecoverable error has occurred.");}finally{if (sourceFilter != null){Marshal.ReleaseComObject(sourceFilter);sourceFilter = null;}if (sampleGrabber != null){Marshal.ReleaseComObject(sampleGrabber);sampleGrabber = null;}}}public void CaptureVideo(){pictureBox1.Image = null;int hr = 0;IBaseFilter sourceFilter = null;ISampleGrabber sampleGrabber = null;try{// Get DirectShow interfacesGetInterfaces();// Attach the filter graph to the capture graphhr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);DsError.ThrowExceptionForHR(hr);// Use the system device enumerator and class enumerator to find// a video capture/preview device, such as a desktop USB video camera.sourceFilter = FindCaptureDevice();// Add Capture filter to graph.hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture");DsError.ThrowExceptionForHR(hr);// Initialize SampleGrabber.sampleGrabber = new SampleGrabber() as ISampleGrabber;// Configure SampleGrabber. Add preview callback.ConfigureSampleGrabber(sampleGrabber);// Add SampleGrabber to graph.hr = this.graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "Frame Callback");DsError.ThrowExceptionForHR(hr);// Configure preview settings.SetConfigParams(this.captureGraphBuilder, sourceFilter, _previewFPS, _previewWidth, _previewHeight);// Render the previewhr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, (sampleGrabber as IBaseFilter),null); DsError.ThrowExceptionForHR(hr);SaveSizeInfo(sampleGrabber);// Set video window style and positionSetupVideoWindow();// Add our graph to the running object table, which will allow// the GraphEdit application to "spy" on our graphrot = new DsROTEntry(this.graphBuilder);// Start previewing video datahr = this.mediaControl.Run();DsError.ThrowExceptionForHR(hr);catch{MessageBox.Show("An unrecoverable error has occurred.");}finally{if (sourceFilter != null){Marshal.ReleaseComObject(sourceFilter);sourceFilter = null;}if (sampleGrabber != null){Marshal.ReleaseComObject(sampleGrabber);sampleGrabber = null;}}}public IBaseFilter SelectCaptureDevice(DsDevice device){object source = null;Guid iid = typeof(IBaseFilter).GUID;device.Mon.BindToObject(null, null, ref iid, out source);return (IBaseFilter)source;}public IBaseFilter FindCaptureDevice(){int hr = 0;#if USING_NET11UCOMIEnumMoniker classEnum = null;UCOMIMoniker[] moniker = new UCOMIMoniker[1];#elseIEnumMoniker classEnum = null;IMoniker[] moniker = new IMoniker[1];#endifobject source = null;// Create the system device enumeratorICreateDevEnum devEnum = (ICreateDevEnum)new CreateDevEnum();// Create an enumerator for the video capture deviceshr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);DsError.ThrowExceptionForHR(hr);// The device enumerator is no more neededMarshal.ReleaseComObject(devEnum);// If there are no enumerators for the requested type, then// CreateClassEnumerator will succeed, but classEnum will be NULL.if (classEnum == null){throw new ApplicationException("No video capture device was detected.\r\n\r\n" +"This sample requires a video capture device, such as a USB WebCam,\r\n" + "to be installed and working properly. The sample will now close.");}// Use the first video capture device on the device list.// Note that if the Next() call succeeds but there are no monikers,// it will return 1 (S_FALSE) (which is not a failure). Therefore, we// check that the return code is 0 (S_OK).#if USING_NET11int i;if (classEnum.Next (moniker.Length, moniker, IntPtr.Zero) == 0)#elseif (classEnum.Next(moniker.Length, moniker, IntPtr.Zero) == 0)#endif{// Bind Moniker to a filter objectGuid iid = typeof(IBaseFilter).GUID;moniker[0].BindToObject(null, null, ref iid, out source);}else{throw new ApplicationException("Unable to access video capture device!");}// Release COM objectsMarshal.ReleaseComObject(moniker[0]);Marshal.ReleaseComObject(classEnum);// An exception is thrown if cast failreturn (IBaseFilter)source;public void GetInterfaces(){int hr = 0;// An exception is thrown if cast failthis.graphBuilder = (IFilterGraph2)new FilterGraph();this.captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();this.mediaControl = (IMediaControl)this.graphBuilder;this.videoWindow = (IVideoWindow)this.graphBuilder;DsError.ThrowExceptionForHR(hr);}public void CloseInterfaces(){if (mediaControl != null){int hr = mediaControl.StopWhenReady();DsError.ThrowExceptionForHR(hr);}if (videoWindow != null){videoWindow.put_Visible(OABool.False);videoWindow.put_Owner(IntPtr.Zero);}// Remove filter graph from the running object table.if (rot != null){rot.Dispose();rot = null;}// Release DirectShow interfaces.Marshal.ReleaseComObject(this.mediaControl); this.mediaControl = null;Marshal.ReleaseComObject(this.videoWindow); this.videoWindow = null;Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;Marshal.ReleaseComObject(this.captureGraphBuilder); this.captureGraphBuilder = null;}public void SetupVideoWindow(){int hr = 0;// Set the video window to be a child of the PictureBoxhr = this.videoWindow.put_Owner(pictureBox1.Handle);DsError.ThrowExceptionForHR(hr);hr = this.videoWindow.put_WindowStyle(WindowStyle.Child);DsError.ThrowExceptionForHR(hr);// Make the video window visible, now that it is properly positionedhr = this.videoWindow.put_Visible(OABool.True);DsError.ThrowExceptionForHR(hr);// Set the video positionRectangle rc = pictureBox1.ClientRectangle;hr = videoWindow.SetWindowPosition(0, 0, _previewWidth, _previewHeight);DsError.ThrowExceptionForHR(hr);}private void SetConfigParams(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight) {int hr;object config;AMMediaType mediaType;// Find the stream config interfacehr = capGraph.FindInterface(PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out config);IAMStreamConfig videoStreamConfig = config as IAMStreamConfig;if (videoStreamConfig == null){throw new Exception("Failed to get IAMStreamConfig");}// Get the existing format blockhr = videoStreamConfig.GetFormat(out mediaType);DsError.ThrowExceptionForHR(hr);// copy out the videoinfoheaderVideoInfoHeader videoInfoHeader = new VideoInfoHeader();Marshal.PtrToStructure(mediaType.formatPtr, videoInfoHeader);// if overriding the framerate, set the frame rateif (iFrameRate > 0){videoInfoHeader.AvgTimePerFrame = 10000000 / iFrameRate;}// if overriding the width, set the widthif (iWidth > 0){videoInfoHeader.BmiHeader.Width = iWidth;}// if overriding the Height, set the Heightif (iHeight > 0){videoInfoHeader.BmiHeader.Height = iHeight;}// Copy the media structure backMarshal.StructureToPtr(videoInfoHeader, mediaType.formatPtr, false);// Set the new formathr = videoStreamConfig.SetFormat(mediaType);DsError.ThrowExceptionForHR(hr);DsUtils.FreeAMMediaType(mediaType);mediaType = null;}private void SaveSizeInfo(ISampleGrabber sampleGrabber){int hr;// Get the media type from the SampleGrabberAMMediaType media = new AMMediaType();hr = sampleGrabber.GetConnectedMediaType(media);DsError.ThrowExceptionForHR(hr);if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero)){throw new NotSupportedException("Unknown Grabber Media Format");}// Grab the size infoVideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); _previewStride = _previewWidth * (videoInfoHeader.BmiHeader.BitCount / 8);DsUtils.FreeAMMediaType(media);media = null;}private void ConfigureSampleGrabber(ISampleGrabber sampleGrabber){AMMediaType media;int hr;// Set the media type to Video/RBG24media = new AMMediaType();media.majorType = MediaType.Video;media.subType = MediaSubType.RGB24;media.formatType = FormatType.VideoInfo;hr = sampleGrabber.SetMediaType(media);DsError.ThrowExceptionForHR(hr);DsUtils.FreeAMMediaType(media);media = null;hr = sampleGrabber.SetCallback(this, 1);DsError.ThrowExceptionForHR(hr);}public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen){if (isGrab){Bitmap v = new Bitmap(_previewWidth, _previewHeight, _previewStride,PixelFormat.Format24bppRgb, pBuffer);//v.RotateFlip(RotateFlipType.Rotate180FlipX);v.RotateFlip(RotateFlipType.Rotate90FlipX);this.BeginInvoke((MethodInvoker)delegate{pictureBox2.BackgroundImage = v;isGrab = false;});}return 0;}public int SampleCB(double SampleTime, IMediaSample pSample){//throw new NotImplementedException();return 0;}}}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

VC+DirectShow对视频进行图片处理(转)

VC+DirectShow对视频进行图片处理(转)

VC+DirectShow对视频进行图片处理(转)现在的图像越来越花巧了,有浮雕、马赛克、相框等特效,看得人眼花缭乱。

本来图像特效没什么稀奇的,在PhotoShop等图像处理软件中我们早已见得多了,不过用在视频上就令人感觉有点神奇。

我一直都想拥有这些效果,但我的摄像头是很早就买到的,没福气奢望驱动程序给它带来的全新精彩。

刚好我学习DirectShow有一段时间了,既为了挑战自己(我从未写过令自己感到满意的程序),也为了检验学习成果,我就下了决心用DirectShow实现这些效果。

几经努力,终于有了一些成绩,我完成了其中一些效果,并发现程序可以用在DirectShow支持的影音文件上,又自己把它应用到D3D中去,感觉还不错。

先看看效果吧,以激励斗志。

我是对着摄像头广告中的效果图来做程序的,我怕编程的热情像以前那样很快冷却,只留下一堆乱糟糟的代码,我需要它来不断兴奋被代码搞得昏头转向的大脑。

(图一:几种效果)(图二:D3D中的摄像展示)编程的思路是这样的:写一个DirectShow的VideoRenderer Filter用于实时获取图像,之后在用DirectShow连接并使用摄像头、播放视频时用上该Filter,这样就可以实时处理视频的图片并进行显示了。

由于要用到DirectShow,我想在这里说一些关于DirectShow的初级知识,初学或没学过DirectShow的朋友就请耐下性子来听我这个初学者罗嗦一阵子(要学DirectShow的朋友可以看天极的DirectShow相关文章,介绍很详细)。

在新版的DX9 SDK中已看不到DirectShow的影子了(DirectShow发展到了尽头?),不过DirectShow还可用,而且相当有用。

听说自带有DX8 SDK开发文件,但我仍希望您能找到DX8 SDK和VC6。

DX8 SDK帮助文件对DirectShow详细的说明和SDK丰富的DirectShow例子对DirectShow开发是大有裨益的。

浅谈DirectShow技术捕获视频流中帧图像

浅谈DirectShow技术捕获视频流中帧图像

浅谈DirectShow 技术捕获视频流中帧图像肖长健(江苏联合职业技术学院盐城生物工程分院,江苏 盐城 224731)摘 要:利用微软公司提供 DirectShow 接口技术,实现了多媒体文件或视频流中视频帧图像的捕获,并提取出有用的图 像帧信息。

关键词:DirectS how 技术;filter ;视频流;视频帧图像捕获Brief T alk on Capturing Images from Video Streams by DirectShow TechnologyXIAO Chan g-ji an(Yancheng Biology Engineering High School, Jiangsu Union Technical Institute, Yancheng, Jiangsu 224731, China )Abstract : Making use of DirectShow interface technology provided by Microsoft C orporation, the capturing video images from multimedia files or video streams is realized, and useful image frames information is extracted. Key words :DirectShow technolog y ;filter ;video streams ;video images capture0 引言本文以 Direct Show 技术为基础,通过对媒体文件或多媒体 流中的视频流的处理,从多媒体文件视频流中捕获视频帧图像,提取出所需要的最好、最有价值的图像帧信息。

利用 Direct Sho w 技术从视频流中捕获帧图像,捕获精度可达到 1 帧。

1 DirectShowD ir ec t X M e d i a 是微软公司发布的专用于开发多媒体应用的 程 序 接 口 ,包 括 D ir ec t A n i m a ti on 、D ir ec t Sho w 、M e d i a P l a y e rC on tr o l 、D ir ec t X T r a n s f o r m 和D ir ec t 3D R e t a i n e d M od e 。

DirectShow获取一张图片

DirectShow获取一张图片

DirectShow:图片的抓取 zz在播放媒体文件的过程中,有一个很有用的功能,就是在当前播放的位置抓取图,实现这种图片抓取功能的方法很多,我们这里只介绍常用的两种。

第1种方法最简单,它使用1BasicVideo::GetCurrentImage接口方法,代码如下。

boolSnapshotBitmap(IBasicVideo*pBa8icVideo,ê? constchar*OutFile) if (pBasicVldeo){long bitmapSize=0;ê?//首先获得图像大小if(SUCCEEDED(pEasicVidee->GetcurrentImage(&bitmapSize,ê?0))){bool pass=false;ê?//分¤?配?图ª?像?帧?内¨²存ä?unsignedchar*buffer=newunsignedchar[bitmapSize];//获?取¨?图ª?像?帧?数ºy据Yif(SUCCEEDED(pBasicVideo->GetCurrentImage(&bitmapSize,(long*)buffer)) ){BITMAPFILEHEADER hdr;ê?LPBITMAPINFOHEADER ipbi;ê?ipbi=(LPBITMAPINFOHEADER)buffer;ê?int nColors=1<<ipbi->biBitCount;ê?if(nColors>256)//always is”¡ÀBM”¡Àhdr.bfType =((WORD)(‘?M’¡¥<<8)|’¡¥B’¡¥);ê?hdr.ê?bfSize =bitmapSize+sizeof(hdr);ê?hdr.ê?bfReservedl =0;hdr.ê?bfReserved2 =0;ê?hdr.ê?bfOffBits =(DWORD)(sizeof(BITMAPFILEHEADER)+lpbi->biSize+nColors*sizeof(RGBQUAD));CFilebitmapFile(outFile,ê?CFile:êo:êomodeReadWrite |CFile:êo:êomodeCreate | CFile:êo:êotypeBinary);ê?//写¡ä入¨?位?图ª?文?件t头ª¡¤bitmapFile.ê?Write{&hdr,ê?sizeof【?BITMApFILEHEADER));//写¡ä入¨?图ª?像?帧?数ºy据Y(包㨹括¤¡§BITMAPINFOHEADER信?息¡é)bitmapFile.ê?Write(buffer,ê?bitmapSize);ê?bitmapFile.ê?Close();ê?pas8=true;}delete[]burfer;ê?return Pass;}returnfalse ;值得注意的是,IBasieVideo接口应该从Filter Graph Manager上获得,但真正实现在Renderer Filter 上。

京航科技 USB2.0工业相机快速指南说明书

京航科技 USB2.0工业相机快速指南说明书

京航科技USB2.0工业相机快速指南*************相机型号产品外观f系列m系列s系列附加特性R近红外NIR红外增强E外触发S CS接口USB线 1.5米3米5米触发线2米其它米资料光盘一硬件连接f系列相机支持C口和CS口工业镜头。

图1.1图1.2m系列或s系列相机只支持C口镜头。

图1.3镜头上有一般有对焦(调清晰度)和光圈(调亮度)旋钮。

安装好镜头后通过USB线将相机连接到电脑,台式电脑请使用后置的电脑主板上的USB口保证高速稳定的数据传输。

外触发连接,f系列请参考应用手册AN021,s系列参考应用手册AN041。

二驱动安装驱动支持Windows XP,Windows7,8,10(64位和32位),驱动包含数字签名,满足Windows8/10系统的安全性要求。

从光盘中或者在如下网址下载工业相机软件。

/download/软件包含驱动程序usbVideo和软件SDK。

图2.1按照安装说明安装,usbVideo_setup 安装过程中将自动安装相机的驱动程序,完毕后将在桌面创建3个快捷方式。

usbVideo为相机配套的一个演示软件,支持本系列的全部相机,DShowManager主要用于注册DirectShow,以供第三方软件如Halcon,Labview,QQ等访问到相机。

JHAmcap用于测试DrictShow是否注册成功,可以预览DirectShow设备图像。

sdk_setup将安装SDK和示例到计算机,将在桌面创建“SDK”的快捷方式。

三软件使用1usbVideo保存图片,先在’设置’(Setting)->’捕获’(Capture) ->’保存路径’(Save Path)选择存储目录,然后在工具栏点击’保存’(Save)保存图片到指定目录。

图3.1‘适应窗口’(Fit Screen)可以显示相机拍摄的全部图像范围,2DShowManager如果使用第三方软件(Halcon,Labview等),需要注册Directshow。

如何使用C#制作播放器技术方法及代码

如何使用C#制作播放器技术方法及代码

如何使用C#制作播放器技术方法及代码要使C# 代码引用COM 对象和接口,需要在C# 内部版本中包含COM 接口的.NET 框架定义。

完成此操作的最简单方法是使用TlbImp.exe(类型库导入程序),它是一个包括在.NET 框架SDK 中的命令行工具。

TlbImp 将COM 类型库转换为.NET 框架元数据,从而有效地创建一个可以从任何托管语言调用的托管包装。

用TlbImp 创建的.NET 框架元数据可以通过/R 编译器选项包括在C# 内部版本中。

如果使用Visual Studio 开发环境,则只需添加对COM 类型库的引用,将为您自动完成此转换。

例如,我们要播放当前目录下的demo.avi文件,需要用到包含在位于Windows 系统目录中的Quartz.dll 中的媒体播放机。

(c:\winnt\system32\quartz.dll)。

可在命令行中运行TlbImp文件(C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\Tlbimp.exe)tlbimp c:\windows\system32\quartz.dll /out:QuartzTypeLib.dll得到的新程序集放到目录C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin下面请注意,得到的DLL 需要命名为QuartzTypeLib,以便.NET 框架可以在运行时正确加载包含类型。

生成程序时使用C# 编译器选项/R 以包含QuartzTypeLib.dll 文件;如果使用Visual Studio 开发环境,直接添加引用即可(using QuartzTypeLib)。

然后就可以使用此程序显示影片了。

具体编写代码时,用到了RenderFile 和Run 方法。

例:private void menuItemOpen_Click(object sender, System.EventArgs e){FilgraphManager m_FilGraphManager = null;IBasicAudio m_BasicAudio = null;IVideoWindow m_VideoWindow = null;IMediaEvent m_MediaEvent = null;IMediaEventEx m_MediaEventEx = null;IMediaPosition m_MediaPosition = null;IMediaControl m_MediaControl = null;OpenFileDialog OpenDialog = new OpenFileDialog();OpenDialog.Filter = "Media Files|*.mpg;*.avi;*.wma;*.mov;*.wav;*.mp2;*.mp3|All Files|*.*"; //本例用对话框读入要显示的影片文件名if (DialogResult.OK == OpenDialog.ShowDialog()){m_FilGraphManager = new FilgraphManager();m_FilGraphManager.RenderFile(OpenDialog.FileName);m_BasicAudio = m_FilGraphManager as IBasicAudio ;try{m_VideoWindow = m_FilGraphManager as IVideoWindow;m_VideoWindow.Owner = (int) panel1.Handle;m_VideoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;//此设置可以不显示播放器的title,使播放器像嵌在窗体中。

VC+DirectShow对视频进行图片处理

VC+DirectShow对视频进行图片处理

VC+DirectShow对视频进行图片处理之四图像处理在我的程序中图像处理函数是作为DirectShow 封装类一部分的,我认为这样便于移动和使用。

没有连着上面的DirectShow 类而另外写标题是因为我觉得有必要把它提到重要位置。

在程序完善阶段您的工作基本就在这里了,除了花心思构造D3D环境外几乎所有效果都要在这里实现,水平高下也体现于此。

在网上可以找到很多图像特效的代码和解说,我结合编程过程再说说。

1. 访问缓冲区的麻烦。

这是最麻烦的,二维图像在这里以一个连续的一维缓冲区呈现,您要靠一个指针去访问它,怎么办呢?先弄懂Pitch,例如32bit ARGB 图像,每个象素就占用4 Byte 内存空间(1 Byte = 8 bit),对于宽度为20 像素的图像,它的Pitch 就是80 Byte,即每一行占用的内存。

按x 、y 坐标就有如下公式(按Byte 计算):B:y * Pitch + x * 4G:y * Pitch + x * 4 + 1R:y * Pitch + x * 4 + 2A:y * Pitch + x * 4 + 3可以看出在内存中是按BGRA 存储的,我不明白为什么这样,可能可以从计算机的内存存储方式找到答案。

上述公式计算多,效率较低,在实际使用中应适时作有益的改变。

2. 浮雕。

到目前为止我在网上找到的几篇文章都说把一点的值减去其右下角点的值再加上128就行了。

为什么要减去右下角的点呢?为什么要加上128呢?原来浮雕是要把图像的变化部分突出显示出来,而把相同部分淡化,所以用一点减去其邻域任意点都可以达到这个目的,倒也不一定是右下角的点,包围着它的八个点都可以,甚至可以选择减去更远的点,只要规则明确、效果好就行。

在相减后点的RGB 值都减小了,大多接近黑色,黑乎乎一片的看不出什么来,一点也不像浮雕,所以要给它们都增加一个相同的亮度,通常加上128,其它的值,例如64、100,当然也行,一切都以实际效果为准。

DirectShow编程实现摄像头视频捕捉

DirectShow编程实现摄像头视频捕捉
第二步、调用RenderStream依次把Still pin、Sample Grabber和系统默认Renderer Filter连接起来。
第三步、配置Sample Grabber以捕获数据。
视频捕捉类CCaptureVideo的具体实现
// CCaptureVideo视频捕捉类头文件/////////////////////////////////////////////////////////////////////#if !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)#define AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_/////////////////////////////////////////////////////////////////////// CaptureVideo.h : header file/////////////////////////////////////////////////////////////////////#if _MSC_VER &gt; 1000#pragma once#endif // _MSC_VER &gt; 1000#include &lt;atlbase.h&gt;#include &lt;windows.h&gt;#include &lt;dshow.h&gt;#ifndef SAFE_RELEASE#define SAFE_RELEASE( x ) /if ( NULL != x ) /{ /x-&gt;Release( )

DirectShow流媒体数据的采集及图片的捕获

DirectShow流媒体数据的采集及图片的捕获

DirectShow流媒体数据的采集及图片的捕获DirectShow流媒体数据的采集及图片的捕获建议你用DirectShow它可以帮你从视频采集设备中取得数据,并通过Sample Grabber过滤器进行抓图DirectShow流媒体数据的采集及图片的捕获用DirectShow来使用摄像头,一般要求摄像头的驱动是WDM 格式的,当然,一些比较老的驱动格式DirectShow也可支持。

在DirectShow中,有一个Sample Grabber过滤器,它是一个可以被插入流的过滤器,它有自己的缓冲,存放采样。

我们就可以用它来从一个视频文件中简单的扑获一桢。

DirectShow通过图形过滤管理器(Filter Graph Manager)来与上层应用程序和下层的驱动进行联系。

DirectShow通过捕获过滤器(Capture Filter)来支持对摄像头的捕获,一个捕获过滤器有多个插口(pin),其中的预览(preview)插口可用来进行显示祯图象。

1、创建图形过滤管理器Filter Graph如上面原理所述,首先要创建Filter Graph:CComPtr< IGraphBuilder > m_pGraph;hr=m_pGraph.CoCreateInstance( CLSID_FilterGraph );2、连接设备还要创建系统枚举器组件对象:CComPtr<ICreateDevEnum>pCreateDevEnum;pCreateDevEnum.CoCreateInstance( CLSID_ SystemDeviceEnum );然后使用接口方法CreateClassEnumerator ()为指定的Filter注册类型目录创建一个枚举器,并获得IenumMoniker接口:CComPtr< IEnumMoniker > pEm;pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &p Em, 0 );接着在调用BindT oObject()以后,可以将设备标识生成一个DirectShow Filter,将其加到Filter Graph中就可以参与工作了。

DShow中实现抓图的几种方法

DShow中实现抓图的几种方法

DShow中实现抓图的几种方法1.加入Sample Grabber Filter当我们加入Sample Grabber Filter的时候,我们可以直接调用其接口(interface)ISampleGrabber。

该接口可以获取经过该Filter的单独的Media Samples。

详情请参见DXSDK。

1.1 派生出自己的Sample Grabber从ISampleGrabberCB中派生出自己的类,然后实现其虚函数,详情请参见SDK中的示例程序(DXSDKROOT\Samples\C++\DirectShow\Editing\GrabBitmaps)。

1.2 直接调用Sample Grabber Filter的接口如果我们在播放的过程中动态的加入Filter的话,操作和效率都不乐观。

所以我采用下面的方法:该方法传递的是时间,不是在播放的时候动态加入Filter然后截图,而是另外打开源文件进行操作。

A)。

申明以下接口:A)。

申明以下接口:#001 IGraphBuilder *pGraph = NULL; //for graph builder #002 IMediaControl *pControl = NULL; //media control #003 IMediaSeeking *pSeeking = NULL; //media seeking #004 IMediaEventEx *pEvent = NULL; //media envent#005 IBaseFilter *pNullFilter =NULL;//for holding the Sample grabber FilterB)。

初始化接口:#001 JIF(CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC,#002 IID_IGraphBuilder, (void **)&pGraph));#003#004 JIF(CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC,#005 IID_IBaseFilter, (void**)&pNullFilter)); #006 JIF(pGraph->QueryInterface(IID_IMediaControl,(void**)&pControl));#007 JIF(pGraph->QueryInterface(IID_IMediaSeeking, (void**)&pSeeking));#008 JIF(pGraph->QueryInterface(IID_IMediaEvent, (void**)&pEvent));C)。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

DirectShow:图片的抓取 zz在播放媒体文件的过程中,有一个很有用的功能,就是在当前播放的位置抓取图,实现这种图片抓取功能的方法很多,我们这里只介绍常用的两种。

第1种方法最简单,它使用1BasicVideo::GetCurrentImage接口方法,代码如下。

boolSnapshotBitmap(IBasicVideo*pBa8icVideo,ê? constchar*OutFile) if (pBasicVldeo){long bitmapSize=0;ê?//首先获得图像大小if(SUCCEEDED(pEasicVidee->GetcurrentImage(&bitmapSize,ê?0))){bool pass=false;ê?//分¤?配?图ª?像?帧?内¨²存ä?unsignedchar*buffer=newunsignedchar[bitmapSize];//获?取¨?图ª?像?帧?数ºy据Yif(SUCCEEDED(pBasicVideo->GetCurrentImage(&bitmapSize,(long*)buffer)) ){BITMAPFILEHEADER hdr;ê?LPBITMAPINFOHEADER ipbi;ê?ipbi=(LPBITMAPINFOHEADER)buffer;ê?int nColors=1<<ipbi->biBitCount;ê?if(nColors>256)//always is”¡ÀBM”¡Àhdr.bfType =((WORD)(‘?M’¡¥<<8)|’¡¥B’¡¥);ê?hdr.ê?bfSize =bitmapSize+sizeof(hdr);ê?hdr.ê?bfReservedl =0;hdr.ê?bfReserved2 =0;ê?hdr.ê?bfOffBits =(DWORD)(sizeof(BITMAPFILEHEADER)+lpbi->biSize+nColors*sizeof(RGBQUAD));CFilebitmapFile(outFile,ê?CFile:êo:êomodeReadWrite |CFile:êo:êomodeCreate | CFile:êo:êotypeBinary);ê?//写¡ä入¨?位?图ª?文?件t头ª¡¤bitmapFile.ê?Write{&hdr,ê?sizeof【?BITMApFILEHEADER));//写¡ä入¨?图ª?像?帧?数ºy据Y(包㨹括¤¡§BITMAPINFOHEADER信?息¡é)bitmapFile.ê?Write(buffer,ê?bitmapSize);ê?bitmapFile.ê?Close();ê?pas8=true;}delete[]burfer;ê?return Pass;}returnfalse ;值得注意的是,IBasieVideo接口应该从Filter Graph Manager上获得,但真正实现在Renderer Filter 上。

如果我们使用的是传统的Video Renderer,那么使用GetCurrentlmage 抓图将是不可靠的。

因为如果Video Renderer使用了DirectDraw加速,这个函数调用会失败;而且调用这个函数,Video Renderer必须处于暂停状态。

但如果我们使用的是VMR,则没有上述这些限制。

第2种方法比较复杂.它使用Sample Grabber Filter。

它其实是一个Trans-In-Place Filter,在SDK安装目录下的Samples\C++\DirectShow’Filters\Grabber提供了源代码。

实际上,Sample Grabber可以抓取任何类型的Sample。

但在这里,我们只介绍使用它抓取视频帧的方法。

步骤如下:(1)创建Sample Grabber,并将之加入到Filter Graph中。

//Create the Sample GrabberIBaseFilter*pGrabberF=NULL;hr=CoCreateInstanee(CLSID_SampleGrabber,NULL,CLSCTX_INPROC_SERVER,IID IBaseFilter, (void**)&pGrabberF);if(FAILED(hr)){//Return an error}hr=pGraph->AddFilter(pGrabberF,L"Sample Grabber");if(FAILED(hr){//Return an error}ISampleGrabber*pGrabber=NULL;pGrabberF->QueryInterface(IID_ISampleGrabber,(void**)&pGrabber);(2)给SampleGrabber设置Pin上连接用的媒体类型。

如果我们想抓取24位的RGB图片,如下设置媒体类型:AM_MEDIA_TYPE mt;ZeroMemorY(&mt,sizeof(AM_MEDIA_TYPE));mt.malOrtype=MEDIATYPE Video;mt.subtype=ME:DIASUBTYPE RGB24;hr=pGrabber->SetMediaType(&mt);也可以根据当前显示器的配置来设置Sample Grabber接受的RGB类型,代码如下://Find the current bit depthHDC hdc=GetDC(NULL);int iBitDepth=GetDeviceCaps(hdc, BITSPIXEL);ReleaseDC(NULL,hdc);//Set the media typemt.maJortype=MEDIATYPE Video;switch(iBitDepth){Case 8:mt.subtype=MEDIASUBTYPE RGB8 ;break;case 1 6:mt.subtype=MEDIASUBTYPE_RGB555;break;case 24:mt.subtype=MEDIASUBTYPE_RGB24;break;case 32:mt.subtype=MEDIASUBTYPE_RGB32;break;default:return E_FAIL;}hr=pGrabber->SetMediaType(&mt);(3)完成FilterGraph的构建。

因为Sample Grabber上已经设置了一个媒体类型,则其他Filter必须以这种媒才能与Sample Grabber相连。

我们可以使用DimctShow的“智能连接”机制,来个Fitler Graph的创建过程,代码如下。

IBaseFiiter*pSrc;hr=pGraph->AddSourceFilter(wszFileName, L"Source", &pSrc};if(FAILED(hr)){//Return an error code}hr=ConnectFiiters(pGraph,pSrc,pGrabberF);其中,ConnectFilters是我们在5.3节中介绍的自定义函数。

如果我们只是想抓图(不需要对视频预览),则Sample Grabber后面可以连接一个Null Renderer Filter(它的CLSID为CLSID NullRenderer)。

如果要Filter Graph中的数据流以最快的速度传送,则Filter Graph不要使用参考时钟(调用IMediaFitter::SetSyncSource,参数为NULL)。

(4)运行FilterGraph。

Sample Grabber可以有如下两种工作模式:缓冲模式将输入的Sample进行缓存后,再往下传送。

回调模式当有输入的Sample时,调用应用程序设置进来的回调函数。

因为回调模式会影响整个Filter Graph的效率,并且容易引起死锁,所以我们推荐使用缓冲模式。

另外,我们可以设置 ISampleGrabber::SetOneShot,使得Sample Grabber获取一个Sample以后,就让FilterGraph停止,代码如下://Set one-shot mode and buffering.hr=pGrabber->SetOneShot(TRUE);hr=pGrabber->SetBufferSamples(TRUE);pControl->Run();//Run the graph.pEvent->WaitForCompletion(INFINITE,&evCode),//Wait till it’s done.(5)获取抓到的Sample数据。

缓冲模式下,我们可以调用ISampleGrabber::GetCurrentBuffer来获取Sample数据,代码如下://Find the required buffer sizelong cbBuffer=0;hr=pGrabber->GetCurrentBuffer(&cbBuffer,NULL);char*pBuffer=new char[cbBuffer];if(!pBuffer)//Out of memory.Return an error code}hr=pGrabber->GetCurrentBuffer(&cbBuffer,(long*)pBuffer);我们也可以将获取的数据使用GDI函数显示出来,代码如下:AM_MEDIA_TYPE mt;hr=pGrabber->GetConnectedMediaType(&rot);if(FAILED(hr)){//Return err05 code}//Examine the format blockVIDEOINFOHEADER*pVih;if((mt.formattype==FORMAT_VideoInfo)&&(mt.cbFormat>=sizeof(VIDEOINFOHEADER))&&(mt.pbFormat!=NULL))pVih={vIDEOINFOHEADER*)mt·pbFormat;}else{//Wrong format.Free the format block and return an error‘FreeMedlaType(mt);return VFW_E_INVALIDMEDIATYPE;//youcan use the media type to access the BITMAPINFOHEAFRE information,//For example,the following code draws the bitmap using GDISetDIBitsToDevice(hdc,0,0,pVih->bmiHeader.biWidth,pVih->bmiHeader.biHeight,O, O,0,pVih->bmiHeader.biHeight,pBuffer,(BITMAPINFO*)&pVih->bmiHeader,DIB RGB COLORS),//Free the format block when you are done:FreeMediaType(mt);从摄像头流中捕捉一张图片zzAtomictry(天影))关键字:视频捕获拍照 ISampleGrabber函数说明HRESULT StartDisplay(HWND hwnd);HRESULT BuilderGraph()HRESULT SnapStill()BOOL SetFormat(ICaptureGraphBuilder2* pBuilder, IBaseFilter* pCap, long lWidth, long lHeight, unsigned short iColorBit, __int64 iRate )HRESULT StartDisplay(HWND hwnd){HRESULT hr = S_OK;hr = BuilderGraph();if(hr==S_FALSE) return S_FALSE;//Create Display WindowspSendWindow->put_Owner((OAHWND)hwnd);pSendWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);pSendWindow->SetWindowPosition(0,0,250,250); pSendWindow->put_Visible(OATRUE);hr = pGrabber->SetOneShot(FALSE);hr = pGrabber->SetBufferSamples(TRUE);//Begin displayhr=pSendControl->Run();Sleep(500);SnapStill();return S_OK;}HRESULT BuilderGraph(){HRESULT hr=S_OK;pSendGraph=NULL;pCaputerFilter=NULL;pCaputerBuilder=NULL;pSendWindow=NULL;pSendControl=NULL;pSendEvent=NULL;pGrabberSample = NULL;//1.Builder Filter Graphhr=CoCreateInstance((REFCLSID)CLSID_FilterGraph,NULL, CLSCTX_INPROC_SERVER,(REFIID)IID_IGraphBuilder,(void**)&pSendGraph);if(FAILED(hr)) return S_FALSE;//2.Builder Caputer Filterhr=CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL, CLSCTX_INPROC,IID_ICaptureGraphBuilder2,(void**)&pCaputerBuilder);if(FAILED(hr)) return S_FALSE;//3.Builder SampleGrabber Filterhr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pGrabberSample);if(FAILED(hr)) return S_FALSE;hr=pCaputerBuilder->SetFiltergraph(pSendGraph);if(FAILED(hr))return S_FALSE;//Find Caputer Filterhr=FindCaputerDevice();if(FAILED(hr)) {SAFE_RELEASE(pCaputerBuilder);SAFE_RELEASE(pSendGraph);return S_FALSE;}hr =pSendGraph->AddFilter(pNetSend,NULL);hr =pSendGraph->AddFilter(pCaputerFilter,L"Caputer Filter");hr =pSendGraph->AddFilter(pCompressor,L"Compressor Filter");hr = pSendGraph->AddFilter(pGrabberSample, L"Sample Grabber");hr=pSendGraph->QueryInterface(IID_IMediaControl,(void**)&pSendControl );if(FAILED(hr)) return S_FALSE;hr=pSendGraph->QueryInterface(IID_IVideoWindow,(void**)&pSendWindow); if(FAILED(hr)) return S_FALSE;hr=pSendGraph->QueryInterface(IID_IMediaEvent,(void**)&pSendEvent);if(FAILED(hr)) return S_FALSE;hr=pGrabberSample->QueryInterface(IID_ISampleGrabber,(void**)&pGrabber);if(FAILED(hr)) return S_FALSE;// 修改分辨率SetFormat(pCaputerBuilder, pCaputerFilter, 640, 480, 24, 30);//Display local videohr=pCaputerBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,NULL,pCaputerF ilter,pGrabberSample,NULL);if(FAILED(hr)) return S_FALSE;return S_OK;}HRESULT SnapStill(){HRESULT hr;long cbBuffer = 0;hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);if(FAILED(hr)) return E_FAIL;char *pBuffer = new char[cbBuffer];if (!pBuffer) {// Deal Out of memory. Return an error code.}hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);if(FAILED(hr)) return E_FAIL;//生成BitmapAM_MEDIA_TYPE mt;hr = pGrabber->GetConnectedMediaType(&mt);if (FAILED(hr)) return E_FAIL;VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)mt.pbFormat;if(pVideoHeader==NULL) return E_FAIL;BITMAPINFO BitmapInfo;ZeroMemory(&BitmapInfo, sizeof(BitmapInfo));CopyMemory(&BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader),sizeof(BITMAPINFOHEADER));HBITMAP hBitmap;hBitmap = ::CreateDIBitmap(::GetDC(NULL), &(pVideoHeader->bmiHeader), CBM_INIT, pBuffer, &BitmapInfo, DIB_RGB_COLORS);if(hBitmap==NULL) return E_FAIL;CStringstrSaveFileName="";CFileDialogfiledlg(FALSE,_T("bmp"),_T(""),OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_ T("BMP(*.bmp)"));if(filedlg.DoModal()==IDOK){strSaveFileName=filedlg.GetPathName();SaveBitmapToFile(hBitmap,strSaveFileName.GetBuffer(0));}return hr;BOOL SetFormat(ICaptureGraphBuilder2* pBuilder, IBaseFilter* pCap, long lWidth, long lHeight, unsigned short iColorBit, __int64 iRate ){VIDEOINFOHEADER* phead;IAMStreamConfig* iconfig;HRESULT hr;hr = pBuilder ->FindInterface( &PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,pCap, IID_IAMStreamConfig, (void **)&iconfig );if ( hr != NOERROR ){hr = pBuilder ->FindInterface( &PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video, pCap,IID_IAMStreamConfig, (void **)&iconfig);}if ( FAILED( hr ) )return FALSE;AM_MEDIA_TYPE* pmt;if ( iconfig ->GetFormat( &pmt ) != S_OK )return FALSE;if ( pmt ->formattype == FORMAT_VideoInfo){phead = ( VIDEOINFOHEADER* )pmt ->pbFormat;phead ->bmiHeader.biBitCount = iColorBit;phead ->bmiHeader.biWidth = lWidth;phead ->bmiHeader.biHeight = lHeight;phead ->bmiHeader.biSizeImage = lWidth * lHeight * iColorBit / 8; phead ->AvgTimePerFrame = iRate;if ( ( hr = iconfig ->SetFormat( pmt ) ) != S_OK )return FALSE;}iconfig -> Release();iconfig = NULL;FreeMediaType( *pmt );return TRUE;}从摄像头流中捕捉一张图片zz视频问题,从摄像头流中捕捉一张图片。

相关文档
最新文档