H264-变换和量化

在早期的标准中,不同的处理步骤之间有明显的边界,对原始数据(或者残差)进行域变换,然后进行量化降低系数的精度,但是在H264中边界却不明显。为了消除浮点数DCT变换造成的误差累计,使用整数DCT变换,并且将放大系数移到量化阶段进行。

在DCT变换当中,存在有无理数系数。在不同精度的机器上的编码图像和解码图像之间,或者在同一个编码器的重建图像之间,会出现误差漂移和累计。h264通过下面的两个方法解决这个问题:

  • 使用核变换,是整数DCT变换,只需要使用整数和定点数运算
  • 使用最少的乘法优化量化操作

基本流程

h264标准中定义了反量化,反系数放大和反变换的过程,相应的正变换没有标准化,但是可以从标准中定义的操作中推导出来。
在这里插入图片描述
基本变换是整数变换,整数变换是一种经过系数放大和整数近似的DCT变换,对4x4或者8x8的残差数据进行变换。直流系数变换使用哈达玛变换。最后经过系数放大和量化。解码端是这个过程的逆向过程。

在这里插入图片描述

亮度分量变换过程

默认处理过程

在这里插入图片描述
在除了下面两种情况下都使用默认处理过程。

  1. 16 × 16 Intra Prediction
  2. High profiles 8 × 8 整数变换

对16x16 残差宏块内每一个4x4 子宏块做core transform Cf4,然后对每一个4x4宏块做Scaling和quantization Mf4,获得量化系数块,量化系数块在生成bitstream时使用标号的顺序。上图容易出现一个错误的理解是,先划分出16x16宏块,让后对内部的4x4块分别进行操作。实际的顺序是对每一个4x4子块进行整个操作,顺序为标号顺序,每一个4x4子块获得量化系数能直接进行反操作,获得重建块用来对下一个字块进行预测。从总体上来看相当于画出16x16块。
在这里插入图片描述
逆过程如上图所示。

Intra 16 × 16 mode

在这里插入图片描述
如果宏块使用的是16x16帧内预测模式,那么就是用上面的变换过程。使用另外的变换对4x4block中的直流系数进行变换。16x16的残差数据经过划分成4x4block经过整数变换获得变换系数。从16个block中提取出DC系数组成新的4x4数据block,直流系数高度相关对这一部分进行重新编码能获得更好的效果,这里使用4x4哈达玛变换。变换后的DC系数和AC系数一起经过
经过放大和量化,在bitstream中传输顺序如标号所示。
逆过程如下图:
在这里插入图片描述

色度分量变换过程

4:2:0 色度分量变换过程

色度分量4:2:0格式下,一个宏块16 x16的亮度sample对应有一个8x 8个Cb数据的宏块和8 x8 Cr数据的宏块。
在这里插入图片描述
Cb Cr两个8 x8大小的宏块,每一个划分为4个4*4大小的宏块,经过Cf4 整数变换,获得变换系数block,从两个8 x8 大小的系数block中提取出DC系数分别组成两个2 x 2block 进行DC 哈达玛变换,然后连同AC系数进行Mf4,生成的数据block在bitstream中的排序如上图。

逆过程如下图:
在这里插入图片描述

4:2:2 色度分量变换过程

色度分量4:2:2格式下,一个宏块16 x16的亮度sample对应有一个8x16个Cb数据的宏块和8 x 16Cr数据的宏块。
在这里插入图片描述

4x4 block的变换和量化

正向变换和量化

从上边的叙述看出主要变换和量化的动作都是基于4x4block的,就是上边的Cf4和Mf4操作。
在这里插入图片描述

  • (a) 4x4 大小的残差数据,经过4 x 4 二维DCT变换,然后使用Qstep进行量化。
  • (b) 将DCT变换重新组织为core transform Cf4和 放大矩阵Sf4
  • © 将量化过程放大215 , 215 是精确度要求和有限的数字精度的折中。
  • (d) 将Sf与量化过程合并获得Mf
    Mf=Sf∗215Qstep M_{f} = \cfrac{S_{f} * 2^{15}}{Q_{step}}Mf=QstepSf215

反向放大和量化过程

这部分是在标准中标准化的部分。
在这里插入图片描述

  • (a) 逆过程首先乘以量化参数,然后进行4 x4 IDCT.
  • (b) 将IDCT 重组为 core transform 反变换Ci 和 反放大系数矩阵Si ,反放大系数矩阵操作在前。
  • © 将量化参数乘以26 系数,然后在最后进行乘以倒数进行补偿
  • (d) 将反放大过程和Si 组合成Vi 过程。
    Vi=Qstep∗26∗Si V_{i} = Q_{step} * 2^{6} * S_{i}Vi=Qstep26Si

Cf4 和 Sf4的导出

二维离散余弦变换
F(u,v)=c(u)c(v)∑x=0M−1∑y=0N−1f(x,y)cos(2x+1)uπ2Mcos(2y+1)vπ2N F(u,v) =c(u)c(v)\sum_{x=0}^{M-1}\sum_{y=0}^{N-1}f(x,y)cos\cfrac{(2x+1)u\pi}{2M}cos\cfrac{(2y+1)v\pi}{2N} F(u,v)=c(u)c(v)x=0M1y=0N1f(x,y)cos2M(2x+1)uπcos2N(2y+1)vπ

c(u)={1Mu=02Mu≠0 c(u) = \begin {cases} \sqrt{\cfrac{1}{M}} \quad u = 0 \\ \sqrt{\cfrac{2}{M} } \quad u\neq 0\end {cases}c(u)=M1 u=0M2 u=0 c(v)={1Nv=02Nv≠0 c(v) = \begin {cases} \sqrt{\cfrac{1}{N}} \quad v = 0 \\ \sqrt{\cfrac{2}{N} } \quad v\neq 0\end {cases} c(v)=N1 v=0N2 v=0

4 x 4 变换矩阵为:
A=[1212121212cosπ812cos3π812cos5π812cos7π812cosπ412cos3π412cos5π412cos7π412cos3π812cos9π812cos15π812cos21π8] A = \begin{bmatrix} \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} \\ \sqrt{\cfrac{1}{2}} cos \cfrac{\pi}{8} & \sqrt{\cfrac{1}{2}}cos \cfrac{3\pi}{8} & \sqrt{\cfrac{1}{2}}cos \cfrac{5\pi}{8} & \sqrt{\cfrac{1}{2}}cos \cfrac{7\pi}{8} \\ \sqrt{\cfrac{1}{2}} cos \cfrac{\pi}{4} &\sqrt{\cfrac{1}{2}} cos \cfrac{3\pi}{4} & \sqrt{\cfrac{1}{2}} cos \cfrac{5\pi}{4} & \sqrt{\cfrac{1}{2}} cos \cfrac{7\pi}{4} \\ \sqrt{\cfrac{1}{2}} cos \cfrac{3\pi}{8} & \sqrt{\cfrac{1}{2}} cos \cfrac{9\pi}{8} & \sqrt{\cfrac{1}{2}} cos \cfrac{15\pi}{8} &\sqrt{\cfrac{1}{2}} cos \cfrac{21\pi}{8} \end{bmatrix} A=2121 cos8π21 cos4π21 cos83π2121 cos83π21 cos43π21 cos89π2121 cos85π21 cos45π21 cos815π2121 cos87π21 cos47π21 cos821π

a=12,b=12cosπ8=0.6532...,c=12cos3π8=0.2706... a = \cfrac{1}{2} , \quad b = \sqrt{\cfrac{1}{2}} cos \cfrac{\pi}{8} = 0.6532..., \quad c = \sqrt{\cfrac{1}{2}} cos \cfrac{3\pi}{8} = 0.2706... a=21,b=21 cos8π=0.6532...,c=21 cos83π=0.2706...
上边的变换矩阵为
A=[aaaabc−c−ba−a−aac−bbc] A = \begin {bmatrix} a & a & a & a\\ b & c & -c & -b \\ a & -a & -a & a \\ c & -b & b & c \end {bmatrix} A=abacacabacababac

4 x 4 二维DCT变换可以表示为
Y=AXAT Y = A X A^{T} Y=AXAT

由于b 和c 计算机中表示都需要浮点,现在把它乘以2.5后近似到最近的整数。Cf4如下

Cf4=[111121−1−21−1−111−221] C_{f4} = \begin {bmatrix} 1 & 1 & 1 & 1\\ 2 & 1 & -1 & -2 \\ 1 & -1 & -1 & 1 \\ 1 & -2 & 2 & 1 \end {bmatrix} Cf4=1211111211121211
单位化
A1=Cf4∙Rf4,∙表示各元素相乘 A_{1} = C_{f4} \bullet R_{f4} , \bullet 表示各元素相乘A1=Cf4Rf4,
Rf4=[1212121211011011011012121212110110110110] R_{f4} = \begin {bmatrix} \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2}\\ \cfrac{1}{\sqrt{10}} & \cfrac{1}{\sqrt{10}} & \cfrac{1}{\sqrt{10}} & \cfrac{1}{\sqrt{10}} \\ \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} \\ \cfrac{1}{\sqrt{10}} & \cfrac{1}{\sqrt{10}} & \cfrac{1}{\sqrt{10}} & \cfrac{1}{\sqrt{10}} \end {bmatrix} Rf4=2110 12110 12110 12110 12110 12110 12110 12110 1
最后
Y=(Cf4XCf4T)∙(Rf4∙Rf4T)=(Cf4XCf4T)∙Sf4Y = (C_{f4} XC_{f4}^{T})\bullet (R_{f4} \bullet R_{f4}^{T}) \\ =(C_{f4} XC_{f4}^{T})\bullet S_{f4}Y=(Cf4XCf4T)(Rf4Rf4T)=(Cf4XCf4T)Sf4
Sf4=Rf4∙Rf4T S_{f4} = R_{f4} \bullet R_{f4}^{T}Sf4=Rf4Rf4T
Sf4=[1412101412101210110121011014121014121012101101210110] S_{f4} = \begin {bmatrix} \cfrac{1}{4} & \cfrac{1}{2\sqrt{10}} & \cfrac{1}{4} & \cfrac{1}{2\sqrt{10}}\\ \cfrac{1}{2\sqrt{10}} & \cfrac{1}{10} & \cfrac{1}{2\sqrt{10}} & \cfrac{1}{10} \\ \cfrac{1}{4} & \cfrac{1}{2\sqrt{10}} & \cfrac{1}{4} & \cfrac{1}{2\sqrt{10}} \\ \cfrac{1}{2\sqrt{10}} & \cfrac{1}{10} & \cfrac{1}{2\sqrt{10}} & \cfrac{1}{10} \end {bmatrix} Sf4=41210 141210 1210 1101210 110141210 141210 1210 1101210 1101

4 * 4 block Ci4 和Si4的导出

4 x 4 二维IDCT变换可以表示为
Z=ATYA Z = A^{T}YA Z=ATYA

a=12,b=12cosπ8=0.6532...,c=12cos3π8=0.2706... a = \cfrac{1}{2} , \quad b = \sqrt{\cfrac{1}{2}} cos \cfrac{\pi}{8} = 0.6532..., \quad c = \sqrt{\cfrac{1}{2}} cos \cfrac{3\pi}{8} = 0.2706... a=21,b=21 cos8π=0.6532...,c=21 cos83π=0.2706...
上边的变换矩阵为
A=[aaaabc−c−ba−a−aac−bbc] A = \begin {bmatrix} a & a & a & a\\ b & c & -c & -b \\ a & -a & -a & a \\ c & -b & b & c \end {bmatrix} A=abacacabacababac
将浮点数近似到最近的0.5 得到:
Ci4=[1111112−12−11−1−1112−11−12] C_{i4} = \begin{bmatrix} 1 & 1 & 1 & 1\\ 1 & \cfrac{1}{2} & -\cfrac{1}{2} & -1 \\ 1 & -1 & -1 & 1 \\ \cfrac{1}{2} & -1 &1 & -\cfrac{1}{2} \end {bmatrix} Ci4=11121121111211111121
单位化
A2=Ci4∙Ri4,∙表示各元素相乘 A_{2} = C_{i4} \bullet R_{i4} , \bullet 表示各元素相乘A2=Ci4Ri4,
Ri4=[12121212252525251212121225252525] R_{i4} = \begin {bmatrix} \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2}\\ \sqrt{\cfrac{2}{5}} & \sqrt{\cfrac{2}{5}} & \sqrt{\cfrac{2}{5}} & \sqrt{\cfrac{2}{5}} \\ \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} & \cfrac{1}{2} \\ \sqrt{\cfrac{2}{5}} & \sqrt{\cfrac{2}{5}} & \sqrt{\cfrac{2}{5}} &\sqrt{\cfrac{2}{5}} \end {bmatrix} Ri4=2152 2152 2152 2152 2152 2152 2152 2152
所以有
Z=A2TYA2Z=(Ci4∙Ri4)T⋅Y⋅(Ci4∙Ri4)=Ci4T⋅(Y∙Ri4T∙Ri4)⋅Ci4 Z = A_{2}^{T}YA_{2}\\ Z = ( C_{i4} \bullet R_{i4})^{T} \cdot Y \cdot (C_{i4} \bullet R_{i4}) \\ = C_{i4}^T\cdot(Y\bullet R_{i4}^T\bullet R_{i4})\cdot C_{i4} Z=A2TYA2Z=(Ci4Ri4)TY(Ci4Ri4)=Ci4T(YRi4TRi4)Ci4
得到
Si4=Ri4T∙Ri4=[1411014110110251102514110141101102511025] S_{i4} = R_{i4}^T\bullet R_{i4} = \\ \begin{bmatrix} \cfrac{1}{4} &\sqrt{\cfrac{1}{10}} & \cfrac{1}{4} &\sqrt{\cfrac{1}{10}} \\ \sqrt{\cfrac{1}{10}} & \cfrac{2}{5} & \sqrt{\cfrac{1}{10}} & \cfrac{2}{5} \\ \cfrac{1}{4} &\sqrt{\cfrac{1}{10}} & \cfrac{1}{4} &\sqrt{\cfrac{1}{10}} \\ \sqrt{\cfrac{1}{10}} & \cfrac{2}{5} & \sqrt{\cfrac{1}{10}} &\cfrac{2}{5} \end{bmatrix} Si4=Ri4TRi4=41101 41101 101 52101 5241101 41101 101 52101 52

Vi4的导出

Vi4≈Si4Qstep26V_{i4} \approx S_{i4}Q_{step}2^6Vi4Si4Qstep26
H264支持一组Q step,但是却没有定义在标准中。代之的是Vi4矩阵作为QP的函数表示。
Vi4由Qstep 也就是QP 和Si4决定。下表列出了qp取0~5时的Vi4的值。
在这里插入图片描述

Vi4 对于QP的函数定义如下:
Vi4=[v(QP,0)v(QP,2)v(QP,0)v(QP,2)v(QP,2)v(QP,1)v(QP,2)v(QP,1)v(QP,0)v(QP,2)v(QP,0)v(QP,2)v(QP,2)v(QP,1)v(QP,2)v(QP,1)] V_{i4} = \\ \begin{bmatrix} v(QP, 0) &v(QP, 2) & v(QP, 0)&v(QP, 2) \\ v(QP, 2) & v(QP, 1) & v(QP, 2) & v(QP, 1) \\ v(QP, 0) &v(QP, 2) & v(QP, 0) &v(QP, 2) \\ v(QP, 2) &v(QP, 1) & v(QP, 2) &v(QP, 1) \end{bmatrix} Vi4=v(QP,0)v(QP,2)v(QP,0)v(QP,2)v(QP,2)v(QP,1)v(QP,2)v(QP,1)v(QP,0)v(QP,2)v(QP,0)v(QP,2)v(QP,2)v(QP,1)v(QP,2)v(QP,1)
表示为Vi4=v(QP,n)V_{i4} = v(QP, n)Vi4=v(QP,n) 其中v(r,n)用一个表来定义r是行号,n是列号, h264中标准中的定义如下:
在这里插入图片描述
对于每个QP 对应一个Vi4矩阵。没列的说明列中Vi4 positions 说明的是v(qp,0) 在Vi4矩阵中占据的位置有哪些。使用这个表和Vi4 的定义矩阵就可以得到Vi4 的数值定义表。
QP > 5时 Vi4=v(QP%6,n)∗2floor(QP/6)V_{i4} = v(QP\%6, n)* 2^{floor(QP/6)}Vi4=v(QP%6,n)2floor(QP/6)
通过给出的Vi4 矩阵可以反推QPstep。 至于h264 中开发人员是先指定的QPstep 还是Vi4,这个过程应该是一个不断的理论加实验的迭代过程。

