根據h264標準,16x16塊plane模式的預測過程如下所示:
上述公式標準中沒有解釋原理,網上也找不到相關資料。所以自己花了點時間分析了它,記錄一下結果。
仔細觀察上面式子可以看到,H和V 代表了水平方向和垂直方向的梯度,b,c是H,V的縮放,其中+32是爲了做到四捨五入。a代表了右上像素和坐下像素的均值。
對這些值進行縮放和移位操作,是爲了避免除法,下面會有更詳細的說明。
宏塊最中間的像素P(7,7)的預測值是右上像素和坐下像素的均值,其他像素根據到中間點的距離和兩個方向的梯度算出。
這種算法可以根據左鄰像素和右鄰像素的值和趨勢,預測整個宏塊的值。下面是一個例子。最上面一行和最座標一行是參考像素,其他是預測值。
[[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
[ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]
[ 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
[ 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
[ 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21]
[ 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22]
[ 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
[ 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]
[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]
[11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27]
[12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28]
[13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]
[14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30]
[15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]
[16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32]]
圖像如下:
下面分析h264中平面模式預測公式的由來。
首先爲了簡化問題,假設左鄰像素都爲0,上鄰近像素爲
P[x, -1]= x+1 , x = [-1:15]
期望得到的預測值如下:
[[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]]
根據式子 8-122 此時H=408
設M 爲右上像素和左下像素的均值,M= (p[15,-1]+p[-1,15])/2 = 8
則預測值應爲
P[x,y] = M + α * p[x-7]
其中α代表水平方向的梯度,也即α = dP[x,y]/dx = 1
此時 α=H/408
這個式子可以推廣到H值爲其他的情況。
所以預測公式爲:
P[x,y] = M + H/408 * p[x-7]
可以根據這個公式進行plane模式的預測。但是這個公式存在一個除法,在計算機中,除法指令的執行時間通常是加法或者乘法的幾十倍。所以對上述公式做一下改造:
其中32M 即爲公式8-119 中的a
分子右半部分即爲公式8-120種的b
分母32即爲公式8-118種右移5位的操作。
將豎直方向的梯度也考慮進來,就是h264種的平面預測方法。
這個算法的關鍵是用2^11 = 2024替代5*408=2040,避免了除法。
分析這麼多,先現在可以小試一下牛刀,假設I8x8有plane模式(當然h264沒有),推導一下I8x8的平面預測公式。
編輯公式太耗時,直接看代碼吧。
def predict8_p(pred,x0, y0,src):
H = np.long(0)
V = np.long(0)
for i in range(4):
H += (i + 1) * (int(src[y0 - 1, x0 + 4 + i]) - int(src[ y0 - 1,x0 + 2 - i]));
V += (i + 1) * (int(src[y0 + (4 + i), x0 - 1]) - int(src[ y0 + (2 - i),x0-1]));
#print(H)
a = 32 * (int(src[y0 + 7,x0 - 1, ]) + int(src[ y0 - 1,x0 + 7,]));
b = np.floor((17 * H + 8) / 16);
c = np.floor((17 * V + 8) / 16 );
i00 = a - b * 3 - c * 3 + 32;
for y in range(8):
pix = i00;
for x in range(8):
pred[y0+y,x0+x] = clip_pixel(np.floor(pix/64));
pix += b;
i00 += c;
這個算法中,同樣用近似替代的方法,避免了除法。
算法效果如下:
最左,最上一行是參考像素,其他爲預測值。
另一個例子: