胡章平,汪維華
(重慶文理學院計算機學院,重慶 永川 402160)
在圖像處理、電視視頻監控、視頻會議、可視電話等視頻處理應用中,根據應用需求獲取數字視頻的某一關鍵幀是前提條件.因此,視頻幀的抓取是圖像處理與視頻處理的關鍵技術之一.很多視頻播放軟件或視頻編輯軟件都提供了抓幀功能,利用這類軟件,視頻工作者可以很輕松地將一部電影某一時刻的幀抓取出來并保存為圖片文件,然后進行相應的加工處理.然而,這類軟件卻不能很好地與我們的應用程序融合為一體,只能在應用程序與視頻播放軟件或視頻編輯軟件之間進行手工協調,大大降低了處理的速度和有效性.因此,需要自己編寫程序實現視頻的抓幀功能,目前關于這方面的研究比較多.
文獻[1-6]介紹了基于 VFW(Video for Windows)技術與VC++平臺下的視頻捕獲與抓幀的應用與實現.VFW是Microsoft公司推出的關于數字視頻的一個軟件開發包,其核心是AVI(Audio Video Interleave)文件標準.圍繞AVI文件標準,VFW包含了一整套完整的視頻采集、壓縮、解壓、回放和編輯的應用程序編程接口(后簡稱 API)[1].
DirectShow是微軟公司在 ActiveMovie和Video for Windows的基礎上推出的新一代基于COM(Component Object Model)的流媒體處理的開發包,與DirectX開發包一起發布.它廣泛地支持各種媒體格式,包括 asf、mpeg、avi、dv、mp3、wave等等,使得多媒體數據的回放變得輕而易舉.另外,DirectShow還集成了DirectX其它部分(比如DirectDraw、DirectSound)的技術,直接支持DVD的播放,視頻的非線性編輯,以及與數字攝像機的數據交換.
Directshow是基于模塊化的,每個功能模塊都采取COM組件方式,稱為Filter,各個Filter在Filter Graph中按一定的順序連接成一條“流水線”協同工作.按照功能來分,Filter大致分為3類:Source Filters、Transform Filters和 Rendering Filters.Source Filters主要負責取得數據,數據源可以是文件、因特網或者計算機里的采集卡、數字攝像機等,然后將數據往下傳輸;Transform Fitlers主要負責數據的格式轉換和傳輸;Rendering Filtes主要負責數據的最終去向.
利用DirectShow實現視頻的抓幀功能有許多方法[11]:
1)使用 Sample Grabber Filter方法,該方法靈活但是復雜,對程序開發人員要求較高,文獻[11]詳細討論了該方法的使用.
2)使用IBasicVideo::GetCurrentImage接口方法:
HRESULT GetCurrentImage(long* pBuffer-Size,long*pDIBImage);
目前部分企業的管理模式落后,而抄核收的各項環節都緊密相關,前項工作的錯誤就將造成整個工作出現誤差。因為管理模式落后,各項環節抄表、核算以及收費等沒有統一的標準,并且不能對存在的數據進行核對,導致電力營銷工作效率下降。管理人員應該有所針對,著重對薄弱環節進行加強,例如,優化用戶耗電數據的總結環節,依據實際情況,輔之合理的梯度抄核收標準,規范各項工作的管理流程,改變落后管理模式的現狀。
其中:pBufferSize為緩沖區大小;pDIBImage為指向存儲DIB格式圖像緩沖區的指針.
如果使用傳統的VideoRenderer,那么使用GetCurrentImage方法抓圖將是不可靠的.因為如果VideoRenderer使用 DirectDraw加速,這個函數調用會失敗;而且調用這個函數時,Video Renderer必須處于暫停狀態.但如果使用VMR9,則沒有上述這些限制[11].
3)最簡單的方法是直接抓屏或是使用DirectX中的 Media Detector(MediaDet)對象.本文將詳細探討該方法的抓幀功能的實現原理與具體方法.
MediaDet對象可以從媒體源文件中獲取媒體的格式信息,也可以從視頻源中抓取所有的視頻幀,如果這個文件是可以搜索的,那么可以根據特征信息獲取該文件中任意幀圖像.
Media Detector不是一個過濾器,應用程序不需要使用過濾圖形管理器或者創建過濾圖形,可以通過調用CoCreateInstance來創建Media Detector對象.在Media Detector內部,它會創建一個包含了Sample Grabber過濾器的過濾圖形.為了得到圖形,Media Detector會搜索和暫停過濾圖形,然后從Sample Grabber過濾器中獲得一幅BMP圖像.
應用程序和Media Detector通訊是通過IMediaDet接口來實現的.通過IMediaDet接口接收媒體文件的數據流以及每個流的媒體類型、持續時間和幀率等信息.該接口也包含了從視頻流中抓取視頻幀在內的方法,常用的方法如表1所示.