反推得到的QPstep的值如下图:
在这里插入图片描述
连续的QPstep的比例是26≈1.2246…\sqrt[6]{2}\approx1.2246\dots62 1.2246 所以QP每增加6,QPstep变为原来两倍。所以所有的QPstep的值都可以从QP0~QP5的值推导得到:
Qstep=Qstep(QP%6,n)∗2floor(QP/6)\quad Q_{step} = Q_{step}(QP\%6, n)* 2^{floor(QP/6)}Qstep=Qstep(QP%6,n)2floor(QP/6)

完整的反向量化和放大过程

Z=round(Ci4T⋅(Y∙v(QP%6,n)∗2floor(QP/6))⋅Ci4)Z= round(C_{i4}^{T}\cdot(Y\bullet v(QP\%6, n)* 2^{floor(QP/6)})\cdot C_{i4})Z=round(Ci4T(Yv(QP%6,n)2floor(QP/6))Ci4)
H264标准中的反向量化和放大过程分为下面几步:

  1. 计算矩阵的LevelScale
    LevelScale(QP%6,i,j)=weightScale(i,j)∗v(QP%6,n)LevelScale(QP\%6, i, j) = weightScale(i, j) ∗ v(QP\%6, n)LevelScale(QP%6,i,j)=weightScale(i,j)v(QP%6,n)
    这里的weightScale(i,j)的默认值为16,像素位置不同这个可能不同。
  2. 放大输入的采样cij
    dij=(cij∗LevelScale(QP%6,i,j))∗(QP/6−4),QP>24d_{ij} = (c_{ij}∗ LevelScale(QP\%6, i, j)) *(QP/6 − 4), \quad QP > 24dij=(cijLevelScale(QP%6,i,j))(QP/64),QP>24
    dij=(cij∗LevelScale(QP%6,i,j)+23−QP/6)∗(4−QP/6),QP<24d_{ij} = (c_{ij}∗ LevelScale(QP\%6, i, j) + 2^{3-QP/6}) *(4 - QP/6), \quad QP < 24dij=(cijLevelScale(QP%6,i,j)+23QP/6)(4QP/6),QP<24
    上面的两步就是完成下边的功能:其中左右移动表示就是除以一个数并向下取整
    D=Y∙v(QP%6,n)⋅2floor(QP/6)D=Y \bullet v(QP\%6,n)\cdot2^{floor(QP/6)}D=Yv(QP%6,n)2floor(QP/6)
  3. 计算core transform
    H=Ci4T⋅D⋅Ci4H = C_{i4}^{T}\cdot D\cdot C_{i4}H=Ci4TDCi4
  4. 将每一个采样除以26
    rij=(hij+25)>>6r_{ij} =(h_{ij} + 2^5) >> 6rij=(hij+25)>>6
    最后获得矩阵R就是恢复的残差数据

Mf4的推导

根据
Mf=Sf∗215Qstep M_{f} = \cfrac{S_{f} * 2^{15}}{Q_{step}}Mf=QstepSf215
Vi=Qstep∗26∗Si V_{i} = Q_{step} * 2^{6} * S_{i}Vi=Qstep26Si
得到:
Mf4≈Sf∙Si221ViM_{f4} \approx \cfrac{S_{f}\bullet S_{i}2^{21}}{V_{i}}Mf4ViSfSi221

