您的位置:首页 > 其它

视频压缩原理之 预测编码

2015-12-25 09:59 246 查看
预测法是最简单和实用的视频压缩方法,压缩编码后传输的并不是像素本身的取样幅

值,而是该取样的预测值和实际值之差(就是传输差分值)。

预测法的流程图如下:



(在量化过程中,会产生量化误差)

预测法大致可分为帧内预测和帧间预测。下面将依次介绍两种预测法,还会提到重叠块运动补偿,最后再细说一下运动估计。

帧内预测:

帧内预测的具体方法是根据一个像素点周围的像素值,来预测(我感觉用“猜测”更贴切)当前像素值。具体方法有一维预测(只利用同行相邻像素点的相关性进行预测,将前一个点的像素值作为当前点的预测值,大多数情况下一个像素点的像素值总与它前一个像素点相同或相近)和二维预测(除利用本行相邻像素外还利用了前一行的相邻像素来预测,预测时一般为周围不同位置的点分配一个权重,然后依据权重求平均作为当前点的像素预测值)。

在量化那一步,人眼视觉特性实验表明,在亮度突变部分,量化误差大些不会使人眼敏感,可采取粗量化(量化节距大);反之,在亮度变化缓慢区域,则应取细量化。总之,利用人眼这种掩盖效应采用非线性(不均匀)量化,可使总码率有所下降。下面是一个差值量化表示例:(下面的值是差值,差值越大,说明变化越快,量化节距就可以取得越大)



当进行玩预测之后,再拿测量到的实际值与预测值比较,得出差值,将此差值记录并编码,而不是直接对实际值编码。

此外,帧内预测有一个“预测编码增益”的概念(可能其他的预测方法也有,但是书上讲这个的时候是放在帧内预测这个小节里的),这个用来反映预测的质量,大致可由原始信号的方差 与 预测误差的方差 之比反映。此值越大,说明预测误差越小,预测的效果越好。

帧间预测:

帧间预测就比较复杂一点,主要是有了运动估计。帧间预测就是利用相邻帧之间像素点的相关性来进行预测。前后帧之间,相同位置处的像素点有很强的相关性(或相似性,因为图像一般很少会剧烈变化),另外,为了使预测更加准确,在使用帧间预测时,一般都会先进行运动估计。运动估计是指,在视频图像中,物体运动大多是平移运动,因此,如果能判断出当前帧的某个物体(图像上的一个区域),是由上一帧中的某个物体运动而来,那么我们就可以讲上一帧中该物体附近区域(通常是以16x16的方块划分区域,称为一个宏块)的像素点直接“复制”到当前帧中对应的位置,作为该宏块的预测值,而算出来的平移量,(i,j),称为这个宏块在两帧之间的运动矢量。得到预测值后,再与实际采样值比较,得出差值并编码。与帧内预测不同的是,除了记录差分值外,帧间预测还要记录每个宏块的运动矢量(就是说,还要对运动矢量进行编码)。帧间预测的复杂,就是复杂在分割宏块和计算运动矢量。

具体的,帧间预测包括 单向预测、双向预测、重叠块运动补偿。

单向预测与双向预测的区别是对参考帧的选取,前者一般只以当前帧的上一帧作为参考帧进行运动估计和预测,而后者可将上一阵(后向预测)和下一帧(前向预测)同时作为参考帧,然后在两个个参考帧上都进行一次运动估计和预测,再将得到的两个预测值加权求平均作为最终预测值。双向预测在实时通信中是不能应用的,例如会议电视、可视电话等,因为后向预测在当前帧之后进行,会引入编码时延。比如,双向预测在编码过程中,要先对第一帧和第三帧编码(因为他们都是参考帧),再对第二帧编码,这样当第二帧采样完时,还不能立即编码并传送,而要等待第三帧采样并编码完,因此就有了编码时延(在解码端,也是先接收第一帧和第三帧,再接收第二帧)。它可用在广播电视系统等允许有时延的场合。

另外,为了进一步提高编码效率,多帧预测(包括单向和双向预测)被引入,在H.264 标准中参考帧可达5 ~15 帧,也是得到多个预测值后求加权平均。

