H.264---去塊效應濾波
轉自:https://blog.csdn.net/dxpqxb/article/details/80312439
我們在觀看視訊的時候,在運動劇烈的場景常能觀察到影象出現小方塊,小方塊在邊界處呈現不連續的效果(如下圖),這種現象被稱為塊效應(blocking artifact)。
首先我們需要搞清楚塊效應產生的原因。h.264在編碼過程中對畫素殘差進行了DCT變換,變換後得到的DCT係數是與每個畫素都相關的,這些係數代表了被變換資料的基礎色調與細節。h.264在DCT變換後對DCT係數進行了量化,量化能有效去除相鄰畫素間的空間冗餘,也就是說會抹去元素資料的部分細節。比較理想的情況是量化抹去人眼無法識別的細節部分,但是在低位元速率的情況下就會導致原始資料的細節丟失過多。而且,DCT變換時基於塊的
h.264的運動補償加劇了由變換量化導致的塊效應。由於運動補償塊的匹配不可能絕對準確,各個塊的殘差大小程度存在差異,尤其是當相鄰兩個塊所用參考幀不同、運動向量或參考塊的差距過大時,塊邊界上產生的資料不連續就更加明顯。
塊效應主要有兩種形式:一種是由於DCT高頻係數被量化為0,使得強邊緣在跨邊界處出現鋸齒狀,稱為梯形噪聲;另一種經常出現在平坦區域,由於量化導致本來平緩變換的亮度塊DC係數發生跳躍,造成變換塊的基礎色調改變,這種稱為格形噪聲。
去塊濾波在編解碼器中的位置
為了減輕和消除視訊影象中的塊效應,通常會使用濾波器對塊邊界處的畫素進行濾波以平滑畫素值的突變,這種濾波被稱為去塊濾波器(Deblocking Filter)。
標準8.7小節中規定了去塊濾波的內容,這部分被稱為環路濾波器(loop filter)。環路濾波器是被放置在編解碼的影象重建環路當中。在啟用了環路濾波的編解碼環境中,無論是編碼器還是解碼器,都是在影象被重建後才進行濾波。在編碼器中,濾波後的影象會作為後續編碼運動補償的參考影象;在解碼器中,濾波後的影象會被輸出顯示並且作為後續影象解碼重建的參考影象。
濾波前的準備
1. 濾波引數
在標準中,去塊濾波會被應用於亮度以及色度巨集塊的濾波,語法元素disable_deblocking_filter_idc用於控制去塊濾波是否開啟,它的取值有三個:0~2。
- 0:開啟去塊濾波功能,去塊濾波能穿越slice邊界。
- 1:關閉去塊濾波功能。
- 2:開啟去塊濾波功能,但是濾波只能對同一個slice範圍內的巨集塊執行。
2. 濾波邊界
去塊濾波基於巨集塊進行,包括亮度塊以及色度塊。亮度塊的寬高為16x16巨集塊,而色度塊有幾種不同的格式,去塊濾波邊界如下圖:
圖中粗線條為濾波邊界,其中紅色粗線為水平邊界(Horizontal edge),藍色粗線為垂直邊界(Vertical edge),濾波邊界把巨集塊分割成多個4x4的塊。需要注意的一點是,如果transform_8x8_mode_flag為1,則代表亮度塊以及4:4:4的色度塊會採用8x8的DCT,此時亮度巨集塊以及4:4:4的色度巨集塊的濾波邊界會把巨集塊分割成8x8的塊。
濾波邊界還能根據濾波過程是否會用到當前巨集塊以外巨集塊來進行細分。巨集塊的頂部邊界、左邊界由於處於巨集塊邊緣,濾波的時候肯定需要用到相鄰巨集塊,而其餘的濾波邊界在濾波時只會用到當前巨集塊內部的畫素。
- Left MB Edge: 垂直方向上巨集塊最左邊的巨集塊濾波邊界
- 如果當前巨集塊為影象的最左邊巨集塊的話,不需要進行左邊界濾波
- 如果規定了只能用當前slice的巨集塊進行濾波(disable_deblocking_filter_idc=2),並且當前巨集塊與其左邊巨集塊不為同一slice,那也不需要進行左邊界濾波
- Vertical Internal Mb Edge: 垂直方向上的巨集塊內部濾波邊界。不同巨集塊型別其中包含的垂直內部濾波邊界的數量不同
巨集塊格式 Y 4:2:0 Cb/Cr 4:2:2 Cb/Cr 4:4:4 Cb/Cr 垂直內部濾波邊界數目 3 1 1 3 - Top MB Edge: 水平方向上巨集塊最頂部的巨集塊濾波邊界
- 如果當前巨集塊為影象的最頂部巨集塊的話,不需要進行頂部邊界濾波
- 如果規定了只能用當前slice的巨集塊進行濾波(disable_deblocking_filter_idc=2),並且當前巨集塊與其上方巨集塊不為同一slice,那也不需要進行頂部邊界濾波
- Vertical Internal Mb Edge: 垂直方向上的巨集塊內部濾波邊界。不同巨集塊型別其中包含的垂直內部濾波邊界的數量不同
巨集塊格式 Y 4:2:0 Cb/Cr 4:2:2 Cb/Cr 4:4:4 Cb/Cr 水平內部濾波邊界數目 3 1 3 3
濾波先進行亮度巨集塊濾波後進行色度巨集塊濾波,對一個巨集塊濾波邊界的濾波也需要遵循一定順序
- 先進行垂直邊界濾波,從左到右
- 後進行水平邊界濾波,從上到下
3. 濾波源畫素選擇
去塊濾波所用的源畫素分佈在邊界的兩邊,分別有4個畫素點,如下圖所示
p與q畫素所在的4x4或者8x8塊我們分別成之為P塊與Q塊。
如果當前編碼的影象以幀或者場的方式進行編碼,則可以直接按照上述邊界兩邊的位置得到濾波的源畫素點。不過如果影象採用幀場自適應方式進行編碼(MBAFF),則需要對邊界兩邊的畫素進行定位以得到正確的源畫素。
我們在前面已經討論過,塊效應是由於對塊(block)進行DCT變換量化產生的,去塊濾波的目的是消除塊效應,因此去塊濾波需要正確地定位出進行DCT變換量化的塊。在幀場自適應的編碼環境下,巨集塊可以以幀或者場的方式進行編碼,但是在巨集塊進行重建後得到的都是幀巨集塊,因此我們需要根據實際情況定位出當時進行DCT變換量化的塊所在的畫素。
以下是在幀場自適應編碼環境下,一個垂直邊界濾波畫素定位的事例
以下是在幀場自適應編碼環境下,一個水平邊界濾波畫素定位的事例
另外,在幀場自適應的編碼環境下,如果當前巨集塊為幀巨集塊,它的上方巨集塊為場巨集塊,那麼在進行頂部邊界濾波時需要進行兩條邊界的濾波
濾波過程
1. 估算邊界強度
對於濾波邊界,我們首先需要根據邊界所在的位置已以及巨集塊的資訊來粗略地估計邊界兩邊的畫素差距,我們稱這個畫素差距為邊界強度(BS,Boundary Strength)。
判斷條件 | 邊界強度 BS |
---|---|
P塊或者Q塊為幀內編碼模式,並且塊邊緣為巨集塊邊緣 | 4 |
P塊或者Q塊為幀內編碼模式 | 3 |
P塊或者Q塊的殘差變換系數包含非零係數 | 2 |
P塊或者Q塊的殘差變換系數都不包含非零係數,並且P塊和Q塊的參考幀或運動向量數目(前後向)不同 | 1 |
P塊或者Q塊的殘差變換系數都不包含非零係數,並且P塊和Q塊的參考幀以及運動向量數目(前後向)相同 | 0 |
上述表格用於亮度BS的計算,色度巨集塊的BS沿用其相應亮度巨集塊的BS。由於表格的描述不盡詳細,詳情請參考標準8.7.2.1
2. 區分真假邊界
在粗略地估算濾波邊界強度後,我們需要區分這個邊界強度是由於對塊進行DCT變換量化引起的塊效應(虛假邊界)還是視訊影象原有的邊界(真實邊界)。如果是真實邊界則不需要進行濾波,如果是虛假邊界則需要進行去塊濾波。區分真假邊界基於下面兩個假設:
- 真實邊界兩邊畫素點的差值通常比虛假邊界兩邊畫素值要大
- 對於兩邊畫素值差別很小的真實邊界,即使使用了去塊濾波,對它的主觀效果不會有太大影響
因此,去塊濾波應該遵循以下原則:
- 在平坦區域,即使很小的畫素不連續也很容易被人察覺,所以要使用比較強的去塊濾波,可以改變較多的畫素點
- 對於複雜的區域,為了保持影象細節,要使用較弱的去塊濾波,改變較少的畫素點
假設下圖為畫素點的亮度值分佈圖,這種情況下兩邊畫素點的差值非常大,根據上面的假設,在p0和q0之間出現的是物體的真實邊界,因而不需要進行濾波。
標準h.264中設定了兩個閾值α和β來判斷真假邊界,α表示塊與塊之間的邊界閾值,β表示塊內部邊界的閾值。對於邊界兩邊的畫素點的差值,如果下面三個條件都滿足就會被判定為需要濾波的虛假邊界,否則就判定為不需要濾波真實邊界。
|p0 - q0| < α[IndexA]
|p1 - p0| < β[IndexB]
|q1 - q0| < β[IndexB]
其中α與β可以通過IndexA以及IndexB從表格中得到。IndexA以及IndxeB為表格的索引,他們的計算方法如下
IndexA = Clip3( 0, 51, QPaverage + FilterOffsetA )
IndexB = Clip3( 0, 51, QPaverage + FilterQffsetB )
其中QPaverage = ( QPp+QPq+1) / 2,FilterOffsetA以及FilterOffsetB則為偏移量,偏移量用於調整濾波強度。當需要增加濾波強度時,用正偏移量,可以去除由次優運動估計、編碼模式選擇不當引起的塊效應,改善影象主觀質量;當需要減少濾波強度時,用負的偏移量,可以保護影象細節不被濾波器的平滑作用模糊掉。偏移量將在slice頭資訊中傳輸,請參考h.264語法結構分析中的deblocking相關語法元素。
Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
α | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | 13 |
β | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 2 | 2 | 3 | 3 | 3 | 3 | 4 | 4 | 4 |
Index | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
α | 15 | 17 | 20 | 22 | 25 | 28 | 32 | 36 | 40 | 45 | 50 | 56 | 63 | 71 | 80 | 90 | 101 | 113 | 127 | 144 | 162 | 182 | 203 | 226 | 255 | 255 |
β | 6 | 6 | 7 | 7 | 8 | 8 | 9 | 9 | 10 | 10 | 11 | 11 | 12 | 12 | 13 | 13 | 14 | 14 | 15 | 15 | 16 | 16 | 17 | 17 | 18 | 18 |
由上述式子知道,α與β的取決於QP的大小,IndexA、IndexB與α、β對應值見下表
可見QP越大(Index越大),α與β就越大。QP越大意味著量化誤差越大,塊效應會越明顯,因此閾值也應該取較大值來增大濾波效果,反之閾值應該取較小值。
3. 濾波運算
在前面我們討論了5種邊界強度BS,當邊界強度不為0時,就需要進行邊界濾波。h.264的邊界濾波有兩種濾波器
- BS = 1,2,3,採用強度較弱的濾波器,首先改變p0、q0兩個畫素點,接著用閾值β判斷是否需要調整p1和q1
- BS = 4,此時有兩種強度的濾波器,強濾波器可以改變6個畫素點(p0、p1、p2、q0、q1、q2),弱濾波器只改變邊界上的兩個點(p0、q0)
(1) BS = 1,2,3時的濾波運算
①首先對邊界上的兩個畫素點p0與q0進行濾波,它需要輸入p1、p0、q0、q1,濾波過程如下
- 先要得到差值Δ,差值的計算方式:Δ = ( (q0-p0)<<2 + (p1-q1) + 4 ) >> 3
- 然後需要對差值Δ進行限幅,保證這個差值在一定的範圍內,這個範圍主要通過查表得到,詳情請檢視標準8.7.2.3
- 用差值Δ來計算新的p0、q0,也就是濾波後的值
②接下來對塊內的畫素點p1與q1分別進行濾波。4:2:0以及4:2:2色度巨集塊邊界的話是不需要執行這部分的濾波的。如果是要計算p1,則需要輸入p2、p1、p0、q0;如果是q1,則需要輸入p0、q0、q1、q2。
另外,只有滿足|p2-p0|<β才能對p1進行濾波,因為滿足這個條件則認為P塊內部p1處有虛假邊界,p1的濾波過程如下
- 先要得到差值Δ,差值的計算方式為:Δ = ( p2 + ((p0+q0+1)>>1) − (p1<<1)) >> 1
- 然後需要對差值Δ進行限幅,保證這個差值在一定範圍內,這個範圍主要通過查表得到,詳情請檢視標準8.7.2.3
- 用差值來計算新的p1
q1的濾波過程也是類似的步驟。
(2) BS = 4時的濾波運算
在h.264的幀內預測編碼中,傾向於對紋理簡單的區域用16x16亮度預測模式編碼(如藍天、白色牆面等),以達到快速編碼的目的。雖然這種方法只會在巨集塊邊界引起輕微的塊效應,但是在這種情況下,即使很小的強度值查表也會在視覺上產生陡峭的階梯狀的感覺(色塊分層),因而對於這種內容平滑的巨集塊邊界就需要採用較強的濾波器;如果此時巨集塊邊界有大量的細節存在,反而不應做強濾波。對此h.264仍採用閾值法來判斷是否存在真實邊界,如果不存在大量細節資訊,可以做強濾波,反之做弱濾波。
這裡的濾波是比較好理解的抽頭濾波器,P、Q塊上的濾波過程差不多,這裡以P塊為例。
對於P塊的點,如果滿足下式,則認為細節資訊不多:
採用強濾波
否則採用弱濾波,只改變p0點
參考文獻
ITU-T Rec. H.264 (04-2013) Advanced video coding for generic audiovisual services
陳靖、劉京、曹喜信:深入理解視訊編解碼技術——基於H.264標準及參考模型