Sf,SiS_f,S_iSfSi都是已知的,ViV_iVi是在标准中定义的,Mf4的正式计算公式为:
Mf4=round(Sf∙Si221Vi)M_{f4} =round( \cfrac{S_{f}\bullet S_{i}2^{21}}{V_{i}})Mf4=round(ViSfSi221)
Mf4的分子矩阵为:
Si4∙Sf4∗221=[131072104857.6131072104857.6104857.683886.1104857.683886.1131072104857.6131072104857.6104857.683886.1104857.683886.1]S_{i4}\bullet S_{f4}*2^{21} = \\ \begin {bmatrix}\\ 131072&104857.6&131072&104857.6\\ 104857.6&83886.1&104857.6&83886.1\\ 131072&104857.6&131072&104857.6\\ 104857.6&83886.1&104857.6&83886.1\\ \end {bmatrix}Si4Sf4221=131072104857.6131072104857.6104857.683886.1104857.683886.1131072104857.6131072104857.6104857.683886.1104857.683886.1
分母Vi4根据上结给出的,0~5 QP的table如下:
在这里插入图片描述
给出Mf4的函数
Mf4=[m(QP,0)m(QP,2)m(QP,0)m(QP,2)m(QP,2)m(QP,1)m(QP,2)m(QP,1)m(QP,0)m(QP,2)m(QP,0)m(QP,2)m(QP,2)m(QP,1)m(QP,2)m(QP,1)]M_{f4} =\\ \begin {bmatrix} m(QP, 0)&m(QP, 2)&m(QP, 0)&m(QP, 2)\\ m(QP, 2)&m(QP, 1)&m(QP, 2)&m(QP, 1)\\ m(QP, 0)&m(QP, 2)&m(QP, 0)&m(QP, 2)\\ m(QP, 2)&m(QP, 1)&m(QP, 2)&m(QP, 1)\\ \end {bmatrix}Mf4=m(QP,0)m(QP,2)m(QP,0)m(QP,2)m(QP,2)m(QP,1)m(QP,2)m(QP,1)m(QP,0)m(QP,2)m(QP,0)m(QP,2)m(QP,2)m(QP,1)m(QP,2)m(QP,1)
简写为:
Mf4=m(QP,n)M_{f4} =m(QP, n)Mf4=m(QP,n)
对于QP >5, 更一般的表示为:
Mf4=m(QP%6,n)/2floor(QP/6)M_{f4} =m(QP\%6, n)/2^{floor(QP/6)}Mf4=m(QP%6,n)/2floor(QP/6)

完整的4x4 正向变换和放大过程

整个过程可以表示为
Y=round([Cf4⋅X⋅Cf4T∙m(QP%6,n)]⋅1215+floor(QP/6)) Y = round([C_{f4} \cdot X \cdot C_{f4}^{T}\bullet m(QP\%6,n)]\cdot \cfrac{1}{2^{15 + floor(QP/6)} }) Y=round([Cf4XCf4Tm(QP%6,n)]215+floor(QP/6)1)

matlab代码

反量化:

function [Wi]= inv_quantization(Z,QP)

% q is qbits
q = 15 + floor(QP/6);

% The scaling factor matrix V depend on the QP and the position of the
% coefficient.
%   delta lambda miu
SM = [10 16 13
      11 18 14
      13 20 16
      14 23 18
      16 25 20
      18 29 23];
 
 x = rem(QP,6);
 
 % find delta, lambda and miu values
 d = SM(x+1,1);
 l = SM(x+1,2);
 m = SM(x+1,3);

 V = [d m d m
      m l m l
      d m d m
      m l m l];
  
 % find the inverse quantized coefficients
  Wi = Z.*V;
  Wi = bitshift(Wi,q-15, 'int64');
 
end

反向整数变换:

function [Y] = inv_integer_transform(W)

a = 1/4;
b = 1/10;
c = sqrt(1/40);

% E is the scaling factor matrix
% Refer to MPEG4-AVC slides (simplified from the H.264 white paper)

E = [a c a c
     c b c b
     a c a c
     c b c b];

 % Ci is the inverse core transform matrix
Ci =  [1 1 1 1
      1 1/2 -1/2 -1
      1 -1 -1 1
      1/2 -1 1 -1/2];

 Y = Ci'*W*Ci;
%  Y = Ci'*(W.*E)*Ci;
 
end
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