H264基本原理

前言

H264視頻壓縮算法如今無疑是全部視頻壓縮技術中使用最普遍,最流行的。隨着 x264/openh264以及ffmpeg等開源庫的推出,大多數使用者無需再對H264的細節作過多的研究,這大下降了人們使用H264的成本。算法

但爲了用好H264,咱們仍是要對H264的基本原理弄清楚才行。今天咱們就來看看H264的基本原理。 緩存

H264概述

H264壓縮技術主要採用瞭如下幾種方法對視頻數據進行壓縮。包括:優化

  • 幀內預測壓縮,解決的是空域數據冗餘問題。
  • 幀間預測壓縮(運動估計與補償),解決的是時域數據冗徐問題。
  • 整數離散餘弦變換(DCT),將空間上的相關性變爲頻域上無關的數據而後進行量化。
  • CABAC壓縮。

通過壓縮後的幀分爲:I幀,P幀和B幀:編碼

  • I幀:關鍵幀,採用幀內壓縮技術。
  • P幀:向前參考幀,在壓縮時,只參考前面已經處理的幀。採用幀音壓縮技術。
  • B幀:雙向參考幀,在壓縮時,它即參考前而的幀,又參考它後面的幀。採用幀間壓縮技術。

除了I/P/B幀外,還有圖像序列GOP。3d

  • GOP:兩個I幀之間是一個圖像序列,在一個圖像序列中只有一個I幀。以下圖所示:

下面咱們就來詳細描述一下H264壓縮技術。cdn

H264壓縮技術

H264的基本原理其實很是簡單,下咱們就簡單的描述一下H264壓縮數據的過程。經過攝像頭採集到的視頻幀(按每秒 30 幀算),被送到 H264 編碼器的緩衝區中。編碼器先要爲每一幅圖片劃分宏塊。視頻

如下面這張圖爲例:blog

劃分宏塊

H264默認是使用 16X16 大小的區域做爲一個宏塊,也能夠劃分紅 8X8 大小。圖片

劃分好宏塊後,計算宏塊的象素值。it

以此類推,計算一幅圖像中每一個宏塊的像素值,全部宏塊都處理完後以下面的樣子。

劃分子塊

H264對比較平坦的圖像使用 16X16 大小的宏塊。但爲了更高的壓縮率,還能夠在 16X16 的宏塊上更劃分出更小的子塊。子塊的大小能夠是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4很是的靈活。

上幅圖中,紅框內的 16X16 宏塊中大部分是藍色背景,而三隻鷹的部分圖像被劃在了該宏塊內,爲了更好的處理三隻鷹的部分圖像,H264就在 16X16 的宏塊內又劃分出了多個子塊。

這樣再通過幀內壓縮,能夠獲得更高效的數據。下圖是分別使用mpeg-2和H264對上面宏塊進行壓縮後的結果。其中左半部分爲MPEG-2子塊劃分後壓縮的結果,右半部分爲H264的子塊劃壓縮後的結果,能夠看出H264的劃分方法更具優點。

宏塊劃分好後,就能夠對H264編碼器緩存中的全部圖片進行分組了。

幀分組

對於視頻數據主要有兩類數據冗餘,一類是時間上的數據冗餘,另外一類是空間上的數據冗餘。其中時間上的數據冗餘是最大的。下面咱們就先來講說視頻數據時間上的冗餘問題。

爲何說時間上的冗餘是最大的呢?假設攝像頭每秒抓取30幀,這30幀的數據大部分狀況下都是相關聯的。也有可能不止30幀的的數據,可能幾十幀,上百幀的數據都是關聯特別密切的。

對於這些關聯特別密切的幀,其實咱們只須要保存一幀的數據,其它幀均可以經過這一幀再按某種規則預測出來,因此說視頻數據在時間上的冗餘是最多的。

爲了達到相關幀經過預測的方法來壓縮數據,就須要將視頻幀進行分組。那麼如何斷定某些幀關係密切,能夠劃爲一組呢?咱們來看一下例子,下面是捕獲的一組運動的檯球的視頻幀,檯球從右上角滾到了左下角。


H264編碼器會按順序,每次取出兩幅相鄰的幀進行宏塊比較,計算兩幀的類似度。以下圖:

經過宏塊掃描與宏塊搜索能夠發現這兩個幀的關聯度是很是高的。進而發現這一組幀的關聯度都是很是高的。所以,上面這幾幀就能夠劃分爲一組。其算法是:在相鄰幾幅圖像畫面中,通常有差異的像素只有10%之內的點,亮度差值變化不超過2%,而色度差值的變化只有1%之內,咱們認爲這樣的圖能夠分到一組。

