天天看點

H264視訊壓縮算法

H264視訊壓縮算法現在無疑是所有視訊壓縮技術中使用最廣泛,最流行的。随着 x264/openh264以及ffmpeg等開源庫的推出,

大多數使用者無需再對H264的細節做過多的研究,這大降低了人們使用H264的成本。

但為了用好H264,我們還是要對H264的基本原理弄清楚才行。今天我們就來看看H264的基本原理。

H264概述

H264視訊壓縮算法

H264壓縮技術主要采用了以下幾種方法對視訊資料進行壓縮。包括:

(1) 幀内預測壓縮:解決的是空域資料備援問題。

(2) 幀間預測壓縮:(運動估計與補償),解決的是時域資料備援問題。

(3) 整數離散餘弦變換(DCT):将空間上的相關性變為頻域上無關的資料,然後進行量化。

(4) CABAC壓縮。

經過壓縮後的幀分為:I幀,P幀和B幀:

I幀:關鍵幀,采用幀内壓縮技術。

P幀:向前參考幀,在壓縮時,隻參考前面已經處理的幀。采用幀間壓縮技術。

B幀:雙向參考幀,在壓縮時,它即參考前面的幀,又參考它後面的幀。采用幀間壓縮技術。

圖像序列GOP:

  • GOP:兩個I幀之間是一個圖像序列;一個圖像序列中隻有一個I幀。
H264視訊壓縮算法

H264基本原理

下我們就簡單的描述一下H264壓縮資料的過程。通過攝像頭采集到的視訊幀(按每秒 30 幀算),被送到 H264 編碼器的緩沖區中。編碼器先要為每一幅圖檔劃分宏塊。

1、劃分宏塊

H264預設是使用 16X16 大小的區域作為一個宏塊,也可以劃分成 8X8 大小的宏塊。

H264視訊壓縮算法

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

H264視訊壓縮算法

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

H264視訊壓縮算法

2、劃分子塊

H264對比較平坦的圖像使用 16X16 大小的宏塊。但為了更高的壓縮率,還可以在 16X16 的宏塊上更劃分出更小的子塊。

子塊的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4,非常的靈活。

H264視訊壓縮算法

上幅圖中,紅框内的 16X16 宏塊中大部分是藍色背景,而三隻鷹的部分圖像被劃在了該宏塊内,

為了更好的處理三隻鷹的部分圖像,H264就在 16X16 的宏塊内又劃分出了多個子塊。

H264視訊壓縮算法

這樣再經過幀内壓縮,可以得到更高效的資料。

下圖是分别使用mpeg-2和H264對上面宏塊進行壓縮後的結果。

其中左半部分為MPEG-2子塊劃分後壓縮的結果,右半部分為H264的子塊劃壓縮後的結果,可以看出H264的劃分方法更具優勢。

H264視訊壓縮算法

宏塊劃分好後,就可以對H264編碼器緩存中的所有圖檔進行分組了。

3、幀分組

對于視訊資料主要有兩類資料備援,一類是時間上的資料備援,另一類是空間上的資料備援。其中時間上的資料備援是最大的。

為什麼說時間上的備援是最大的呢?假設攝像頭每秒抓取30幀,這30幀的資料大部分情況下都是相關聯的。也有可能不止30幀的的資料,可能幾十幀,上百幀的資料都是關聯特别密切的。

對于這些關聯特别密切的幀,其實我們隻需要儲存一幀的資料,其它幀都可以通過這一幀再按某種規則預測出來,是以說視訊資料在時間上的備援是最多的。

為了達到相關幀通過預測的方法來壓縮資料,就需要将視訊幀進行分組。那麼如何判定某些幀關系密切,可以劃為一組呢?

我們來看一下例子,下面是捕獲的一組運動的撞球的視訊幀,撞球從右上角滾到了左下角。

H264視訊壓縮算法

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

H264視訊壓縮算法

通過宏塊掃描與宏塊搜尋可以發現這兩個幀的關聯度是非常高的。進而發現這一組幀的關聯度都是非常高的。是以,上面這幾幀就可以劃分為一組。

