胡章平,汪維華
(重慶文理學(xué)院計(jì)算機(jī)學(xué)院,重慶 永川 402160)
在圖像處理、電視視頻監(jiān)控、視頻會(huì)議、可視電話等視頻處理應(yīng)用中,根據(jù)應(yīng)用需求獲取數(shù)字視頻的某一關(guān)鍵幀是前提條件.因此,視頻幀的抓取是圖像處理與視頻處理的關(guān)鍵技術(shù)之一.很多視頻播放軟件或視頻編輯軟件都提供了抓幀功能,利用這類軟件,視頻工作者可以很輕松地將一部電影某一時(shí)刻的幀抓取出來并保存為圖片文件,然后進(jìn)行相應(yīng)的加工處理.然而,這類軟件卻不能很好地與我們的應(yīng)用程序融合為一體,只能在應(yīng)用程序與視頻播放軟件或視頻編輯軟件之間進(jìn)行手工協(xié)調(diào),大大降低了處理的速度和有效性.因此,需要自己編寫程序?qū)崿F(xiàn)視頻的抓幀功能,目前關(guān)于這方面的研究比較多.
文獻(xiàn)[1-6]介紹了基于 VFW(Video for Windows)技術(shù)與VC++平臺(tái)下的視頻捕獲與抓幀的應(yīng)用與實(shí)現(xiàn).VFW是Microsoft公司推出的關(guān)于數(shù)字視頻的一個(gè)軟件開發(fā)包,其核心是AVI(Audio Video Interleave)文件標(biāo)準(zhǔn).圍繞AVI文件標(biāo)準(zhǔn),VFW包含了一整套完整的視頻采集、壓縮、解壓、回放和編輯的應(yīng)用程序編程接口(后簡稱 API)[1].
DirectShow是微軟公司在 ActiveMovie和Video for Windows的基礎(chǔ)上推出的新一代基于COM(Component Object Model)的流媒體處理的開發(fā)包,與DirectX開發(fā)包一起發(fā)布.它廣泛地支持各種媒體格式,包括 asf、mpeg、avi、dv、mp3、wave等等,使得多媒體數(shù)據(jù)的回放變得輕而易舉.另外,DirectShow還集成了DirectX其它部分(比如DirectDraw、DirectSound)的技術(shù),直接支持DVD的播放,視頻的非線性編輯,以及與數(shù)字?jǐn)z像機(jī)的數(shù)據(jù)交換.
Directshow是基于模塊化的,每個(gè)功能模塊都采取COM組件方式,稱為Filter,各個(gè)Filter在Filter Graph中按一定的順序連接成一條“流水線”協(xié)同工作.按照功能來分,F(xiàn)ilter大致分為3類:Source Filters、Transform Filters和 Rendering Filters.Source Filters主要負(fù)責(zé)取得數(shù)據(jù),數(shù)據(jù)源可以是文件、因特網(wǎng)或者計(jì)算機(jī)里的采集卡、數(shù)字?jǐn)z像機(jī)等,然后將數(shù)據(jù)往下傳輸;Transform Fitlers主要負(fù)責(zé)數(shù)據(jù)的格式轉(zhuǎn)換和傳輸;Rendering Filtes主要負(fù)責(zé)數(shù)據(jù)的最終去向.
利用DirectShow實(shí)現(xiàn)視頻的抓幀功能有許多方法[11]:
1)使用 Sample Grabber Filter方法,該方法靈活但是復(fù)雜,對(duì)程序開發(fā)人員要求較高,文獻(xiàn)[11]詳細(xì)討論了該方法的使用.
2)使用IBasicVideo::GetCurrentImage接口方法:
HRESULT GetCurrentImage(long* pBuffer-Size,long*pDIBImage);
目前部分企業(yè)的管理模式落后,而抄核收的各項(xiàng)環(huán)節(jié)都緊密相關(guān),前項(xiàng)工作的錯(cuò)誤就將造成整個(gè)工作出現(xiàn)誤差。因?yàn)楣芾砟J铰浜螅黜?xiàng)環(huán)節(jié)抄表、核算以及收費(fèi)等沒有統(tǒng)一的標(biāo)準(zhǔn),并且不能對(duì)存在的數(shù)據(jù)進(jìn)行核對(duì),導(dǎo)致電力營銷工作效率下降。管理人員應(yīng)該有所針對(duì),著重對(duì)薄弱環(huán)節(jié)進(jìn)行加強(qiáng),例如,優(yōu)化用戶耗電數(shù)據(jù)的總結(jié)環(huán)節(jié),依據(jù)實(shí)際情況,輔之合理的梯度抄核收標(biāo)準(zhǔn),規(guī)范各項(xiàng)工作的管理流程,改變落后管理模式的現(xiàn)狀。
其中:pBufferSize為緩沖區(qū)大小;pDIBImage為指向存儲(chǔ)DIB格式圖像緩沖區(qū)的指針.
如果使用傳統(tǒng)的VideoRenderer,那么使用GetCurrentImage方法抓圖將是不可靠的.因?yàn)槿绻鸙ideoRenderer使用 DirectDraw加速,這個(gè)函數(shù)調(diào)用會(huì)失敗;而且調(diào)用這個(gè)函數(shù)時(shí),Video Renderer必須處于暫停狀態(tài).但如果使用VMR9,則沒有上述這些限制[11].
3)最簡單的方法是直接抓屏或是使用DirectX中的 Media Detector(MediaDet)對(duì)象.本文將詳細(xì)探討該方法的抓幀功能的實(shí)現(xiàn)原理與具體方法.
MediaDet對(duì)象可以從媒體源文件中獲取媒體的格式信息,也可以從視頻源中抓取所有的視頻幀,如果這個(gè)文件是可以搜索的,那么可以根據(jù)特征信息獲取該文件中任意幀圖像.
Media Detector不是一個(gè)過濾器,應(yīng)用程序不需要使用過濾圖形管理器或者創(chuàng)建過濾圖形,可以通過調(diào)用CoCreateInstance來創(chuàng)建Media Detector對(duì)象.在Media Detector內(nèi)部,它會(huì)創(chuàng)建一個(gè)包含了Sample Grabber過濾器的過濾圖形.為了得到圖形,Media Detector會(huì)搜索和暫停過濾圖形,然后從Sample Grabber過濾器中獲得一幅BMP圖像.
應(yīng)用程序和Media Detector通訊是通過IMediaDet接口來實(shí)現(xiàn)的.通過IMediaDet接口接收媒體文件的數(shù)據(jù)流以及每個(gè)流的媒體類型、持續(xù)時(shí)間和幀率等信息.該接口也包含了從視頻流中抓取視頻幀在內(nèi)的方法,常用的方法如表1所示.
表1 IMediaDet接口常用方法
視頻幀的捕獲功能流程圖如圖1所示.
圖1 捕獲流程
為了能在CJHJ開發(fā)平臺(tái)下利用IMediaDet接口獲取媒體文件信息與實(shí)現(xiàn)視頻幀抓取,首先必須引入命名空間DexterLib,即using DexterLib.
為了打開視頻流,需創(chuàng)建一個(gè)MediaDet對(duì)象,并通過對(duì)象的文件名同多媒體文件關(guān)聯(lián),語句如下:
IMediaDet mediaDet=new MediaDetClass();mediaDet.Filename=videoFile;
由于媒體類型比較多,因此在獲取媒體流之前必須首先要知道所需要的媒體類型.媒體類型的獲取是通過MediaDet對(duì)象的StreamMediaType實(shí)現(xiàn)的,如:
利用MediaDet的GetBitmapBits方法能夠截取某一時(shí)間的圖片,該方法沒有直接提供獲取某幀的圖像,因此主要是利用視頻流的總體播放時(shí)間及其播放速度,求出第i幀的時(shí)間位置,進(jìn)而抓取該幀圖片.計(jì)算總幀數(shù)如(1)式所示.
其中:
streamLength——MediaDet對(duì)象屬性,描述整個(gè)視頻的播放時(shí)間(單位秒);
FrameRate——MediaDet對(duì)象屬性,描述播放速度(單位是幀/秒);
第i幀的播放時(shí)間如(2)式.
抓取第i幀的方法為:GetBitmapBits(iTime,ref bufferSize,ref*frameBuffer,Width,Height).其中參數(shù)的含義為:
bufferSize—緩沖區(qū)大小;
frameBuffer—保存位圖的緩沖區(qū);
Width—位圖的寬度;
Height—位圖的高度;
得到第i幀圖片后,為了保存或者是加工圖片,需要知道幀的寬度、高度等基本信息.使用Marshal.PtrToStructure方法可以獲取媒體基本信息,包括:視頻流的數(shù)據(jù)速率、幀的平均顯示時(shí)間、位圖基本信息等.獲取幀信息的代碼如下:
其中,VIDEOINFOHEADER結(jié)構(gòu)如下:
本文分析研究了傳統(tǒng)的VFW技術(shù)與VC++平臺(tái)下的視頻捕獲,討論了新技術(shù)DirectShow的視頻捕獲方法,重點(diǎn)探討利用IMediaDet接口在CJHJ平臺(tái)中實(shí)現(xiàn)視頻捕獲的技術(shù),并利用該技術(shù)實(shí)現(xiàn)了一個(gè)視頻抓取與回放系統(tǒng),通過程序還能夠控制播放的速度,達(dá)到了很好的效果.
[1]易小波,周海偉.VC平臺(tái)下視頻捕獲的實(shí)現(xiàn)[J].衡陽師范學(xué)院學(xué)報(bào),2006,27(6):75-77.
[2]李國芳.在 VC++6.0中實(shí)現(xiàn)視頻捕獲編程[J].教育信息化,2009(9):2-4.
[3]于曉康,柴喬林.基于VC++的可控視頻回放系統(tǒng)[J].計(jì)算機(jī)應(yīng)用,2003,23(12):326-328.
[4]彭凱,盧益民.VC++實(shí)現(xiàn)遠(yuǎn)程監(jiān)控系統(tǒng)中視頻捕捉[J].電視技術(shù),2001,234(12):86-87.
[5]郭新軍.用VC++實(shí)現(xiàn)視頻監(jiān)控錄像[J].微電子學(xué)與計(jì)算機(jī),2004,21(4):58-59,87.
[6]龔偉.基于VFW的遠(yuǎn)程專家會(huì)診系統(tǒng)中的實(shí)時(shí)音視頻捕獲[J].計(jì)算機(jī)科學(xué),2007,34(11):127-128.
[7]倪緒能,胡濤,張志剛.利用VC++實(shí)現(xiàn)基于Direct-Show的視頻捕獲[J].電視技術(shù),2003,256(10):15-17.
[8]許曉勇,唐小妹,王飛雪.基于分段相關(guān)-視頻積累方法的偽碼串行捕獲優(yōu)化設(shè)計(jì)[J].信號(hào)處理,2009,25(9):1338-1341.
[9]王國富,陳良益,何俊華.星載光電儀器捕獲跟蹤視頻處理系統(tǒng)設(shè)計(jì)[J].傳感器與儀器儀表,2007,23(8-1):139-141.
[10]陳昱,王博亮,謝杰鎮(zhèn).基于DirectShow的眼前節(jié)圖像采集系統(tǒng)的設(shè)計(jì)[J].廈門大學(xué)學(xué)報(bào):自然科學(xué)版,2005,44(4):503-506.