H264编码器12( H264基本原理 --图文表达很清晰)
來自:https://blog.csdn.net/garrylea/article/details/78536775
?
前言
H264視頻壓縮算法現(xiàn)在無疑是所有視頻壓縮技術(shù)中使用最廣泛,最流行的。隨著 x264/openh264以及ffmpeg等開源庫的推出,大多數(shù)使用者無需再對H264的細(xì)節(jié)做過多的研究,這大降低了人們使用H264的成本。
但為了用好H264,我們還是要對H264的基本原理弄清楚才行。今天我們就來看看H264的基本原理。
H264概述
H264壓縮技術(shù)主要采用了以下幾種方法對視頻數(shù)據(jù)進(jìn)行壓縮。包括:
- 幀內(nèi)預(yù)測壓縮,解決的是空域數(shù)據(jù)冗余問題。
- 幀間預(yù)測壓縮(運(yùn)動估計與補(bǔ)償),解決的是時域數(shù)據(jù)冗徐問題。
- 整數(shù)離散余弦變換(DCT),將空間上的相關(guān)性變?yōu)轭l域上無關(guān)的數(shù)據(jù)然后進(jìn)行量化。
- CABAC壓縮。
經(jīng)過壓縮后的幀分為:I幀,P幀和B幀:
- I幀:關(guān)鍵幀,采用幀內(nèi)壓縮技術(shù)。
- P幀:向前參考幀,在壓縮時,只參考前面已經(jīng)處理的幀。采用幀音壓縮技術(shù)。
- B幀:雙向參考幀,在壓縮時,它即參考前而的幀,又參考它后面的幀。采用幀間壓縮技術(shù)。
除了I/P/B幀外,還有圖像序列GOP。
GOP:兩個I幀之間是一個圖像序列,在一個圖像序列中只有一個I幀。如下圖所示:
下面我們就來詳細(xì)描述一下H264壓縮技術(shù)。
?
H264壓縮技術(shù)
H264的基本原理其實(shí)非常簡單,下我們就簡單的描述一下H264壓縮數(shù)據(jù)的過程。通過攝像頭采集到的視頻幀(按每秒 30 幀算),被送到 H264 編碼器的緩沖區(qū)中。編碼器先要為每一幅圖片劃分宏塊。
以下面這張圖為例:
劃分宏塊
H264默認(rèn)是使用 16X16 大小的區(qū)域作為一個宏塊,也可以劃分成 8X8 大小。
劃分好宏塊后,計算宏塊的象素值。
以此類推,計算一幅圖像中每個宏塊的像素值,所有宏塊都處理完后如下面的樣子。
?
劃分子塊
H264對比較平坦的圖像使用 16X16 大小的宏塊。但為了更高的壓縮率,還可以在 16X16 的宏塊上更劃分出更小的子塊。子塊的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4非常的靈活。
上幅圖中,紅框內(nèi)的 16X16 宏塊中大部分是藍(lán)色背景,而三只鷹的部分圖像被劃在了該宏塊內(nèi),為了更好的處理三只鷹的部分圖像,H264就在 16X16 的宏塊內(nèi)又劃分出了多個子塊。
這樣再經(jīng)過幀內(nèi)壓縮,可以得到更高效的數(shù)據(jù)。下圖是分別使用mpeg-2和H264對上面宏塊進(jìn)行壓縮后的結(jié)果。其中左半部分為MPEG-2子塊劃分后壓縮的結(jié)果,右半部分為H264的子塊劃壓縮后的結(jié)果,可以看出H264的劃分方法更具優(yōu)勢。
宏塊劃分好后,就可以對H264編碼器緩存中的所有圖片進(jìn)行分組了。
?
幀分組
對于視頻數(shù)據(jù)主要有兩類數(shù)據(jù)冗余,一類是時間上的數(shù)據(jù)冗余,另一類是空間上的數(shù)據(jù)冗余。其中時間上的數(shù)據(jù)冗余是最大的。下面我們就先來說說視頻數(shù)據(jù)時間上的冗余問題。
為什么說時間上的冗余是最大的呢?假設(shè)攝像頭每秒抓取30幀,這30幀的數(shù)據(jù)大部分情況下都是相關(guān)聯(lián)的。也有可能不止30幀的的數(shù)據(jù),可能幾十幀,上百幀的數(shù)據(jù)都是關(guān)聯(lián)特別密切的。
對于這些關(guān)聯(lián)特別密切的幀,其實(shí)我們只需要保存一幀的數(shù)據(jù),其它幀都可以通過這一幀再按某種規(guī)則預(yù)測出來,所以說視頻數(shù)據(jù)在時間上的冗余是最多的。
為了達(dá)到相關(guān)幀通過預(yù)測的方法來壓縮數(shù)據(jù),就需要將視頻幀進(jìn)行分組。那么如何判定某些幀關(guān)系密切,可以劃為一組呢?我們來看一下例子,下面是捕獲的一組運(yùn)動的臺球的視頻幀,臺球從右上角滾到了左下角。
H264編碼器會按順序,每次取出兩幅相鄰的幀進(jìn)行宏塊比較,計算兩幀的相似度。如下圖:
通過宏塊掃描與宏塊搜索可以發(fā)現(xiàn)這兩個幀的關(guān)聯(lián)度是非常高的。進(jìn)而發(fā)現(xiàn)這一組幀的關(guān)聯(lián)度都是非常高的。因此,上面這幾幀就可以劃分為一組。其算法是:在相鄰幾幅圖像畫面中,一般有差別的像素只有10%以內(nèi)的點(diǎn),亮度差值變化不超過2%,而色度差值的變化只有1%以內(nèi),我們認(rèn)為這樣的圖可以分到一組。
在這樣一組幀中,經(jīng)過編碼后,我們只保留第一幀的完整數(shù)據(jù),其它幀都通過參考上一幀計算出來。我們稱第一幀為IDR/I幀,其它幀我們稱為P/B幀,這樣編碼后的數(shù)據(jù)幀組我們稱為GOP。
?
運(yùn)動估計與補(bǔ)償
在H264編碼器中將幀分組后,就要計算幀組內(nèi)物體的運(yùn)動矢量了。還以上面運(yùn)動的臺球視頻幀為例,我們來看一下它是如何計算運(yùn)動矢量的。
H264編碼器首先按順序從緩沖區(qū)頭部取出兩幀視頻數(shù)據(jù),然后進(jìn)行宏塊掃描。當(dāng)發(fā)現(xiàn)其中一幅圖片中有物體時,就在另一幅圖的鄰近位置(搜索窗口中)進(jìn)行搜索。如果此時在另一幅圖中找到該物體,那么就可以計算出物體的運(yùn)動矢量了。下面這幅圖就是搜索后的臺球移動的位置。
通過上圖中臺球位置相差,就可以計算出臺圖運(yùn)行的方向和距離。H264依次把每一幀中球移動的距離和方向都記錄下來就成了下面的樣子。
運(yùn)動矢量計算出來后,將相同部分(也就是綠色部分)減去,就得到了補(bǔ)償數(shù)據(jù)。我們最終只需要將補(bǔ)償數(shù)據(jù)進(jìn)行壓縮保存,以后在解碼時就可以恢復(fù)原圖了。壓縮補(bǔ)償后的數(shù)據(jù)只需要記錄很少的一點(diǎn)數(shù)據(jù)。如下所示:
?
我們把運(yùn)動矢量與補(bǔ)償稱為幀間壓縮技術(shù),它解決的是視頻幀在時間上的數(shù)據(jù)冗余。除了幀間壓縮,幀內(nèi)也要進(jìn)行數(shù)據(jù)壓縮,幀內(nèi)數(shù)據(jù)壓縮解決的是空間上的數(shù)據(jù)冗余。下面我們就來介紹一下幀內(nèi)壓縮技術(shù)。
幀內(nèi)預(yù)測
人眼對圖象都有一個識別度,對低頻的亮度很敏感,對高頻的亮度不太敏感。所以基于一些研究,可以將一幅圖像中人眼不敏感的數(shù)據(jù)去除掉。這樣就提出了幀內(nèi)預(yù)測技術(shù)。
H264的幀內(nèi)壓縮與JPEG很相似。一幅圖像被劃分好宏塊后,對每個宏塊可以進(jìn)行 9 種模式的預(yù)測。找出與原圖最接近的一種預(yù)測模式。
?
然后,將原始圖像與幀內(nèi)預(yù)測后的圖像相減得殘差值。
?
對殘差數(shù)據(jù)做DCT
可以將殘差數(shù)據(jù)做整數(shù)離散余弦變換,去掉數(shù)據(jù)的相關(guān)性,進(jìn)一步壓縮數(shù)據(jù)。如下圖所示,左側(cè)為原數(shù)據(jù)的宏塊,右側(cè)為計算出的殘差數(shù)據(jù)的宏塊。
?
做完 DCT 后,還不夠,還要進(jìn)行 CABAC 進(jìn)行無損壓縮。
?
CABAC
上面的幀內(nèi)壓縮是屬于有損壓縮技術(shù)。也就是說圖像被壓縮后,無法完全復(fù)原。而CABAC屬于無損壓縮技術(shù)。
無損壓縮技術(shù)大家最熟悉的可能就是哈夫曼編碼了,給高頻的詞一個短碼,給低頻詞一個長碼從而達(dá)到數(shù)據(jù)壓縮的目的。MPEG-2中使用的VLC就是這種算法,我們以 A-Z 作為例子,A屬于高頻數(shù)據(jù),Z屬于低頻數(shù)據(jù)。看看它是如何做的。
?
從上面這張圖中明顯可以看出采用 CACBA 的無損壓縮方案要比 VLC 高效的多。
?
小結(jié)
至此,我們就將H264的編碼原理講完了。本篇文章主要講了以下以點(diǎn)內(nèi)容:?
1. 簡音介紹了H264中的一些基本概念。如I/P/B幀, GOP。?
2. 詳細(xì)講解了H264編碼的基本原理,包括:
- 宏塊的劃分
- 圖像分組
- 幀內(nèi)壓縮技術(shù)原理
- 幀間壓縮技術(shù)原理。
- DCT
- CABAC壓縮原理。
?
總結(jié)
以上是生活随笔為你收集整理的H264编码器12( H264基本原理 --图文表达很清晰)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VSCODE配置C环境以及豆沙绿背景并且
- 下一篇: app mysql图片存储空间不足,光影