基于DirectShow视频及图片捕获软件的开发.docx
- 文档编号:28287875
- 上传时间:2023-07-10
- 格式:DOCX
- 页数:12
- 大小:20.71KB
基于DirectShow视频及图片捕获软件的开发.docx
《基于DirectShow视频及图片捕获软件的开发.docx》由会员分享,可在线阅读,更多相关《基于DirectShow视频及图片捕获软件的开发.docx(12页珍藏版)》请在冰豆网上搜索。
基于DirectShow视频及图片捕获软件的开发
我们知道目前很多工业相机的图像数据采集都是基于DirectShow的,常见的有映美精等。
DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。
DirectShow为多媒体流的捕捉和回放提供了强有力的支持。
运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。
它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒体数据的回放变得轻而易举。
另外,DirectShow还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD的播放,视频的非线性编辑,以及与数字摄像机的数据交换。
更值得一提的是,DirectShow提供的是一种开放式的开发环境,我们可以根据自己的需要定制自己的组件。
笔者使用visualstudio2005来开发了基于DirectShow的视频捕获软件,并用开发的软件对映美精相机进行了测试。
本软件不但可以实现对相机的视频捕获,而且还可以抓取图像帧。
软件运行时自动搜索所连接的相机,预览后可以对相机参数进行设置。
下面是软件的主界面。
预览视频后可以对视频格式和图像参数进行设置。
开始预览时,捕获的视频是黑白的,我们将颜色空间设置为UYVY即可捕获彩色视频。
下面是捕获的一帧图像,图像质量虽然没有映美精自带的软件效果好,但已经实现了所需各项基本功能,接下来的工作将会进一步提高软件性能。
另外我们还可以捕获视频,点击“捕获视频”按钮,输入要保持的文件名,注意要以.avi后缀结尾,点确定就开始捕获视频。
从我们开发的软件可以看到,映美精的相机能够很好的支持DirectShow的驱动,我们的软件对映美精相机的识别是如此的容易。
接下来我们将继续开发基于其它驱动的图像捕获软件,为最终实现在一个软件中识别各种相机而努力。
我们将逐步开放我们的源代码,以便更多的同行一起来探讨相机的图像采集技术。
下面是详细的软件开发过程。
一、安装DirectShow和visualstudio2005
首先我们安装DirectShowSDK,它有许多版本,作者使用的是2003年发布的,安装在D盘的DXSDK下。
软件下载地址为。
然后安装好visualstudio2005。
安装完以后我们将进行开发环境的配置。
二、开发环境配置
开发环境的配置主要有两个工作要做:
一是在使用DirectshowSDK开发自己的程序时需要的DirectShow的有关静态库的配置,二是visualC++开发环境的配置。
1、生成DirectShowSDK开发库
使用DirectShowSDK开发用户自己的程序需要几个静态链接库:
、、和。
中间两个lib需要用户自己编译生成,而其他两个微软已经提供。
下表列出了使用DirectShowSDK开发程序所有要使用的库。
库名
功能说明
定义了DirectShow标准的输出类标识(CLSID)和接口标识(IID)
流媒体开发用到的库,Debug、Debug_Unicode版本
流媒体开发用到的库,Release、Release_Unicode版本
定义了导出函数AMGetErrorText
使用Windows多媒体编程用到的库
基于VC++2005开发软件使用DirectShowSDK,首先需要用户编译DirectShow自带的源代码工程baseclasses,以生成DirectShowSDK的不同版本的库。
同时由于DirectShowSDK是早期的VC开发软件,所以使用VC++2005编译DirectShowSDK会出现很多编译问题。
下面列出了详细的编译过程和问题分析、解决方法。
编译工程baseclasses工程
启动VS2005,选择“文件”→“打开”→“项目/解决方案”命令,在弹出的对话框中打开“BaseClasses”项目。
打开“”项目。
如果VS2005有提问,则默认同意或确定。
现在就开始编译该项目。
按“F7”快捷键可以编译生成项目。
初次编译VS2005会报很多错误或者警告,有的需要我们手工修改程序,或者修改VS2005环境配置或编译选项;有的是一类问题,解决方法也有很多种。
具体解决方法请参考路锦正的《VisualC++音频/视频处理技术及工程实践》第225页-229页。
VisualC++开发环境配置
有了DirectShowSDK库,用户就可以使用这些库来开发自己的程序了。
为了能让VC++自动搜寻到SDK库和头文件,还需要对VC++的开发环境进行配置。
添加库或路径的时候,根据你的要求添加Debug、Release、Debug_Unicode、Release_Unicode版本的库所在路径。
下面假定添加非Unicode版本的库或路径。
首先确定VC2005是否已经包含了库和头文件所在的路径,因为在安装VC2005时,它会自动添加该目录。
如果没有,则需要用户手工添加。
1. 更改添加的include内容:
D:
\DXSDK\Include
D:
\DXSDK\Samples\C++\DirectShow\BaseClasses
D:
\DXSDK\Samples\C++\Common\Include
添加过程如下。
选择“工具”→“选项”命令,在“项目和解决方案下”选择“VC++目录”,在下拉框中选择“包含文件”选项,将上面的三个Include内容添加进去。
2. 更改添加lib路径
要添加的lib内容:
D:
\DXSDK\Lib
D:
\DXSDK\Samples\C++\DirectShow\BaseClasses\Debug
D:
\DXSDK\Samples\C++\DirectShow\BaseClasses\Debug_Unicode
D:
\DXSDK\Samples\C++\DirectShow\BaseClasses\Release
D:
\DXSDK\Samples\C++\DirectShow\BaseClasses\Release_Unicode
添加过程和Include内容相似,只是在下拉框中选择“库文件”选项。
3. 添加链接库支持
上面的设置是在VC2005的开发环境的目录(Directories)中,添加用户在开发中可能用到的库或头文件“路径”,需要明确的事文件夹,而不是具体的文件。
所以,要使用相关的库支持,还要用户明确地把要使用的库包含、添加到开发环境中。
基于DirectShowSDK开发流媒体应用程序,一般需要链接和,前者定义了DirectShow标准的类标识符CLSID和接口标识IID,后者定义了导出函数AMGetErrorText(如果应用程序中没有使用这个函数,也可以不链接这个库)。
在编译生成DirectShow的BaseClasses库、时,由于该工程是生成库而不是应用程序,所以在编译该项目时VC++2005没有“链接器”选项。
但是在开发其他应用可执行程序时,需要添加DirectShowSDK库的支持。
添加路径:
项目→属性→配置属性→链接器→输入→附加依赖项,输入,库名之间用空格分开。
另外,在程序中使用DirectShowSDK类或接口的代码程序中,还要添加#include<>。
在添加链接库时,除了以上配置VC的开发环境外,也可以在源程序文件开头部分,直接语句编程引入#pragmacomment(lib,””)。
如果程序中没有使用,而是包含了,则库文件需要链接、,在源程序文件开头添加:
#pragmacomment(lib,””)
#pragmacomment(lib,””)
#include<>
不过,编译器会报出以下的错误。
errorC2146:
语法错误为缺少“;”(在标识符“m_pString”的前面)。
问题定位在(329)中。
经分析得知,由于某种原因,编译器认为PTCHAR没有定义,那用户可以在类外定义:
typedefWCHAR*PTCHAR;再编译项目。
三、开发过程
DirectShowSDK的视频采集经典技术是使用ICaptureGraphBuilder2标准接口,利用其方法RenderStream自动建立、连接滤波器链表。
RenderStream方法在预览、捕获视频时引脚的类型分为PIN_CATEGORY_PREVIEW和PIN_CATEGORY_CAPTURE,媒体类型均为MEDIATYPE_Video。
此实例要完成的目的有两个:
一是实时预览采集的视频数据;二是在预览图像的同时,实时地把捕获数据保存到文件中。
首先我们使用GraphEdit模拟实现该过程。
1、GraphEdit模拟实现
步骤一、添加"VideoCaptureSources"视频捕获设备,如图1所示。
图1、添加视频捕获设备
步骤二、视频捕获滤波器只有一个Pin,而我们要求在预览数据的同时还能够保存数据,即需要一个组件把捕获的流分成两个。
DirectShowSDK为此提供了SmartTee滤波器,把捕捉的视频流分成两个流供使用。
在GraphEdit中单击"DirectShowFilters"按钮,插入"SmartTee"滤波器,如图2所示
图2添加SmartTee滤波器
步骤三、采集捕捉的视频数据保存到文件,以AVI格式写文件。
插入"AVIMux"滤波器,如图3所示。
图3添加AVIMux滤波器
步骤四、插入"Filewriter"滤波器,保存文件命名为""。
如图4所示
图4插入Filewriter
步骤五、插入"SampleGrabber"和"VideoRenderer"滤波器,如图5所示
图5插入SampleGrabber和VideoRenderer滤波器
步骤六、最后把所有的滤波器用鼠标连接起来,完成构建滤波器链表,如图6所示
图6视频预览、保存滤波器链表
步骤七、运行滤波器链表,单击"Graph"→"Play"按钮执行视频数据的预览、保存。
1、视频捕获类CCaptureClass的实现
详细讲述CCaptureClass类的成员变量和其他成员方法的实现,剖析其完成视频采集、保存的技术过程。
1)定义CCaptureClass类
classCCaptureClass
{
public:
CCaptureClass();
hr=CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC_SERVER,
IID_IBaseFilter,(void**)&pGrabberF);
if(FAILED(hr))
{
AfxMessageBox(_T("Can’tcreatethegrabber"));
returnhr;
}
hr=pGrabberF->QueryInterface(IID_ISampleGrabber,(void**)&pGrabber);
hr=CoCreateInstance(CLSID_VideoRenderer,NULL,CLSCTX_INPROC_SERVER,
IID_IBaseFilter,(void**)&pNull);
hr=m_pGB->AddFilter(pNull,L"VideoRender");
if(FAILED(hr))
{
AfxMessageBox(_T("Can’taddtheVideoRender"));
returnhr;
}
VIDEOINFOHEADER*pVih;
if(==FORMAT_VideoInfo)&&
>=sizeof(VIDEOINFOHEADER))&&
!
=NULL))
{
pVih=(VIDEOINFOHEADER*);
}
else
{
Freetheformatblockandreturnanerror.
returnVFW_E_INVALIDMEDIATYPE;
}
hr=pGrabber->SetOneShot(TRUE);
if(SUCCEEDED(pGrabber->SetBufferSamples(TRUE)))
{
boolpass=false;
m_pMC->Run();
longEvCode=0;
hr=pEvent->WaitForCompletion(INFINITE,&EvCode);
Returnanerrorcode.
AfxMessageBox(_T("OutofMemory"));
}
hr=pGrabber->GetCurrentBuffer(&cbBuffer,(long*)(pBuffer));
BITMAPFILEHEADERbfh;
ZeroMemory(&bfh,sizeof(bfh));
='MB';=sizeof(bfh)+cbBuffer+sizeof(BITMAPINFOHEADER);
=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
DWORDdwWritten=0;
WriteFile(hf,&bfh,sizeof(bfh),&dwWritten,NULL);
vi)|*.avi|"); |*.*|";
CFileDialogdlg(TRUE,NULL,NULL,
mp");
c++;
TCHAR*p=());
();
if((constchar*)p))
{
}else
MessageBox(_T("抓图失败!
"));
}
本功能将自动给图片命名并设置保存路径。
双击"保存图表"按钮,添加事件处理代码。
voidCCaptureVideoDlg:
:
OnBnClickedSavegraph()
{
//TODO:
在此添加控件通知处理程序代码
CFileDialogdlg(TRUE);
if()==IDOK){
CStringstr=(); //要保存的Graph文件名
TCHAR*inFileName=());//获取字符串指针
(); //切记要释放Buffer
(inFileName); //保存Graph
}
}
本功能存储的Graph文件可以使用程序GraphEdit播放。
双击"退出程序"按钮,添加事件处理代码。
程序隐含调用了类CCaptureClass的析构函数,释放资源和COM库。
voidCCaptureVideoDlg:
:
OnBnClickedExit()
{
//TODO:
在此添加控件通知处理程序代码
CDialog:
:
OnOK();
}
退出本程序时,由于视频捕获类CCaptureClass的析构函数已经包含了释放资源、指针的工作,所以退出应用程序时不用释放任何资源,只是关闭应用程序。
其他工作
在对话框的初始化OnInitDialog中枚举本系统的视频采集设备,添加到列表框并默认显示第一个设备。
());
(0);
至此我们详细介绍了软件的开发过程。
在开发过程中我们遇到了许多问题,如对于图片捕获有很多种方法,不同的方法将在很大程度上影响软件的稳定性和捕获图片的效果。
当然程序还存在许多有待改进的地方,我们将进一步完善它。
关于本软件及其源代码,我们将于近期在中国视觉网上公布并提供下载,希望大家及时关注我们的网站。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 DirectShow 视频 图片 捕获 软件 开发