HEVC加权预测(Weight Prediction)原理兼解码代码

HEVC添加加权预测模式的原因:

现今很多视频中都采用的一种技术:场景随着时间光线强弱渐变(temporal illumination variation),或者相同场景,出现阴影效应。这样的视频,帧与帧之间,背景的相似度可能很高,明暗差别较大,若单纯采用运动预测,运动补偿技术,得到的残差会不够理想。此时,有人注意到,出现temporal illumination variation现象,相邻帧(或者相邻Slice)之间的像素值整体上都是渐变的(shape),逐渐变大或变小,相对前面的图像帧,当前帧相当于整体乘了一个数(weight),再加上一个偏移量(offset),编码效果就会大大改善。这就是加权预测。

加权预测原理解析

加权预测在H.264已经被提出来并且得到应用。加权预测应用于运动估计之后,它是以Slice为单位,每一帧的每一个Slice都需要单独地传输相应的加权预测参数。对与当前解码图像,它有两个参考链表L0和L1,编码端需要给L0和L1中的每一个参考图像的YUV三个分量分别传输相应的加权预测参数。 
在H.264中,加权预测存在两种模式,分别是explicit WP (EWP) 和 implicit WP(IWP)。 
IWP模式的加权预测参数都是固定的,编解码端约定好采用相同的加权预测参数,不需要编码端传输,减少了码流传输的压力,提高传输效率。 
由于IWP模式的参数都是固定的,所以它不能用于单向预测,因为当前帧跟参考帧的距离是变化的,导致权重会相差较大,采用固定的权重,效果不理想。所以在HEVC中,不存在IWP模式,只采用EWP模式,下面分析EWP模式。 
Explicit WP: 
EWP模式的加权预测参数是由编码端决定的,解码端需要从码流中读取得到相应的加权预测参数。采用EWP模式,编码端可以根据具体情况,灵活采用不同的参数。 
加权预测共有三个预测参数,分别是:weight(权重), offset(偏移量),LDW(log weight denominator)。具体计算方式如下式: 

    (1) 

    (2) 
上面两个式子,(1)式用于单向预测,(2)用于B帧的双向预测。P为像素预测值,W为权重,Q为偏移量,LX为参考链表L0或者L1。在编码端,为了避免浮点运算,需要将权重放大,放大的倍数为2的LWD次方,LWD的取值范围为[0,7]。解码端则缩小相应的倍数,是为了四舍五入。Clip()是控制像素值在有效值之内,如8比特的有效值为[0,255]。 
大致流程如下图所示(转): 

优化:

采用EWP模式,不管视频有没有光照衰弱效应,也就是Weight Prediction 有无压缩效果的情况下,编码端都需要将加权预测参数传输到解码端。此时: 
W = (1<<LWD), Offset = 0。代入(1)式跟(2)式,可以发现,此时相当于没采用加权预测的效果。所以我们需要对加权预测参数进行优化,减少传输。

(1)因为L0和L1的每个参考图像都有自己的加权预测参数,可以发掘他们之间的关系,减少传输次数。 
(2)每张图像的YUV三个分量都需要传输自己的加权预测参数,色度分量可以以亮度分量为预测值,减少传输大小。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的MATLAB代码示例,用于实现HEVC的帧内预测: ```matlab function [predBlock] = intra_predict(image, blockSize, row, col, mode) % image: 输入图像 % blockSize: 块大小 % row, col: 当前块的起始行和列 % mode: 帧内预测模式 % 获取参考像素 switch(mode) case 0 % 模式0:DC预测 refBlock = image(row:blockSize + row - 1, col:blockSize + col - 1); p = mean2(refBlock); predBlock = ones(blockSize, blockSize) * p; case 1 % 模式1:水平预测 refBlock = image(row:blockSize + row - 1, col - 1); predBlock = repmat(refBlock, [1, blockSize]); case 2 % 模式2:垂直预测 refBlock = image(row - 1, col:blockSize + col - 1); predBlock = repmat(refBlock, [blockSize, 1]); case 3 % 模式3:左上角预测 refBlock = image(row - 1, col - 1); predBlock = ones(blockSize, blockSize) * refBlock; case 4 % 模式4:右上角预测 refBlock = image(row - 1, col + blockSize); predBlock = ones(blockSize, blockSize) * refBlock; case 5 % 模式5:左下角预测 refBlock = image(row + blockSize, col - 1); predBlock = ones(blockSize, blockSize) * refBlock; case 6 % 模式6:垂直右下预测 refBlock1 = image(row - 1, col + blockSize); refBlock2 = image(row - 2, col + blockSize); refBlock3 = image(row - 3, col + blockSize); refBlock4 = image(row - 4, col + blockSize); refBlock5 = image(row - 5, col + blockSize); refBlock6 = image(row - 6, col + blockSize); refBlock7 = image(row - 7, col + blockSize); refBlock = (refBlock1 + 2 * refBlock2 + 3 * refBlock3 + 4 * refBlock4 + 5 * refBlock5 + 6 * refBlock6 + 7 * refBlock7 + 8) / 16; predBlock = ones(blockSize, blockSize) * refBlock; case 7 % 模式7:水平右下预测 refBlock1 = image(row + blockSize, col - 1); refBlock2 = image(row + blockSize, col - 2); refBlock3 = image(row + blockSize, col - 3); refBlock4 = image(row + blockSize, col - 4); refBlock5 = image(row + blockSize, col - 5); refBlock6 = image(row + blockSize, col - 6); refBlock7 = image(row + blockSize, col - 7); refBlock = (refBlock1 + 2 * refBlock2 + 3 * refBlock3 + 4 * refBlock4 + 5 * refBlock5 + 6 * refBlock6 + 7 * refBlock7 + 8) / 16; predBlock = ones(blockSize, blockSize) * refBlock; end end ``` 请注意,此代码仅实现了HEVC的帧内预测的一些基本模式,可能需要根据您的特定需求进行更改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值