重叠块运动补偿OBMC:

重叠块运动补偿OBMC,这个方法的出现是因为前面的方法中,我们在进行运动估计时,都进行了人为的分块,而当分块的运动矢量估计不准确、物体不是简单的平移运动以及一个分块中包含多个运动物体时,都容易出现方块效应。采用OBMC 时,一个像素的预测不仅基于它所属的 MV估计,还基于其相邻的 MV估计。



(但为什么这样就能减少方块效应?搞不明白,我感觉这样并不会什么显著改善,反而增加了算法复杂度和计算量。但书上这么写的,就先这样记录着吧)。

运动估计:

下面具体介绍运动估计。这一块内容比较多,这是预测编码中最关键的一步。把几个关键词罗列一下,先有个概念。下面将提到:

运动搜索时宏块的匹配标准

亚像素插值

空间域和时间域中运动矢量的预测宏块分割 上层块预测

匹配误差的预测

运动搜索算法

运动估计指的是计算宏块运动矢量的过程。刚才也提到了,运动估计需要有参考帧,有前向参考和后向参考。H.264 编码标准和以往采用的视频压缩标准很大的不同在于,在运动估计过程中采用了多参考帧预测来提高预测精度。

选好参考帧后,需要计算当前帧中某个宏块(一般是一个16x16的方块区域)的运动矢量时,就先在参考帧内搜索与当前宏块最匹配的块,然后计算根据这个宏块在两帧中的坐标值求差就可计算出宏块的运动矢量。那如何衡量参考帧中一个宏块与当前正分析的宏块的“匹配”程度呢?有两个可选的标准:均方误差和 绝对误差均值 。一般都选参考帧的搜索域中误差最小的宏块来计算运动矢量,数学表达式如下图:



这两个标准的效果差不多。MSE的方法能更突出误差绝对值大的点。MAD算起来较快速。

对于块的尺寸,为了使预测效果更好,也不是限定块的大小必须是16x16,还可以是其他值(如16x8,8x8等,最小的允许块一般是4x4)。对于比较平坦的区域,可采用大点的分块,而对于细节较多的区域,则应取较小的块进行分析。另外,宏块中的每个色度块(Cb和Cr)尺寸宽高都应是亮度块的一半(这个根据YUV的具体格式确定,只要他们代表的是视图中的同一块矩形区域即可),每个色度块的运动矢量的水平和垂直坐标都是亮度块的一半。

在进行运动估计时有时还需用到“亚像素插值”。别被这个名字吓到,其实并不难理解,这个方法相当于将像素点的数量扩充了而已。它的出现是因为,物体实际运动的距离不一定恰好就是整数个像素,为了细化运动矢量的“刻度”从而更精确的表示运动矢量,就出现了“分数倍像素”,即亚像素(如1/2像素、1/4像素、1/8像素等)。这些亚像素被插在对应的位置,并根据与之相邻的几个整数像素来为这个亚像素分配一个合适的亮度色度值。这样,如果使用的是1/4亚像素,就相当于将每行每列的像素数量都扩充到了原来的4倍,在进行运动估计时,就可以有更精细的(1/4)刻度。下图给出了一个视频序列当采用
1/2 像素精度、1/4 像素精度和 1/8 像素精度时编码效率的情况:



可以看到,1/4 像素精度相对于1/2 像素精度的编码效率有很明显的提高,但是 1/8 像素精度相对于1/4 像素精度的编码效率除了在高码率情况下,并没有明显的提高,而且1/8 像素精度时,内插公式更复杂,再加上需要计算的像素点数大大增加,导致计算量相当大,因此在H.264的制定过程中1/8 像素精度的运动矢量模型逐渐被取消而只采用了 1/4 像素精度的运动矢量模型。

当运动估计进行完后,还有一个要解决的问题就是,如何记录(编码)这些运动矢量,因为这些运动矢量要跟随像素的差分值一块传送到接收端,这样接收端才能根据运动矢量和差分值将原图像解码出来。

