0 前言

自适应环路滤波(ALF)并不是在 H.266/VVC 标准制定过程中才被提出来的技术,实际上其早在 H.265/HEVC 标准制定时就基本确定了现有形式的雏形,只是由于当时硬件算力的限制未能加入到 HEVC 标准中。详细可阅读以下的论文。随着硬件算力的提升与一些优化方法的提出,以及人们对更高效率的编解码算法的期望,ALF 自然就成了 VVC 标准中不可或缺的部分。由于 ALF 是一个十分有效的手段,也就吸引力不少人去研究,很多率失真改进方法不断被提出,所以基本每一次会议之后都能看到一些不同的地方。我第一次详细地接触研读 ALF 是在 VTM2 发布的时候,后来到了 VTM4 再去看代码时已经多了很多没见过的东西。但总之,其内核是不会改变的,所以这里我主要就其滤波的原理进行介绍,这些目前在网上的资料是比较少的,也可以让大家能够更好地理解 VTM 代码里的相关实现。

[1] C. Tsai et al., Adaptive Loop Filtering for Video Coding, in IEEE Journal of Selected Topics in Signal Processing, vol. 7, no. 6, pp. 934-945, Dec. 2013.

ALF 模块处于去块效应滤波(Deblocking Filtering, DF)和样点自适应补偿(Sample Adaptive Offset, SAO)之后。相比于 DF 和 SAO,ALF 更加贴近于我们对图像滤波的一般理解,也就是说其可以表示为图像与卷积核之间的卷积运算。而至于所使用卷积核,当然不是什么高斯模糊、边缘检测之类的,视频编解码算法里降低码率和误差才是王道。靠滤波来直接降低码率自然是不行的,那是熵编码干的活,那什么滤波可以降低误差呢?没错,就是维纳滤波(Wiener Filtering, WF)。维纳滤波是一种基于最小均方误差准则、对平稳过程的最优估计器,其输出与期望输出之间的均方误差为最小。然而,要注意的是,维纳滤波并不是一种现成的滤波器,其只是确立了一种准则,具体还是要自己设计的,在信号与系统里也就是找到相应的系统冲激响应,在离散图像里也就是要找到相应的卷积核。因此,下面的内容将就该卷积核的求导进行详细的介绍。

1 滤波器形状

虽然维纳滤波并没有限制所用的滤波器形式,但我们还是要综合考虑其实现的难度以及所能带来的增益。在图像处理中,最方便、直观的滤波方式就是采用一个矩形的卷积核,ALF 也遵循这种习惯。不过,很显然,卷积核的尺寸越大,所获得的增益一般来说会越大,但其所带来的计算复杂度也就越高,而且这种增益和复杂度之间的关系并不是线性的。另外,维纳滤波是和原始数据相关的,而解码端是不可能接触到原始数据的,那就意味着我们必须要把解码端所求得的滤波系数编到码流中进行传输,所以我们也不能把卷积核弄得太大。

考虑以上因素,H.266 定义了两种形状的滤波器,其中对亮度分量使用 7x7 的滤波器,而对色度分量采用 5x5 的滤波器。为了减少传输滤波器系数的码字以及降低滤波的计算复杂度,ALF 使用了菱形且中心对称的滤波系数矩阵,其形状如图 1 所示,也就是只有菱形内的像素会参与滤波,而中心对称的像素使用相同的滤波系数,其中滤波器中心的位置即是当前滤波的像素位置。对于亮度分量,H.266 定义了最多 25 组滤波系数,像素所属分组基于重建后的图像以 4x4 小块为单位根据该块以及周围像素的梯度信息进行推导,该块内所有像素均属于同一组。而对于色度分量,Cb,Cr 各自只定义一组系数。三个分量独立进行率失真优化与系数推导以及最终的滤波。具体亮度分量像素的分类在标准文档中有详细介绍,这里不多说。

图1 ALF filter shapes (chroma: 5x5 diamond, luma: 7x7 diamond)

2 维纳滤波


将上式写成矩阵形式,可得

为了方便,我们令


那么上面的线性方程组可写为
其中

求解该方程组,我们就可以得到相应的滤波系数了。可以看到,这实际上与优化线性超定方程组 Rc = o \textbf{Rc}=\textbf{o} Rc=o 所用的最小二乘法的结果是一致的,也就是说对于卷积这种线性运算的维纳滤波可通过线性最小二乘法来求解。至于求解线性方程组的方法有很多种,我们可以注意到矩阵 T \textbf{T} T 是一个实对称且正定的,因此采用例如 Cholesky 分解的方法来进行加速,这也是 VTM 代码里面所使用的方法。另外可以看到 T = R T R = ( R T ) ( R T ) T \textbf{T}=\textbf{R}^{T}\textbf{R}=(\textbf{R}^{T})(\textbf{R}^{T})^{T} T=RTR=(RT)(RT)T,这个跟协方差的公式比较相近,所以 VTM 代码里面也使用协方差的符号 Cov \textbf{Cov} Cov 来代替 T \textbf{T} T,但实际上,协方差的公式应该为 T = ( R T − μ ) ( R T − μ ) T \textbf{T}=\left(\textbf{R}^{T}-\mu\right)\left(\textbf{R}^{T}-\mu\right)^{T} T=(RT−μ)(RT−μ)T,所以只有当 μ = 0 \mu=0 μ=0 时才可以认为两者是等价的。

对于 ALF 来说,由于其卷积核是中心对称的,如图 1 所示,所以在求解过程中可以将相同系数的像素值先合并再计算,即

3 滤波后的均方误差

求得相应的滤波系数后,我们还得通过率失真优化(Rate-Distortion Optimization, RDO)才能确定是否采用这个结果,因为前面已经提到了,我们必须把这些系数编到码流中供解码端使用,所以滤波所能减小的误差不一定能够弥补码字的损失。至于 RDO 的具体流程这里不作介绍,我们主要关注怎么去快速地求得滤波后的误差。

一个直观的想法是,我们利用求得的滤波系数,对集合中每一个像素进行滤波,那么就可以得到滤波后的像素值了,相应的均方误差(MSE)自然也就可以求得了。然而,其所需的计算复杂度也是非常高的,更不用说 RDO 过程中这种计算还得重复很多次了。如果 ALF 使用这种方法,那它也别想成为 VVC 标准的一部分了。实际上,由于维纳滤波的特殊性,其 MSE 是可以跳过实际滤波这步操作而直接快速求得的,也就是说,在 RDO 过程中,我们根本就不需要进行真正的滤波。

根据 MSE 的定义,有

当然,我们可以更简单地直接通过矩阵运算来推导,也就是


由于相应像素集对应的 T \textbf{T} T 和 v \textbf{v} v 可以快速求出,所以新的 MSE 也可以快速求出,而不需要进行真正的滤波操作。注意,这个公式中所使用的滤波系数并不要求是维纳滤波所求得的系数,即任何系数都可以利用这个公式快速求得滤波后的 MSE。这主要用于 ALF 系数后期基于 RDO 的量化调整,因为 ALF 系数最初是浮点数,直接编码所需的码字较多,所以需要在维纳滤波系数的基础上进行量化和微调,这就导致了最后所使用的滤波系数并不等于维纳滤波的系数。具体的量化和微调操作这里不细说。如果使用的是维纳滤波的系数,那么在第 2 节可知 Tc = v \textbf{Tc}=\textbf{v} Tc=v,那么进一步简化可得

似乎到这里相关的内容就讲完了,但实际上 VTM 代码中并没有使用这个公式来求 MSE,因为这里有一部分的计算和其他模块的计算重复了。没错,那就是不使用 ALF,即直接使用 DF 和 SAO 的输出作为最终输出时的 MSE,而这个 MSE 是我们在 RDO 过程中必须用到的,毕竟这是确定 ALF 有没有用的基准。那为什么上面的公式会产生冗余呢?这里包含了一个简单的小技巧。

我们令卷积核中心的系数(即当前滤波的像素位置的系数)减 1,即

对于维纳滤波来说,有 Tc = v \textbf{Tc}=\textbf{v} Tc=v,其系数的求解就可转化为以下公式。而且这种表示方法有一个好处就是,当 c ^ = 0 \hat{\textbf{c}}=\textbf{0} c^=0 时,实际代表着不进行滤波。当然,我们通过最小二乘法也能很容易得到相同的结果。

那么,根据 MSE 的定义,可得
同样,如果使用矩阵运算会更加清晰明了,即


注意到没有,这里实际上可提取出 M S E n o n − f i l t e r e d MSE_{non-filtered} MSEnon−filtered​ 这一项,也就是不使用 ALF 时的 MSE,而这一项前面已经求得,因此只需要求前面那部分即可。对于维纳滤波的系数来说,由于有 T c ^ = v ^ \textbf{T}\hat{\textbf{c}}=\hat{\textbf{v}} Tc^=v^,所以也可简化为
这就是 VTM 代码中所使用的 MSE 求解方式。

4 后语

这里主要是对 ALF 中所使用到的维纳滤波的原理以及一些优化的技巧进行了详细的介绍,但这些只是 ALF 模块的比较小的组成部分。ALF 之所以能有那么大的改进,还离不开一些精妙的设计以及复杂的 RDO 过程,这方面的提案也是非常多的,在这里就不进行介绍了,毕竟我也看不完。就这样。。。

VVC/VTM: 自适应环路滤波(ALF, Adaptive Loop Filtering)中维纳滤波(Wiener Filtering)的公式推导相关推荐

  1. VVC/VTM:环路滤波——Luma mapping with chroma scaling (LMCS)

    VTM中环路滤波的顺序:LMCS,deblocking filter,SAO 和ALF.其中deblocking filter和SAO 与HEVC中的相同. Luma mapping with chr ...

  2. VVC环路滤波(一):ALF

    在VTM5中提供了三种环路滤波技术:去方块滤波(Deblocking filter,DF),样点自适应补偿(Sample adaptive offset,SAO)和自适应环路滤波(adaptive l ...

  3. FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  4. 视频千倍压缩背后的技术原理之环路滤波

    随着5G的成熟和广泛商用,带宽越来越高,让传输视频变得更加容易.移动设备算力的提升.存储容量的提升,也使得视频技术的应用越来越广泛.视频相关的技术,特别是视频压缩技术,因其专业性,深入开发的门槛较高, ...

  5. h264解码之环路滤波

    代码以ffmpeg为例,h264解码代码在h264.c里. 环路滤波(Loop Filter)部分 FFmpeg的H.264解码器调用decode_slice()函数完成了解码工作.这些解码工作可以大 ...

  6. 基于深度学习的环路滤波的消融实验

    本文来自提案JVET-Z0106,在上一篇文章<基于深度学习的环路滤波和残差缩放>中介绍了JVET-Y0143提案使用深度学习模型来做环路滤波带来了性能提升,但是整个模型还是一个" ...

  7. FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  8. H.266/VVC技术学习之环路滤波:去块滤波(Deblock)技术

    一.方块效应 目前主流的视频编码标准都是基于分块的混合编码机制,其处理过程是针对每个块单独进行处理的,因此由于编码模式的差异以及量化误差的原因,会导致相邻块重建像素不连续的现象.对于一个两侧强相关性的 ...

  9. TIP 2019开源论文:基于深度学习的HEVC多帧环路滤波方法

    作者丨李天一 学校丨北京航空航天大学博士生 研究方向丨视频编码与深度学习 本文概述的是作者近期在 IEEE TIP 期刊上发表的论文:A Deep Learning Approach for Mult ...

最新文章

  1. linux用户及用户组管理
  2. 浅析IT软件项目团队人力资源管理
  3. org.dom4j.DocumentException: null Nested exception: null解决方法
  4. 汇编语言hello word!
  5. cadcene17.4软件汉化
  6. js 判断数组是否是递增的
  7. java isbn_Java ISBN formating
  8. 猫哥教你写爬虫 034--爬虫-BeautifulSoup实践
  9. Gephi报错cannot load even default layout, using internally predefined configuration解决方法
  10. 网课研究生学术与职业素养讲座mooc答案
  11. /etc/rc0.d----rc3.d---rcS.d这些目录的意义
  12. 马化腾,直接把360做特了!
  13. minio对象存储单机部署并设置开机自启动及集成spring boot进行(创建删除桶)(上传下载删除文件)
  14. 项目管理工具——项目开发者工具
  15. 融跃教育登陆湖南卫视!揭秘融跃是个什么样机构!CFA/FRM/ACCA
  16. H. 知识图谱 知识问答
  17. Python:设置不显示Using TensorFlow backend及FutureWarning: Passing (type, 1) or ‘1type‘ as a synonym of typ
  18. altair 8800_Python数据可视化场景的戏剧性浏览(包括ggpy和Altair)
  19. 没NFC功能的手机如何能刷公交卡
  20. 给大家推荐一款由PHP+MYSQL搭建的同城跑腿系统

热门文章

  1. mysql version 乐观锁_mysql乐观锁总结和实践
  2. layer.open参数;layer.open关闭事件;layer.open关闭刷新;layer.open获取子页的值;layer.open调用子页面的方法
  3. 广州大学2020操作系统实验一:进程管理与进程通信
  4. 质素因子【Java】
  5. w3c 质素求和算法挑战
  6. google免费导航来了,导航API还会远吗
  7. 刷爆leetcode
  8. SQL Server~函数
  9. Category为什么不能添加属性
  10. UG NX 12 删除与恢复对象