幀分組算法是:在相鄰幾幅圖像畫面中,一般有差别的像素隻有10%以内的點,亮度內插補點變化不超過2%,而色度內插補點的變化隻有1%以内,我們認為這樣的圖可以分到一組。

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

4、運動估計與補償(幀間預測)

在H264編碼器中将幀分組後,就要計算幀組内物體的運動矢量了。還以上面運動的撞球視訊幀為例,我們來看一下它是如何計算運動矢量的。

H264編碼器首先按順序從緩沖區頭部取出兩幀視訊資料,然後進行宏塊掃描。當發現其中一幅圖檔中有物體時,就在另一幅圖的鄰近位置(搜尋視窗中)進行搜尋。

如果此時在另一幅圖中找到該物體,那麼就可以計算出物體的運動矢量了。

H264視訊壓縮算法

通過上圖中撞球位置相差,就可以計算出台圖運作的方向和距離。

H264依次把每一幀中球移動的距離和方向都記錄下來就成了下面的樣子:

H264視訊壓縮算法

運動矢量計算出來後,将相同部分(也就是綠色部分)減去,就得到了補償資料。我們最終隻需要将補償資料進行壓縮儲存,

以後在解碼時就可以恢複原圖了。壓縮補償後的資料隻需要記錄很少的一點資料。

我們把運動矢量與補償稱為幀間壓縮技術,它解決的是視訊幀在時間上的資料備援。

除了幀間壓縮,幀内也要進行資料壓縮,幀内資料壓縮解決的是空間上的資料備援。下面我們就來介紹一下幀内壓縮技術。

5、幀内預測

人眼對圖象都有一個識别度,對低頻的亮度很敏感,對高頻的亮度不太敏感。是以基于一些研究,可以将一幅圖像中人眼不敏感的資料去除掉。這樣就提出了幀内預測技術。

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

幀内預測後的圖像與原始圖像的對比如下:

H264視訊壓縮算法

然後,将原始圖像與幀内預測後的圖像相減得殘內插補點。

H264視訊壓縮算法

再将我們之前得到的預測模式資訊一起儲存起來,這樣我們就可以在解碼時恢複原圖了。效果如下:

H264視訊壓縮算法

經過幀内與幀間的壓縮後,雖然資料有大幅減少,但還有優化的空間。

6、對殘差資料做DCT轉換

可以将殘差資料做整數離散餘弦變換,去掉資料的相關性,進一步壓縮資料。

如下圖所示,左側為原資料的宏塊,右側為計算出的殘差資料的宏塊。

H264視訊壓縮算法

将殘差資料宏塊數字化後如下圖所示:

H264視訊壓縮算法

将殘差資料宏塊進行 DCT 轉換。

H264視訊壓縮算法

去掉相關聯的資料後,我們可以看出資料被進一步壓縮了。

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

7、CABAC 壓縮

上面的幀内壓縮是屬于有損壓縮技術。也就是說圖像被壓縮後,無法完全複原。而CABAC屬于無損壓縮技術。

無損壓縮技術大家最熟悉的可能就是哈夫曼編碼了,給高頻的詞一個短碼,給低頻詞一個長碼進而達到資料壓縮的目的。

MPEG-2中使用的VLC就是這種算法,我們以 A-Z 作為例子,A屬于高頻資料,Z屬于低頻資料。看看它是如何做的。

H264視訊壓縮算法

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

H264視訊壓縮算法

現在将 A-Z 換成視訊幀,它就成了下面的樣子。

H264視訊壓縮算法

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

小結

至此,我們就将H264的編碼原理講完了。本篇文章主要講了以下以點内容:

1. 簡音介紹了H264中的一些基本概念。如I/P/B幀, GOP。

2. 詳細講解了H264編碼的基本原理,包括:

宏塊的劃分

圖像分組

幀内壓縮技術原理

幀間壓縮技術原理。

DCT

CABAC壓縮原理。

希望以上内容能對您有所幫助。謝謝!

原文網址:https://blog.csdn.net/garrylea/article/details/78536775 

本文有小的修改、删減。

H264視訊壓縮算法