一、方块效应
目前主流的视频编码标准都是基于分块的混合编码机制,其处理过程是针对每个块单独进行处理的,因此由于编码模式的差异以及量化误差的原因,会导致相邻块重建像素不连续的现象。对于一个两侧强相关性的块边界,当图像较平滑时,就会在重建图像中出现方块效应,如下图所示。
方块效应产生的原因主要包括以下两个方面:
- 一是由变换、量化的误差引起的。在视频编码中,量化是一个有损压缩过程,因此在反量化、反变换之后的重建图像会出现误差,由于不同块之间的处理不一致,而且边界处的误差格外大一些,会造成图像在边界上的视觉不连续。
- 二是来自帧间的运动补偿过程。对于相邻块,其运动补偿的预测数据可能来自同一帧的不同位置、不同帧不同的位置,因此会产生误差,引起图像在复制的边界上的不连续现象。
为了消除或者减轻块效应,通常使用去块滤波(DBF)修正图像边界处的像素值。
二、VVC中的去块滤波
VVC中与HEVC的去块滤波过程类似。在VVC中,对CU边界、变换子块边界和预测子块边界进行去块滤波处理。预测子块边界包括由SbTMVP和仿射模式引入的预测单元PU边界,变换子块边界包括由SBT和ISP模式引入的变换单元边界,以及由于大CUs的隐式划分而引起的变换。对CU边界和变换子块边界采用4x4滤波处理网格,对预测子块边界采用8x8滤波处理网格。对于SBT和ISP子块,类似于HEVC去块滤波器中TU的逻辑,当任一变换子块的边缘有非零系数时,在TU边界上应用去块滤波器。对于SbTMVP和仿射预测子块,类似于HEVC中PU中的逻辑,在8x8网格上应用去块滤波器,同时考虑相邻预测子块的运动矢量和参考图片之间的差异。变换块边界最多可以用变换边界一侧的5个样本去块,变换边界也是编码块的一部分,其中SbTMVP或affine用于实现并行友好去块。内部预测子块边界来自变换块边界的4个样本在每侧最多滤波1个样本,内部预测子块边界远离变换块边界的8个样本在边界的每侧最多滤波2个样本,并且其他内部预测子块边界在边界的每侧最多滤波3个样本。
针对亮度滤波,VVC对“大块”引入了双线性滤波器(更强滤波),“大块”即边界长度大于等于32的块。亮度分量的滤波器分类如下:
- 更强滤波,最多可达每侧边界的7个像素
- 强滤波,对边界像素每边修改3个像素
- 弱滤波,最多对边界两边修改2个像素
由于VVC的二叉树、三叉树划分引入矩形块,所以VVC中亮度使用4x4大小的滤波处理单元。
针对色度滤波,主要分为以下两种滤波器:
- 强滤波,对边界每边修改3个像素
- 弱滤波,对边界每侧修改1个像素
色度滤波仅使用8x8的滤波处理单元。
以8x8滤波处理单元为例,每个处理块横跨4个8x8的呈“+”字形的边界, 如下图所示,边界两侧块分别用P(垂直边界左侧块或者水平边界上侧块)和Q(垂直边界右侧块和水平边界下侧块)表示。对于需要滤波的边界,按照先亮度分量后色度分量的顺序;对于同一分量的块,按照先垂直边界后水平边界的顺序。
VVC的去块滤波过程和HEVC的类似,主要包含三个步骤
- 根据边界两侧的编码模式和编码参数确定边界强度
- 根据边界两侧像素值,确定滤波强度(包括滤波开关决策和滤波强度决策)
- 进行滤波处理过程
1、边界强度(BS)的判定
由于视频块的相邻边界采用不同的编码参数, 例如不同的预测方式、 不同运动矢量、不同参考图像等,容易引起块边界像素值的不连续,VVC 根据这些编码参数,确定其不同滤波类型。VVC中边界强度有3中,分别对应BS=0、1、2三个等级。对于每个待处理边界,按照如下表的优先级顺序依次进行判断,若某个优先级的条件已被满足,则直接可以得出该边界的边界强度 BS而不用再进行判断。
对于亮度分量,BS=2 或 1 表示需要进行滤波,BS=0 表示不需要进行滤波。对于色度分量,BS=2 或者BS=1且为大块边界表示需要进行滤波,其余情况不需要进行滤波。
优先级 | 条件 | BS | ||
Y | U | V | ||
6 | 相邻块中的至少一个用intra或CIIP模式编码 | 2 | 2 | 2 |
5 | 相邻块中的至少一个具有非零变换系数 | 1 | 1 | 1 |
4 | 相邻块中的一个以IBC预测模式编码,另一个以帧间预测模式编码 | 1 | 1 | 1 |
3 | 属于相邻块的运动矢量之间的绝对差大于或等于半个亮度样本 | 1 | 0 | 0 |
2 | 两个相邻块所指的参考帧不同 | 1 | 0 | 0 |
1 | 其余情况 | 0 | 0 | 0 |
2、滤波强度的判定
①滤波开关和滤波强度阈值参数
滤波开关和滤波强度的阈值参数β和和边界两边的QP值有关(即P块的和Q块的)的平均有关:
其中偏移量qpOffset由重建像素的平均亮度级LL决定。
阈值参数β和通过查表可得到。
const int iIndexTC = Clip3(0, MAX_QP + DEFAULT_INTRA_TC_OFFSET, int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs - 1) + (tcOffsetDiv2 << 1)));
const int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1));
const uint16_t LoopFilter::sm_tcTable[MAX_QP + 1 + DEFAULT_INTRA_TC_OFFSET] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 4, 4,
4, 5, 5, 5, 5, 7, 7, 8, 9, 10, 10, 11, 13, 14, 15, 17, 19, 21, 24, 25, 29, 33,
36, 41, 45, 51, 57, 64, 71, 80, 89, 100, 112, 125, 141, 157, 177, 198, 222, 250, 280, 314, 352, 395
};
const uint8_t LoopFilter::sm_betaTable[MAX_QP + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24,
26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88 };
②滤波开关决策
由于人眼的空间掩蔽效应,图像平坦区域的不连续边界更容易被观察到。如图(a)所示,当边界两侧的像素值相对平滑,但在边界处呈现较大的差异时,人眼可以明显的识别出这种位于边界处的不连续。然而,当边界两侧的像素值呈现高度变化的现象,如图(b)所示,此时这种不连续难以察觉。当边界两侧变化剧烈时边界处的不连续可能是由视频内容自身导致。另外,滤波会减弱强纹理区域应有的纹理信息。滤波开关决策就是根据边界块内像素值的变化程度判断该边界的内容特性,然后根据内容特性确定是否需要进行滤波操作。
下图是一个垂直块边界区域示意图。p(x,y),q(x,y)分别是边界两侧的像素值。
定义首行和末行像素的变化率。
该垂直块边界的纹理度定义为;
纹理度值越大表明该区域越不平坦,当大到一定程度时该边界不需要滤波。当CB < β时,该边界需要进行滤波,否则不需要。
阈值β为滤波开关的判决门限,其与边界两侧的量化参数Qp相关。
在VVC中,引入了“大块边界”,即边界长度大于等于32的块,对于该类型的块,其开关决策类似,由于其滤波的边界像素数增加,所以其滤波开关决策计算变化率使用的像素数也增加了。
③滤波强度决策
在滤波开关打开的前提下,滤波前需要判断滤波的强度
上面3种边界情况,(a)与(b)相比,边界两侧像素平坦而边界处变化剧烈,在视觉上会形成更强的块效应,需要对边界周围像素进行大范围、大幅度修正。(c)边界处像素变化特别大,由于失真总会处于一定范围,当差值超出一定范围后,这种块边界则是由视频内容本身所致。
若以下条件满足,则进行强滤波。前两个式子用于判断边界两侧像素的变化率;中间两个式子用于保证边界两侧像素平坦;最下面两个用于保证边界处像素跨度在合理范围内,避免对视频内容本身导致的边界错误地进行滤波
如果 P 块或 Q 块中至少有一个是“大块”(长或宽≥32 的块),在进行滤波强度决策时,判断边界两侧的平坦度所用到的像素增加。
其中参数β和tc和Qp相关,随着Qp的增加,它们的值也会迅速增加。
3、滤波处理过程
(a)亮度分量的更强滤波
亮度的更强滤波是VVC中新加入的滤波器,使用双线性滤波器,并修改更多的像素值,最多可达每块的每行 7 个像素。其修改后的像素值用下列式表示
相关参数如下;
(b)亮度分量的强滤波
强滤波需要对每块的每行 3 个像素进行修正,其修改后的像素值用下列式表示
(c)亮度分量的弱滤波
弱滤波修正的像素范围和幅度较小。最多需要修正的像素为边界两侧各2个像素。需要根据每行像素具体情况进行滤波操作。首先计算该行边界像素的变化程度:
如果,说明这种不连续可能是视频内容导致的,故该行像素不需要滤波;否则,需要对p(0,0) , q(0, 0)修正
对于某些情况,需要判断是否需要对p(1,0) , q(1, 0)进行修正:
(d)色度分量的强滤波
色度分量的强滤波与亮度类似,也对每个块的每行 3 个像素进行修正,其修改后的像素值用下列式表示:
(e)色度分量的弱滤波
色度分量的弱滤波仅对每块的每行 1 个像素进行修正,即紧靠边界的像素。其修改后的像素值用下列式表示: