06|帧内预测:如何减少空间冗余?

你好,我是李江。

前面几节课我们一起讨论了视频编码的原理以及编码码流结构,从今天开始我们一起来聊一聊具体的编码模式。

我们知道在视频编码时主要需要减少4个冗余,包括:空间冗余、时间冗余、视觉冗余和信息熵冗余。其中空间冗余就是通过帧内预测的方式来实现的。那帧内预测到底是怎么做到减少空间冗余的呢?

其实一般来说,一幅图像中相邻像素的亮度和色度信息是比较接近的,并且亮度和色度信息也是逐渐变化的,不太会出现突变。也就是说,图像具有空间相关性。帧内预测就是利用这个特点来进行的。即帧内预测通过利用已经编码的相邻像素的值来预测待编码的像素值,最后达到减少空间冗余的目的

这里需要注意的一个点就是,我们是通过已经编码了的像素值去预测待编码的像素值。你可能会问,已经编码了的像素值变成码流了,不再是一个个像素了,怎么去预测待编码的像素呢?其实已经编码了的像素是会重建成重建像素,用来做之后待编码块的参考像素的。你可以认为是已经编码的块会解码成像素用来做参考像素

好了,我们已经知道了帧内预测是怎么减少空间冗余的,那我们还有一个最重要的问题要解答。既然帧内预测是通过相邻像素来预测待编码像素的,那它到底是怎么预测的呢?下面我们就以H264标准来讲解每种帧内预测模式是怎么做预测的。

不同块大小的帧内预测模式

我们在视频编码原理的那节课里面讲过,视频编码是以块为单位进行的。在H264标准里面,块分为宏块和子块。宏块的大小是16 x 16(YUV 4:2:0图像亮度块为16 x 16,色度为8 x 8)。在帧内预测中,亮度宏块可以继续划分成16个4 x 4的子块。因为图像中有的地方细节很多,我们需要划分成更小的块来做预测会更精细,所以会将宏块再划分成4 x 4的子块。如下图所示:

帧内预测是根据块的大小分为不同的预测模式的。还有一个点就是亮度块和色度块的预测是分开进行的。这里我给你总结一下,主要有以下3点规则:

  1. 宏块大小是16 x 16,其中亮度块为16 x 16,色度块为8 x 8

  2. 帧内预测中亮度块和色度块是分开独立进行预测的,即亮度块参考已编码亮度块的像素,而色度块参考已编码色度块的像素;

  3. 16 x 16的亮度块可以继续划分成16个4 x 4的子块

所以,我们在实际帧内预测的时候就会分为:4 x 4亮度块的预测、16 x 16亮度块的预测、8 x 8色度块的预测(注意亮度8 x 8模式和I_PCM模式很少使用,我们这里不做讨论)。下面我们就开始一个个展开来讨论吧。

4 x 4亮度块的帧内预测模式

因为4 x 4的块帧内预测模式最多,并且基本包含亮度16 x 16和色度8 x 8的模式,所以我们接下来先从4 x 4亮度块的帧内预测模式讲起。

4 x 4亮度块的帧内预测模式总共有9个。其中有8种方向模式和一种DC模式,且方向模式指的是预测是有方向角度的。好了,那我们接下来就聊聊这9种模式吧。

  1. Vertical模式

Vertical模式就是指,当前编码亮度块的每一列的像素值,都是复制上边已经编码块的最下面那一行的对应位置的像素值。这句有点拗口,别急,等会儿我会给出计算方法和示意图,让你能很容易地理解它。

Vertical模式得到的预测块同一列中的像素值都是一样的。该模式得到的块就叫做Vertical预测块。注意,该模式只有在上边块存在的时候才可用,如果不存在则该模式不可用。比如图像最上边的块就没有可参考的块存在。

该模式下预测块像素计算方法如下:

示意图如下:

图片

  1. Horizontal模式

Horizontal模式就是指,当前编码亮度块的每一行的像素值,都是复制左边已经编码块的最右边那一列的对应位置的像素值(同样地,下面有计算方法和示意图)。Horizontal模式得到的预测块同一行的像素值都是一样的,该模式得到的块就叫做Horizontal预测块。注意,该模式只有在左边块存在的时候才可用,如果不存在则该模式不可用。比如图像最左边的块就没有可参考的块存在。

该模式下预测块像素计算方法如下:


示意图如下:
图片

  1. DC模式

DC模式就是指,当前编码亮度块的每一个像素值,是上边已经编码块的最下面那一行和左边已编码块右边最后一列的所有像素值的平均值。注意,DC模式预测得到的块中每一个像素值都是一样的。DC模式得到的块就叫做DC预测块。

根据上边块和左边块是不是存在,该模式下预测块像素的计算方法分为以下四种情况:


示意图如下:
图片

  1. Diagonal Down-Left模式

Diagonal Down-Left模式是上边块和右上块(上边块和右上块有可能是一个块,因为可能是一个16 x 16的亮度块,意思理解就可以)的像素通过插值得到如果上边块和右上块不存在则该模式无效。

该模式下预测块计算的方法分为下面两种情况:


示意图如下:

图片

  1. Diagonal Down-Right模式

Diagonal Down-Right模式需要通过上边块、左边块和左上角对角的像素通过插值得到。如果这三个有一个不存在则该模式无效

该模式下预测块计算的方法有以下三种情况:

示意图如下:
图片

  1. Vertical-Right模式

Vertical-Right模式是需要通过上边块、左边块以及左上角对角的像素插值得到的。必须要这三个都有效才能使用,否则该模式无效。

该模式下预测块计算的方法有以下四种情况:


示意图如下:
图片

  1. Horizontal-Down模式

Horizontal-Down模式需要通过上边块、左边块以及左上角对角的像素插值得到。必须要这三个都有效才能使用,否则该模式无效。

该模式下预测块计算的方法有以下四种情况:


示意图如下:
图片

  1. Vertical-Left模式

Vertical-Left模式是需要通过上边块和右上块(上边块和右上块有可能是一个块,因为可能是一个16 x 16的亮度块,意思理解就可以)最下面一行的像素通过插值得到。如果这两种块不存在则该模式不可用。该模式下预测块的计算方法有下面两种情况:


示意图如下:
图片

  1. Horizontal-Up模式

Horizontal-Up模式是需要通过左边块的像素通过插值得到的。如果左边块不存在,则该模式不可用。

该模式下预测块的计算方法有下面四种情况:

示意图如下:
图片

16 x 16亮度块的帧内预测模式

上面我们讲了4 x 4亮度块的9种预测模式,接下来我们来聊一下16 x 16亮度块的预测模式。

16 x 16亮度块总共有4种预测模式。它们分别是Vertical模式,Horizontal模式、DC模式Plane模式,前面三种模式跟4 x 4的原理是一样的这里就不重复讲解了。16 x 16亮度块的帧内预测的4种模式的示意图如下:

图片

图片

接下来我们介绍一下Plane模式。这种模式相比前面三种模式稍微复杂一些,但是基本原理都差不多。Plane预测块的每一个像素值,都是将上边已编码块的最下面那一行,和左边已编码块右边最后一列的像素值经过下面公式计算得到的

8 x 8色度块的帧内预测模式

上面我们讲述了亮度块的帧内预测模式,接下来我们简单介绍一下色度块的帧内预测模式。

8 x 8色度块的帧内预测模式跟16 x 16亮度块的是一样的,也是总共有4种,分别为DC模式、Vertical模式,Horizontal模式、Plane模式。与16 x 16亮度块不同的是,块大小不同,所以参考像素值数量会不同。但是基本是一致的,这里就不重复了。

帧内预测模式的选择

现在我们学习了这么多的模式,而每一个块却只能有一种帧内预测模式。那我们怎么确定一个块到底使用哪种模式呢?我们这边先把思路讲一讲,具体细节不展开。等到你把编码基础弄明白了之后可以阅读一下x264的代码,里面有关于具体如何去选择模式的方法。

以亮度块为例。一个16 x 16的亮度块,我们可以不划分,直接使用4种16 x 16的帧内预测模式,最多得到4种预测块;也可以划分成16个4 x 4的子块,每一个子块最多有9种帧内预测模式。

对于每一个块或者子块,我们可以得到预测块,再用实际待编码的块减去预测块就可以得到残差块。主要有下面3种方案来得到最优预测模式:

  • 第一种方案,先对每一种预测模式的残差块的像素值求绝对值再求和,称之为cost,然后取其中残差块绝对值之和也就是cost最小的预测模式为最优预测模式。
  • 第二种方案,对残差块先进行Hadamard变换(在DCT变换和量化那节课中会介绍),变换到频域之后再求绝对值求和,同样称为cost,然后取cost最小的预测模式为最优预测模式。
  • 第三种方案,也可以对残差块直接进行DCT变换量化熵编码,计算得到失真大小和编码后的码流大小,然后通过率失真优化(作为课外内容自行学习,这里不展开讨论)的方法来选择最优预测模式。
    为了让你更容易理解第三种方案,这里我稍微简单介绍一下率失真优化的思想

我们知道预测之后经过DCT变换再量化会丢失高频信息。一般来说QP越大,丢失的信息越多,失真就越大,但是码流大小也越小;反之,QP越小,丢失的信息越少,但是码流大小就越大。这是一个跷跷板。我们一般会在失真和码流大小之间平衡,尽量找到在一定码率下,失真最小的模式作为最优的预测模式,这就是率失真优化的思想

其实还有很多不同的方案,比如有的为了加速模式选择的过程,率失真计算的时候,只会进行DCT变换和量化,不会进行熵编码。码流大小直接通过QP值估算或者使用预测模式的大小来代替。这些方案都可以,具体看编码器的实现。一般来说,选择过程越精细效果越好,但是速度会越慢。

通过上面讲的这些方法我们找到了每一个4 x 4块的最优模式之后,将这16个4 x 4块的cost加起来,与16 x 16块的最小cost对比,选择cost最小的块划分方式和预测模式作为帧内预测模式。

小结

好了,今天的课到这里就要结束了。我们来回顾一下这节课的主要内容。

我们主要是一起聊了聊帧内预测。我们先详细讲述了有哪几种预测模式,以及各种预测模式的预测块的计算方法。同时强调一点,就是有的模式在参考像素不存在的时候是无效的,也就是不能使用的。这一点需要注意,并不是列举出来的每一个模式都是可以使用的。

为了方便你记忆,下面我把每一种块和子块支持的预测模式用一个表格来总结一下。


最后,我们还简单介绍了一下预测模式的选择方法,主要有计算残差块绝对值之和、将残差块做Hadamard变换之后再求和、率失真优化等几种方案来得到cost,然后我们取cost最小的模式作为帧内预测模式。

思考题

在H264标准里面,视频的第一帧的第一个块应该怎么选择预测模式呢?

你可以把你的答案留在评论区,和我一起探讨、交流,看看自己的理解是不是正确。下节课再见。

精选留言

  • paradise

    2021-12-03 13:48:40

    在 H264 标准里面,视频的第一帧的第一个块的左和上都是空,没法预测,所以设置成了一个约定值128,方便编码。这边找个几个264的码流,第一个I帧的第一个4*4 子块的yuv 预测值全都是128,大家也可以找个264的码流确认一下
    作者回复

    回答的非常棒

    2021-12-06 18:02:49

  • 我有一条鱼

    2021-12-23 13:42:29

    想问一个问题:

    4x4、16x16不同大小的块为什么会有不同的预测模式。

    我理解预测模式只是参考不同方向已经编码过的块找出差异最小的,最容易变出更多0的方式。这样想的话是不是4x4的9种预测模式都是可以使用在16x16上的?还是说已经验证16x16上效果一定会很差?
    作者回复

    单纯从编码压缩性能来说是模式当然是越多越好。但是我们还要兼顾编码速度的。16 x 16的块一般用在相对平坦的区域,也就是细节相对少一些的区域,模式少一点对编码速度会好一些。而对于细节多的地方,我们需要更精细化编码,所以块也更小、模式也更多。

    2021-12-24 09:40:18

  • Geek_9c9938

    2023-11-08 21:42:16

    李老师好

    文中 '通过上面讲的这些方法我们找到了每一个 4 x 4 块的最优模式之后,将这 16 个 4 x 4 块的 cost 加起来,与 16 x 16 块的最小 cost 对比,选择 cost 最小的块划分方式和预测模式作为帧内预测模式'

    意思是说:
    第一步、一个 16 * 16 的宏块需要先分成 16 个 4 * 4 大小的子块,每个 4 * 4 的子块分别做 9 种模式的预测,16 个 4 * 4 的子块就是 16 * 9 = 144 次预测,
    每个 4 * 4 子块得到 9 个 cost 取其中 cost 最小的预测模式为最优预测模式,这个最小的 cost 也就是这个子块最终的 cost,16 个 4 * 4 子块得到 16 个最终的 cost,再将这 16 个 cost 求和得到这 16 个 4 * 4 子块的最终的一个 cost

    二、再通过 16 * 16 的宏块做 4 次预测得到 4 个 cost,同样取其中 cost 最小的预测模式为最优预测模式,同样这个最小的 cost 也就是这个宏块最终的 cost,最后比较这个 16 * 16 宏块的 cost 与上一步得到的16 个 4 * 4 子块的最终 cost,
    如果第一步中的最终 cost 小,则这个 16 * 16 宏块预测过程和结果都丢弃(或者说都没有用了)使用 16 个 4 * 4 个子块这种块划分方式和它们对应的 16 种最优预测模式,反过来如果第二步中的最终 cost 小则 16 个 4 * 4 子块的块划分和预测模式预测模式都丢弃(或者说都没有用了)使用 16 * 16 宏块划分方式和对应的最优预测模式

    是这样吗 ?
    作者回复

    是的

    2025-04-01 19:59:17

  • chao

    2022-01-11 11:43:53

    是每个块都要做帧内预测模式选择吗?
    如果是的话,感觉计算量很大,假如都是4*4的块,每个块都要计算9遍然后选出一个最优的。
    作者回复

    所以一般会有多种编码速度供你选择,在快速档会有一些快速算法根据块和周边块的像素特点提前判断编码模式,得到的就不一定是最优解。在慢速档就可能会每种模式都遍历得到的就是最优解。这也是我在第一节课说的,不是码率高就清晰度高。

    2022-01-14 12:45:01

  • tony

    2021-12-25 23:26:37

    帧内预测模式选择16x16或者4x4时,要综合考虑cost,编码速度,是否平坦等等,编码速度以及是否平坦是如何衡量的?
    作者回复

    1、模式的选择其实最后是看cost的,其实在选择的时候并不会看平不平坦,因为一个16x16的块如果划分的话,要划分成16个4x4的块,每一个块都需要带模式等额外的信息也需要消耗码率,所以如果图像区域确实是平坦的,在模式选择的时候16x16的块计算出来的cost会比16个4x4总cost要小。所以我们一般会说平坦区域更适合16x16的大小,但实际上最后还是通过cost大小来判断的。
    2、编码速度可以通过编码器的参数设置,比如x264可以通过preset来设置。设置速度快的话编码器内部会把一些编码工具关闭不使用它们。这样速度就快了,但是编码效果就差一些。

    2021-12-29 10:17:55

  • 翔链智深

    2022-06-11 19:06:37

    老师问下,如何断绝预测块的误差蔓延(比如说上一个的预测块不准确编码成为编码块,后续的预测块在这已编码有误差的编码块的基础上进行预测,好比帧间预测有IDR帧,那帧内是否也有这个机制)
    作者回复

    其实残差可以补偿这部分的误差的,但是如果你解码出错了的话,那么确实会出现严重的误差的,比如说花屏。这种时候就只能到下一个关键帧才能完全解决了

    2025-04-01 20:19:34

  • 余健辉

    2022-01-26 07:48:50

    老师,想请问下后面的计算公式中为什么几个像素值加上后还要加上4或者2或者1再去做除法呢,对这一点有点疑惑
    作者回复

    四舍五入

    2022-01-29 10:15:30

  • ROYIS

    2021-12-27 16:36:24

    算平均值偏要写成移位操作,不容易看懂啊
    作者回复

    因为编码器代码一般都是用移位操作的,养成这个习惯吧。

    2021-12-28 12:06:21

  • 为了维护世界和平

    2022-11-14 09:03:50

    参考帧是如何选择的?
    作者回复

    如果只有一个参考帧,那么就没有选择的余地。如果是多个参考帧的话,那么就会遍历所有的参考帧,选择cost最小的

    2022-11-21 17:02:15

  • FamliarMan

    2022-08-23 08:38:43

    有几个问题没能理解,第一,第一帧的第一个编码块如何确定;第二,我们如何确定相邻的块一定是连续的,万一遇到那种泾渭分明的呢?所以是不是有什么算法用来确认相邻块可以预测?
  • lytasky

    2022-06-28 20:50:47

    请教下:有个疑问:
    比如 4*4 Vertical 模式,A B C 是从上到下的3个快 。 B的每一列都取A最下面一行(a,b,c,d)的像素值,则B的4列分别为全a,全b,全c,全d,那么C的每一列应该取B最下面一行的像素值,则C的4列是不是也是全a,全b,全c,全d,以此类推,再往下D、E、F都是这样的? 是我理解错了吗?
  • 翔链智深

    2022-06-11 18:52:34

    老师,问下如何选定采用4*4还是16*16的宏块(一般图像更多细节的时候选4*4?那么怎么判断图像更多细节复杂?)
  • A君

    2022-04-12 20:52:19

    帧内预测,用已经编码好的子块预测相邻块,可以减小码流大小。
  • ilio

    2022-03-09 09:21:54

    请教一下老师,一帧里边每个宏块的预测模式都是不一样的吗
    作者回复

    是不一样的

    2022-03-12 09:30:39

  • T------T

    2022-01-27 10:37:33

    老师好,我看到4X4 模式下有9中预测模式。但是参考方向只有左、左上、上、右上。
    实际编码过程中是否是:
    从左上角开始,按行从左至右逐个计算每个宏块的像素值?
    作者回复

    是的,因为其他方向对应的位置的块是没有编码,因此不能用来做参考

    2022-02-18 23:00:16

  • 易水南风

    2022-01-04 17:30:39

    老师,每个宏块的预测中的参考像素都是非预测的么?还是也可以是预测的?
    作者回复

    预测使用的参考像素都是已经编码好了的像素,就是编码模式已经定了的。这些参考像素在编码的时候也是预测编码得到的。

    2022-01-06 16:22:46

  • 扁担

    2021-12-23 22:34:40

    16x16中的16 是指16个像素吗
    作者回复

    是的

    2021-12-24 09:31:45

  • !null

    2021-12-22 23:18:52

    Plane我是里边,预测块计算公式里好像没用到前边算出来的中间变量。
    作者回复

    不好意思,这个地方确实是错误的,我修改一下。谢谢兄弟提醒

    2021-12-24 09:37:08

  • J

    2021-12-22 22:37:41

    DC 模式的第四种模式😂
  • 写点啥呢

    2021-12-06 11:20:14

    请教下老师,在编码过程中每个块对应的预测模式是否也需要编码到码流中呢,这样解码方可以根据模式进行相同操作得到预测块,加上残差后得到实际的像素信息?
    作者回复

    需要的

    2021-12-06 17:59:22