那如何记录运动矢量呢?直接记录吗?这并不是好方法,因为不同帧之间,同一个宏块的运动矢量也是有相关性的,这个相关性可以按照物理中的物体运动模型来理解:在一段极短的时间内(比如两帧图像之间的时间间隔),物体的运动速度可以看成是不变的,也就是说,在上一个小时间段和下一个小时间段中,物体运动的位移大致相等。相同的,一个宏块在上一帧与当前帧中的运动矢量,与其在上上帧与上一帧之间的运动矢量一般是大致相同的。因此我们可以利用这个相关性,进一步减少数据的冗余度和编码长度,实现压缩。

具体方法也是使用预测法:先根据不同帧之间运动矢量的相关性计算出运动矢量的预测值,然后将最佳匹配法计算出来的实际运动矢量与预测值做差,再将这个差值记录。

上一段我提到的其实是运动矢量在时间域上的相关性(不同帧代表不同时刻),在“空间域”上,也有相关性存在,即一个宏块的运动矢量,跟与之相邻的宏块的运动矢量也是有相关性的。

空域的预测方法有两种:中值预测 和上层块模式预测(别被陌生名词吓到哦,因为并不难理解)。

中值预测比较简单,就是直接跟当前宏块左边、上边和右上方的三个相邻宏块的运动矢量,取其中值,作为当前宏块运动矢量的预测值。

上层块模式,看名字挺吓人,但并不复杂,只不过解释起来稍微费劲。H.264标准中提供的可用块尺寸有16×16 ,8×16,16×8,8×8 ,8×4 ,4×8 ,4×4 (上面我提到过),共七个,可以看成7种分块模式(书中用的词是“搜索模式”,这个词容易让人产生疑惑,所以我就用“分块模式”替代了),分别用Mode1-Mode7表示。假设当前分割区域的分区模式为 Modecurr ,则他的上层模式 Modeup定义为:



根据这个原则,找到它的上层块。然后用上层块的运动矢量作为当前块的预测值。

补充,h.264的宏块分割规则如下:每个宏块(16×16 像素)可以 4 种方式分割:一个 16×16 ,两个 16×8,两个 8×16,四个 8×8 。其运动补偿也相应有四种。而8×8 模式的每个子宏块还可以四种方式分割:一个8×8 ,两个4×8 或两个8×4 及4 个4×4 。

至于h.264是如何进行块的划分的,目前我还不清楚,以后知道了再回来补充。

*关于匹配误差的预测(貌似不重要?):

H.264中定义的匹配误差函数如下:

J (MV,λMOTION)=SAD(s, c (MV) )+λMOTION×R(MV-PMV)

上面的第二项R(MV-PMV )代表了运动矢量差分编码可能耗费的比特数,这一项对不同的预测方法来说都是差不多的,因此在衡量不同预测算法的预测特性时,一般只需比较前一项。对于SAD(s, c (MV)),其定义如下:



其中s 是当前进行编码的原始数据,而c 是已经编码重建的用于进行运动补偿的参考帧的数据。这一项反映了预测的效果。对某个宏块使用这个公式,就可以得到这个宏块的匹配误差。

对匹配误差预测时,大致与运动矢量的预测方法一样,也是分时间域和空间域预测两种。不过还不太清楚为什么要预测匹配误差?难道匹配误差还有需要传输吗?只要得到运动矢量和像素差分值,就可以根据参考帧还原图像了,不需要匹配误差吧。又或者说这个只是用在编码端,以便让编码端先预测出最小匹配误差对应的运动矢量,然后在预测值附近迅速找出真正的最小匹配误差对应的运动矢量?

运动搜索算法中的快速搜索算法:

主要有二维对数搜索法和三步搜索法,他们原理都类似,都是通过对几个点的计算逐渐逼近最佳匹配点(准确的说是局部最佳匹配点)。

但是,上述一些快速算法更适合用于估计运动幅度比较大的场合,对于部分运动幅度小的场合,它们容易落入局部最小值,而真正的匹配误差最小的值却没有被检测到,导致匹配精度很差。针对这一缺点,H.264编码标准使用了一种自适应搜索范围的改进的快速运动估计算法。总之,运动搜索算法是视频编码中很重要的一块!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: