h264的帧内预测plane模式算法分析

根据h264标准,16x16plane模式的预测过程如下所示:

 

上述公式标准中没有解释原理,网上也找不到相关资料。所以自己花了点时间分析了它,记录一下结果。

仔细观察上面式子可以看到,HV 代表了水平方向和垂直方向的梯度,b,cH,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;

这个算法中,同样用近似替代的方法,避免了除法。

算法效果如下:

最左,最上一行是参考像素,其他为预测值。

 

另一个例子:

 

欢迎留言交流指正。


猜你喜欢

转载自blog.csdn.net/soulmate_scut/article/details/80447343