關鍵詞: 視頻 , 壓縮
前言
視頻壓縮算法通過對視頻信號的壓縮處理可以極大地降低視頻信號的存儲和帶寬需求,在此基礎上盡可能多的獲得最佳的圖像質(zhì)量。因此,了解視頻壓縮算法的基本原理對于嵌入式系統(tǒng),處理器以及視頻應用工具的開發(fā)人員來說,是非常必要的,例如在處理器選型以及軟件優(yōu)化的過程中,視頻壓縮算法的性能開銷和存儲空間占用就是其中非常關鍵的因素。
在本文中,我們將著重探討視頻壓縮算法的特點和處理流程,我們將對基本的視頻壓縮算法進行解釋,包括靜態(tài)圖像壓縮、運動估計、圖像去噪, 以及色彩空間轉(zhuǎn)換,同時我們還將討論視頻壓縮算法對處理器的性能需求以及由這些需求所帶來的一系列影響。
靜態(tài)圖像壓縮
視頻剪輯也就是我們通常所說的動態(tài)圖像序列,動態(tài)圖像序列是由在時間軸上的若干幅靜態(tài)圖片組成的,在動態(tài)圖像序列中的每一幅圖片稱之為“幀”。在動態(tài)圖像的壓縮算法中大量的使用了靜態(tài)圖像壓縮的算法和技術(shù),例如靜態(tài)圖像壓縮標準JPEG。實際上簡單的動態(tài)圖像序列壓縮的方法就是將此序列中的每一幅靜態(tài)圖片獨立的壓縮,忽略掉這些圖片在時間上的相關性。在一些視頻產(chǎn)品的應用中使用了這種方法,將每一幅圖片都用JPEG標準進行壓縮,我們稱之為“運動JPEG”或者也叫MJPEG。
目前更為先進的視頻壓縮算法更多的利用了視頻序列中連續(xù)的靜態(tài)圖像,也就是連續(xù)幀之間的時間相關性,利用運動估計和運動補償算法獲得更好的壓縮比,當然這些先進的視頻壓縮算法也同樣采用了靜態(tài)圖像壓縮里面的一些基本算法,因此我們的討論就從基于塊變換的靜態(tài)圖像算法JPEG開始。
數(shù)字圖像壓縮的基本單元
塊變換
在JPEG和大多視頻壓縮算法中所采用的壓縮算法都是“有損壓縮”,所謂有損壓縮就是指從壓縮后的數(shù)據(jù)中無法完全恢復重構(gòu)出原始的壓縮前圖像,有損壓縮會丟失掉一部分原始圖像的信息,因此,有損壓縮算法就需要盡量保證由信息丟失所造成的原始圖像和重構(gòu)圖像之間的差異不被人眼所察覺。
對于JPEG和類似的圖像壓縮算法來說,壓縮的第一步需要將圖像分割為小塊,同時將每個小塊進行變換,使之由空域信號變換成為時域信號。這種空域到時域的變換多采用8x8的離散余弦變換(以下稱DCT),經(jīng)過DCT變換之后,8x8的空域像素矩陣變換成為 8x8的頻域信號矩陣,DCT變換能夠完整的保留所有8x8像素塊的信息,因此反向離散余弦變換(以下稱IDCT)也就能夠從8x8頻域信號矩陣中完整的恢復原始8x8像素矩陣。DCT變換后的頻域信號矩陣中包含原始8x8像素矩陣的低頻部分和高頻部分,其中低頻部分對應圖像的重要信息,高頻部分對應圖像的細節(jié)信息,就人眼的特點來說,對于圖像低頻部分的感知要比對于圖像高頻部分的感知敏感很多,因此在DCT變換將圖像的信息按照其人眼感知的敏感程度分離之后,后續(xù)的壓縮步驟就是將其低頻部分編碼更多的比特,從而獲得更高的精度,而對其高頻部分編碼更少的比特數(shù)或者不編碼比特,從而在保留一定的視覺效果的同時,獲得更好的壓縮效果。在解碼端,再用IDCT變換從頻域信號矩陣中恢復出原始8x8像素矩陣。
IDCT變換和DCT變換的運算量基本一致,因此這兩種變換對處理器的性能要求也基本類似。一個二維8x8 DCT變換和IDCT變換在典型的DSP平臺上需要數(shù)百個指令周期完成,視頻壓縮算法的執(zhí)行中每秒都需要進行大量的DCT和IDCT運算,以一個 MPEG4的解碼器為例,在解碼分辨率為CIF(352x288),幀率為30fps的視頻序列時,需要每秒進行71,280次IDCT運算,在TI TMS320C55x DSP處理器平臺上需要占用40MHz的處理性能(不考慮集成DCT加速器),這大概占用了整個視頻解碼器應用時處理器性能的30%。
由于DCT和IDCT運算的單位都是很小的圖像塊,因此相對于幀緩存以及圖像壓縮應用中的其他數(shù)據(jù)存儲來說,其對存儲資源的占用幾乎可以忽略不計,正是基于其大運算量,低存儲占用的特點,DCT和IDCT運算單元特別適合用專用的硬件加速協(xié)處理器來實現(xiàn)。
量化
DCT變換后的結(jié)果稱為DCT系數(shù),正如上文所說,編碼器需要對于DCT系數(shù)中的重要的低頻分量編碼更多的比特,對于DCT系數(shù)中的次要的高頻分量編碼更少的比特,這種對系數(shù)的編碼方法可以通過兩步來實現(xiàn):首先通過量化過程舍去次要的視頻信息,然后利用統(tǒng)計學的方法盡可能少的對剩余的重要信息進行比特編碼。
量化過程就是將每個DCT系數(shù)向若干預設值進行舍入的過程,例如,DCT系數(shù)是值介于-1 到1 之間的實數(shù),將其用縮放因子20進行縮放,同時將結(jié)果舍入到最近的整數(shù),于是DCT系數(shù)便量化成為值介于-20到20之間的整數(shù),共有41個,在理想情況下,為每個DCT系數(shù)選擇合適的量化因子可以使量化后的DCT系數(shù)在向右取整的過程中不至于引入明顯的量化噪聲。
在解碼端,采用與編碼端相反的反量化過程,就上文所屬的例子來說,對量化后的DCT系數(shù)進行反量化,用1/20進行縮放,反量化值縮放到-1到1之間,注意此時的反量化值與原始的量化前系數(shù)已經(jīng)不再相等,不過足夠接近,以保證IDCT 變換以后不會引入明顯的視覺差異。反量化大概需要占用整個視頻解碼器應用時處理器性能的3%-15%,與DCT和IDCT變化類似,量化和反量化對存儲器的資源占用可以忽略不計。
編碼
壓縮的下一個步驟即是對量化后的DCT系數(shù)進行比特編碼,使之成為傳輸比特流,為了盡可能少的編碼比特數(shù),達到數(shù)據(jù)壓縮的效果,需要利用量化后的DCT系數(shù)的一些統(tǒng)計特性。
量化后的DCT系數(shù)的值大多是0值,特別是大量的高頻DCT系數(shù)分量,一種叫做“游程編碼”(以下稱run-length編碼)的技術(shù)可以很好的利用DCT 系數(shù)的這一特點,在這種編碼技術(shù)中,并不對每個0值系數(shù)單獨編碼,而是將連續(xù)的0值(run)進行打包,然后再對這些連續(xù)0值系數(shù)的個數(shù)(length) 進行編碼。
為了更大程度的利用run-length編碼的特點,需要對8x8系數(shù)矩陣進行zig-zag掃描,保證先對低頻系數(shù)分量進行編碼,然后再對高頻系數(shù)分量進行編碼,這樣做的目的是因為在高頻系數(shù)分量中出現(xiàn)大量連續(xù)0值系數(shù)的概率更高。
Run- length編碼完成后即進行變長編碼(VLC),在變長編碼中,每個可能出現(xiàn)的數(shù)據(jù)值作為一個符號(例如每種可能run-length值作為一個符號),出現(xiàn)概率大的符號值用比特數(shù)更少的碼字表示,出現(xiàn)概率小的符號值用比特數(shù)更多的碼字表示,變長碼相對于定長碼使用的比特數(shù)更少,(定長碼是一種直接編碼方法,例如直接將每個量化后DCT系數(shù)編碼為其二進制表示),因此變長碼在編碼一幅圖像時所消耗的平均比特數(shù)更少。在變長碼編碼中,哈夫曼編碼是一種廣泛使用的編碼方法,基于每個符號的發(fā)生頻率,哈夫曼編碼可以獲得更優(yōu)的編碼效果。
理論上,對一組符號序列來說,變長編碼并不是最優(yōu)的編碼方法,相對于變長編碼來說,“算術(shù)編碼”的編碼比特數(shù)更少,編碼效果更好。變長編碼為每個符號分配單獨的碼字,因此每個符號都需要整數(shù)個比特個數(shù)(即每個符號至少占用1個比特),算術(shù)編碼將一組符號序列作為一個整體來進行編碼,因此并不是每個符號都需要占用比特,因此可以獲得更大的壓縮率,但是算術(shù)編碼的運算法雜程度遠遠大于變長編碼,因此只在最近的一些商用視頻壓縮算法中獲得應用,相對于算術(shù)編碼,在很多應用中,run-length編碼和變長編碼的組合編碼方法相對于算術(shù)編碼運算復雜程度低,編碼效率足夠,因此時至今日變長編碼仍然在大量的視頻壓縮協(xié)議中廣泛應用。
變長編碼通過對碼字和其長度的查找表實現(xiàn),完成查找后將碼字取出填充進比特流輸出,對應的解碼端過程稱之為變長解碼(VLD),最直接的變長解碼做法需要對每一個比特都要進行查表操作和判決,相對于變長編碼對每一個符號所進行的查表操作來說,這種變長解碼的方法運算量更加密集,平均每個比特需要進行11步操作,因此變長解碼的處理性能需求是和解碼器的解碼碼率成正比的,對于一些低分辨率和低碼率的視頻序列來說,變長解碼往往占到整個解碼器應用時處理器性能的 25%。
在一個典型的視頻解碼器中,上文所描述的這種最直接的變長解碼方法需要占用數(shù)KB大小的存儲空間用于存放查找表,為了獲得更高的解碼性能,可以采用一次處理一批比特的做法,當然,這種做法需要付出更大存儲空間的代價。
變長編碼的缺點在于,當編碼后的圖像或者編碼后視頻幀的比特流中出現(xiàn)誤碼時,解碼端將無法正確恢復誤碼后的圖像部分,一旦出現(xiàn)誤碼,解碼端就無法識別誤碼所對應的正確碼字的長度,因此也就無法識別下一個正確碼字在比特流里的起始位置,也就無法繼續(xù)解碼圖像。一種技術(shù)可以部分解決這個問題,該技術(shù)在編碼比特流中預先插入“重同步標志”,重同步標志的插入位置和內(nèi)容是事先定義好的,因此解碼端在解碼過程中能夠?qū)χ赝綐酥具M行正確定位,因此當誤碼發(fā)生的時候,解碼器可以從誤碼位置向后搜索下一個重同步標志,然后可以從這個重同步標志以后解碼出后續(xù)的圖像部分。
此外,在MEPG4視頻壓縮標準中,還采用了稱為“反向變長碼”的技術(shù),在反向變長碼中,碼字的選擇保證了其不但能夠從普通的正向進行解碼,同時也能夠從反向進行解碼,因此當誤碼發(fā)生的時候,解碼端可以向下搜索下一個重同步標志,搜索到了以后,再從重同步標志的位置反向解碼至誤碼位置,因此解碼端能夠盡可能多的恢復圖像數(shù)據(jù)。
到此為止,上面描述的所有技術(shù)都是針對一個獨立的8x8的像素塊,一幅圖像所包含的信息遠大于一個8x8像素塊所能包含的信息,因此利用相鄰塊彼此的相關性可以應用更多更有效的壓縮方法。
為了利用塊與塊之間的相關性,可以采用預測的技術(shù),編碼器在對DCT系數(shù)進行量化之前,可以基于周邊塊的DCT系數(shù)預測當前塊的DCT系數(shù),然后對預測值和當前實際值的差值進行量化,而不是直接對當前DCT系數(shù)進行量化,由于這個差值往往比較小,因此這項技術(shù)可以減少對DCT系數(shù)編碼的比特數(shù),對于解碼端,采用相同的預測方法,然后將從碼流解碼出來的差值加上預測出來的預測值,就可以重構(gòu)出實際的DCT系數(shù)值,需要注意的是,由于解碼端只能夠獲得那些在當前塊解碼前已經(jīng)解碼的塊的DCT系數(shù),因此編碼端必須保證只用到那些在編碼當前塊之前已經(jīng)編碼的塊的DCT系數(shù)作為預測值。
對于最簡單的情況,只對每個塊的第一個系數(shù)進行預測,這個系數(shù)被稱作“DC系數(shù)”,它代表 DCT系數(shù)里的最低頻分量,等于所有塊像素的均值,其余的系數(shù)被稱作“AC系數(shù)”。這種最簡單的做法是基于這樣的假設,即當前塊的DC系數(shù)等于左邊相鄰塊的DC系數(shù),這種做法利用了當前塊和左邊相鄰塊的空間相關性,對當前塊和前一編碼塊的DC系數(shù)的差值進行編碼,被稱為“DC系數(shù)差分編碼”,在JPEG圖像壓縮標準中得到了廣泛的應用。
也有一些更為復雜的預測方法,例如對8x8塊的每一行和每一列的第一個DCT系數(shù)進行預測,這樣的方法被稱作“AC-DC預測”,同上面所描述的差分編碼的方法相比,這種方法采用了更為復雜的預測方法,首先,對預測值的計算采用了濾波的方法,而不是簡單的等于相鄰塊對應的系數(shù),其次,預測值的產(chǎn)生可能要考慮多個相鄰塊,預測值可能是基于多個塊預測值的組合,同樣,編碼器會從多個預測塊中選出一個來獲得最好的預測效果,這樣的話編碼器就必須在碼流中表明哪一個相鄰塊被選中,這樣解碼器才能夠進行同樣的預測過程正確重構(gòu)DCT系數(shù)。
來源:Berkeley Design Technology, Inc.
評論
查看更多