表1 IMediaDet接口常用方法
視頻幀的捕獲功能流程圖如圖1所示.

圖1 捕獲流程
為了能在CJHJ開發平臺下利用IMediaDet接口獲取媒體文件信息與實現視頻幀抓取,首先必須引入命名空間DexterLib,即using DexterLib.
為了打開視頻流,需創建一個MediaDet對象,并通過對象的文件名同多媒體文件關聯,語句如下:
IMediaDet mediaDet=new MediaDetClass();mediaDet.Filename=videoFile;
由于媒體類型比較多,因此在獲取媒體流之前必須首先要知道所需要的媒體類型.媒體類型的獲取是通過MediaDet對象的StreamMediaType實現的,如:


利用MediaDet的GetBitmapBits方法能夠截取某一時間的圖片,該方法沒有直接提供獲取某幀的圖像,因此主要是利用視頻流的總體播放時間及其播放速度,求出第i幀的時間位置,進而抓取該幀圖片.計算總幀數如(1)式所示.

其中:
streamLength——MediaDet對象屬性,描述整個視頻的播放時間(單位秒);
FrameRate——MediaDet對象屬性,描述播放速度(單位是幀/秒);
第i幀的播放時間如(2)式.

抓取第i幀的方法為:GetBitmapBits(iTime,ref bufferSize,ref*frameBuffer,Width,Height).其中參數的含義為:
bufferSize—緩沖區大小;
frameBuffer—保存位圖的緩沖區;
Width—位圖的寬度;
Height—位圖的高度;
得到第i幀圖片后,為了保存或者是加工圖片,需要知道幀的寬度、高度等基本信息.使用Marshal.PtrToStructure方法可以獲取媒體基本信息,包括:視頻流的數據速率、幀的平均顯示時間、位圖基本信息等.獲取幀信息的代碼如下:

其中,VIDEOINFOHEADER結構如下:

本文分析研究了傳統的VFW技術與VC++平臺下的視頻捕獲,討論了新技術DirectShow的視頻捕獲方法,重點探討利用IMediaDet接口在CJHJ平臺中實現視頻捕獲的技術,并利用該技術實現了一個視頻抓取與回放系統,通過程序還能夠控制播放的速度,達到了很好的效果.
[1]易小波,周海偉.VC平臺下視頻捕獲的實現[J].衡陽師范學院學報,2006,27(6):75-77.
[2]李國芳.在 VC++6.0中實現視頻捕獲編程[J].教育信息化,2009(9):2-4.
[3]于曉康,柴喬林.基于VC++的可控視頻回放系統[J].計算機應用,2003,23(12):326-328.
[4]彭凱,盧益民.VC++實現遠程監控系統中視頻捕捉[J].電視技術,2001,234(12):86-87.
[5]郭新軍.用VC++實現視頻監控錄像[J].微電子學與計算機,2004,21(4):58-59,87.
[6]龔偉.基于VFW的遠程專家會診系統中的實時音視頻捕獲[J].計算機科學,2007,34(11):127-128.
[7]倪緒能,胡濤,張志剛.利用VC++實現基于Direct-Show的視頻捕獲[J].電視技術,2003,256(10):15-17.
[8]許曉勇,唐小妹,王飛雪.基于分段相關-視頻積累方法的偽碼串行捕獲優化設計[J].信號處理,2009,25(9):1338-1341.
[9]王國富,陳良益,何俊華.星載光電儀器捕獲跟蹤視頻處理系統設計[J].傳感器與儀器儀表,2007,23(8-1):139-141.
[10]陳昱,王博亮,謝杰鎮.基于DirectShow的眼前節圖像采集系統的設計[J].廈門大學學報:自然科學版,2005,44(4):503-506.