在這樣一組幀中,通過編碼後,咱們只保留第一帖的完整數據,其它幀都經過參考上一幀計算出來。咱們稱第一幀爲IDR/I幀,其它幀咱們稱爲P/B幀,這樣編碼後的數據幀組咱們稱爲GOP

運動估計與補償

在H264編碼器中將幀分組後,就要計算幀組內物體的運動矢量了。還以上面運動的檯球視頻幀爲例,咱們來看一下它是如何計算運動矢量的。

H264編碼器首先按順序從緩衝區頭部取出兩幀視頻數據,而後進行宏塊掃描。當發現其中一幅圖片中有物體時,就在另外一幅圖的鄰近位置(搜索窗口中)進行搜索。若是此時在另外一幅圖中找到該物體,那麼就能夠計算出物體的運動矢量了。下面這幅圖就是搜索後的檯球移動的位置。

經過上圖中臺球位置相差,就能夠計算出臺圖運行的方向和距離。H264依次把每一幀中球移動的距離和方向都記錄下來就成了下面的樣子。

運動矢量計算出來後,將相同部分(也就是綠色部分)減去,就獲得了補償數據。咱們最終只須要將補償數據進行壓縮保存,之後在解碼時就能夠恢復原圖了。壓縮補償後的數據只須要記錄不多的一點數據。以下所示:

咱們把運動矢量與補償稱爲幀間壓縮技術,它解決的是視頻幀在時間上的數據冗餘。除了幀間壓縮,幀內也要進行數據壓縮,幀內數據壓縮解決的是空間上的數據冗餘。下面咱們就來介紹一下幀內壓縮技術。

幀內預測

人眼對圖象都有一個識別度,對低頻的亮度很敏感,對高頻的亮度不太敏感。因此基於一些研究,能夠將一幅圖像中人眼不敏感的數據去除掉。這樣就提出了幀內預測技術。

H264的幀內壓縮與JPEG很類似。一幅圖像被劃分好宏塊後,對每一個宏塊能夠進行 9 種模式的預測。找出與原圖最接近的一種預測模式。

下面這幅圖是對整幅圖中的每一個宏塊進行預測的過程。

幀內預測後的圖像與原始圖像的對好比下:

而後,將原始圖像與幀內預測後的圖像相減得殘差值。

再將咱們以前獲得的預測模式信息一塊兒保存起來,這樣咱們就能夠在解碼時恢復原圖了。效果以下:

通過幀內與幀間的壓縮後,雖然數據有大幅減小,但還有優化的空間。

對殘差數據作DCT

能夠將殘差數據作整數離散餘弦變換,去掉數據的相關性,進一步壓縮數據。以下圖所示,左側爲原數據的宏塊,右側爲計算出的殘差數據的宏塊。

將殘差數據宏塊數字化後以下圖所示:

將殘差數據宏塊進行 DCT 轉換。

去掉相關聯的數據後,咱們能夠看出數據被進一步壓縮了。

作完 DCT 後,還不夠,還要進行 CABAC 進行無損壓縮。

CABAC

上面的幀內壓縮是屬於有損壓縮技術。也就是說圖像被壓縮後,沒法徹底復原。而CABAC屬於無損壓縮技術。

無損壓縮技術你們最熟悉的可能就是哈夫曼編碼了,給高頻的詞一個短碼,給低頻詞一個長碼從而達到數據壓縮的目的。MPEG-2中使用的VLC就是這種算法,咱們以 A-Z 做爲例子,A屬於高頻數據,Z屬於低頻數據。看看它是如何作的。

CABAC也是給高頻數據短碼,給低頻數據長碼。同時還會根據上下文相關性進行壓縮,這種方式又比VLC高效不少。其效果以下:

如今將 A-Z 換成視頻幀,它就成了下面的樣子。

從上面這張圖中明顯能夠看出採用 CACBA 的無損壓縮方案要比 VLC 高效的多。

##小結

至此,咱們就將H264的編碼原理講完了。本篇文章主要講了如下以點內容:

  1. 簡音介紹了H264中的一些基本概念。如I/P/B幀, GOP。
  2. 詳細講解了H264編碼的基本原理,包括:
  • 宏塊的劃分
  • 圖像分組
  • 幀內壓縮技術原理
  • 幀間壓縮技術原理。
  • DCT
  • CABAC壓縮原理。

但願以上內容能對您有所幫助。謝謝!

相關文章
相關標籤/搜索