当前位置: 首页 > news >正文

音视频学习(四十一):H264帧内压缩技术

帧内压缩,顾名思义,是对单个视频帧进行独立压缩,不依赖于其他帧的数据。这与利用帧间预测(如P帧和B帧)的帧间压缩形成对比。帧内压缩的核心思想是利用图像内部的空间冗余,即相邻像素之间通常存在很强的相关性。H.264的帧内压缩技术在MPEG-2等前代标准的基础上进行了显著增强,主要体现在更细致的块划分、更丰富的预测模式以及更优化的变换和量化过程。

块划分与宏块结构

在H.264中,视频帧首先被划分为一系列的宏块(Macroblock, MB),每个宏块的大小为16x16像素(对于亮度分量Y,色度分量Cb和Cr则根据采样格式有所不同,通常是8x8)。宏块是H.264编码的基本单元。

与早期标准不同,H.264引入了更灵活的子宏块划分(Sub-Macroblock Partitioning)。一个16x16的宏块可以进一步划分为:

  • 16x16块
  • 16x8块
  • 8x16块
  • 8x8块

而8x8的子宏块还可以进一步划分为更小的块,例如:

  • 8x8块
  • 8x4块
  • 4x8块
  • 4x4块

这种可变块大小(VBS)的灵活划分方式,使得编码器能够根据图像内容的纹理和细节变化,选择最合适的块大小进行编码。例如,对于平坦区域,可以使用较大的块来提高编码效率;对于纹理丰富

帧内预测(Intra Prediction)

帧内预测是H.264帧内压缩最关键的技术之一。其核心思想是利用当前块周围已经编码并重建的像素信息,预测当前块的像素值。编码器不传输原始像素值,而是传输原始像素值与预测值之间的残差(Residual)。由于相邻像素通常高度相关,预测残差的能量远小于原始块的能量,因此残差数据量小,更易于高效压缩。

H.264为亮度(Y)分量和色度(Cb, Cr)分量提供了不同的预测模式。

亮度分量的帧内预测

亮度分量的预测模式根据块大小而有所不同:

a) 4x4亮度块预测(Intra_4x4) 对于4x4的亮度块,H.264提供了9种预测模式:

  • 模式0:垂直预测(Vertical):利用上方已编码像素的平均值作为当前块的预测值。

在这里插入图片描述

  • 模式1:水平预测(Horizontal):利用左侧已编码像素的平均值作为当前块的预测值。

在这里插入图片描述

  • 模式2:直流预测(DC):利用上方和左侧已编码像素的平均值作为当前块的预测值。如果上方或左侧没有可用像素,则全部设为128。

在这里插入图片描述

  • 模式3-8:对角线及方向性预测(Diagonal and Directional):这6种模式是不同方向上的对角线或斜向预测,通过线性插值或直接复制周围像素来生成预测值。这些模式能够更好地适应图像中的边缘和纹理方向,从而更精确地进行预测。下图为其中一种示例:

在这里插入图片描述

编码器会为每个4x4块评估所有可用的预测模式,并选择使残差最小(通常通过SAD或SATD衡量)的模式。所选模式的信息会作为头部信息进行传输。

b) 16x16亮度块预测(Intra_16x16) 对于16x16的亮度块,H.264提供了4种预测模式:

  • 模式0:垂直预测(Vertical):与4x4垂直预测类似,扩展到16x16。
  • 模式1:水平预测(Horizontal):与4x4水平预测类似,扩展到16x16。
  • 模式2:直流预测(DC):与4x4直流预测类似,扩展到16x16。
  • 模式3:平面预测(Plane):这是一种更复杂的预测模式,它假设当前块的亮度值近似于一个平面,并通过其周围已编码像素来拟合这个平面,从而生成预测值。平面预测在图像亮度平缓过渡的区域表现优异。

选择16x16预测模式还是4x4预测模式由编码器根据编码效率决定。通常,对于平坦区域,16x16的预测效率更高;对于细节区域,4x4的预测更为精细。

色度分量的帧内预测

色度(Cb和Cr)分量的预测通常基于8x8的块。H.264为色度分量提供了4种预测模式:

  • 模式0:直流预测(DC):与亮度直流预测类似。
  • 模式1:水平预测(Horizontal):与亮度水平预测类似。
  • 模式2:垂直预测(Vertical):与亮度垂直预测类似。
  • 模式3:平面预测(Plane):与亮度平面预测类似。

选择这些模式的方式与亮度分量类似,都是为了最小化残差。

残差值计算

残差值计算

在视频编码(如H.264)的帧内压缩中,残差值(Residual Value)的计算是至关重要的一步。简单来说,残差值就是原始图像数据与预测图像数据之间的差值。这个过程可以数学表示为:

残差值=原始像素值−预测像素值

或者对于一个图像块:

残差块=原始图像块−预测图像块

为什么需要计算残差值?

视频编码的目标是最大限度地去除视频数据中的冗余,从而实现高效压缩。图像或视频帧中的像素之间存在大量的空间冗余(相邻像素相似)和时间冗余(相邻帧相似)。预测技术就是为了利用这些冗余。

  • 预测:编码器通过某种算法(例如H.264的帧内预测模式)根据已经编码的相邻像素来生成一个预测值预测块。这个预测值越接近原始值,说明预测越准确。
  • 残差:如果预测非常准确,那么原始值和预测值之间的差值(即残差)就会非常小,甚至为零。
  • 压缩优势:编码器传输的不是原始像素值,而是这个残差值。由于残差值通常比原始像素值具有更小的幅度和更少的统计冗余(例如,很多残差值会是零或接近零),因此它更容易被高效地进行变换、量化和熵编码,从而实现更高的压缩比。

计算流程

宏块划分

H.264 将帧划分为多个宏块(Macroblock):

  • 每个宏块大小通常为 16×16;
  • 宏块会进一步划分为子块(如 4×4、8×8)用于预测。

帧内预测

对每个子块(如 4×4)执行帧内预测,得到预测图像:

  • 利用已编码的左侧、上方、左上、右上等像素;
  • 预测模式包括:垂直、水平、DC、斜向等。

举例:4×4 预测模式之一 —— 垂直预测

在这里插入图片描述

即每列使用其上方像素值作为预测值。

残差计算

对每个像素执行减法操作:

在这里插入图片描述

示例:

假设某 4×4 原始块为:

[[110, 112, 115, 117],[108, 111, 114, 116],[107, 110, 113, 115],[105, 108, 111, 114]]

预测值(使用 DC 模式)为:

[[110, 110, 110, 110],[110, 110, 110, 110],[110, 110, 110, 110],[110, 110, 110, 110]]

则残差值为:

[[ 0,  2,  5,  7],[-2,  1,  4,  6],[-3,  0,  3,  5],[-5, -2,  1,  4]]

残差矩阵用于后续变换编码

该残差矩阵将传递给变换模块(整数 DCT)、量化模块,进一步压缩存储。

总结

  1. 块划分:原始图像帧首先被划分为宏块(16x16)和子宏块(如4x4、8x8等)。
  2. 帧内预测:对于当前正在编码的图像块,编码器会根据其上方和左侧(已经编码并重建的)相邻像素,使用多种帧内预测模式(如垂直、水平、直流、对角线等)生成一个预测块
  3. 计算残差:将原始图像块的每一个像素值减去对应位置上预测块的像素值,从而得到一个残差块。这个残差块通常包含了图像中预测失败的细节和纹理信息。
    • 例如,如果原始块中的某个像素是150,而预测值是148,那么残差值就是 150−148=2。
    • 如果原始块中的某个像素是50,而预测值是52,那么残差值就是 50−52=−2。 残差值可以是正数、负数或零。
  4. 后续处理:得到的残差块会进行下一步处理:
    • 变换(Transform):将残差块从空间域转换到频率域(例如使用4x4或8x8整数DCT),将能量集中到少数几个系数上。
    • 量化(Quantization):对变换后的频率系数进行有损压缩,将大部分小幅度的系数置为零,进一步减少数据量。
    • 熵编码(Entropy Coding):对量化后的系数进行无损压缩,生成最终的比特流。

残差应用

在解码端,整个过程是逆向的。解码器接收到的是熵编码后的残差信息和预测模式信息。

  1. 熵解码:恢复出量化后的变换系数和预测模式。

  2. 反量化和反变换:将系数进行反量化和反变换,恢复出残差块

  3. 重建:根据传输过来的预测模式,解码器利用已重建的相邻像素,生成相同的预测块

  4. 像素重建:将反变换得到的残差块与预测块相加,即可重建出原始图像块:

    重建像素值=预测像素值+残差值
    

通过这种方式,解码器能够精确地恢复出原始图像数据(在有损压缩中会有一些误差)。

变换(Transform)

经过帧内预测后得到的残差数据仍然存在一定的空间相关性。为了进一步去除这些冗余,H.264采用了基于整数离散余弦变换(Integer Discrete Cosine Transform, DCT)的变换技术。

  • 4x4整数DCT:H.264主要使用4x4的整数DCT。这种变换将空间域的像素残差数据转换到频率域,将能量集中到少数低频系数上。与传统的浮点DCT相比,整数DCT避免了浮点运算误差积累,简化了硬件实现,并保证了编解码的一致性。
  • 8x8整数DCT(可选):对于较大的块(如8x8),H.264也支持8x8的整数DCT。这在某些情况下可以提供更好的压缩效率,尤其是在图像内容比较平坦的区域。

变换后的系数被称为变换系数频率系数。这些系数代表了原始残差块在不同频率分量上的强度。

量化(Quantization)

量化是视频压缩中实现有损压缩的关键步骤,也是控制压缩比和图像质量的主要手段。经过变换后的频率系数通常是浮点数或高精度的整数,量化的目的是减少这些系数的精度,将其映射到有限的离散值上,并尽可能地将许多系数变为零,从而实现数据量的显著减少。

H.264的量化特点包括:

  • 统一的量化步长(Quantization Parameter, QP):H.264使用一个QP值来控制量化程度。QP值的范围通常是0到51,QP值越大,量化步长越大,量化越粗糙,压缩比越高,但图像质量损失也越大;反之,QP值越小,量化越精细,图像质量越好,但压缩比降低。
  • 自适应量化:编码器可以根据图像内容的复杂性、感知的重要性(例如人眼对亮度比色度更敏感)以及比特率限制等因素,动态调整不同宏块或区域的QP值,以达到更好的视觉质量。
  • 可逆性:H.264的量化和反量化过程是基于整数运算,并具有很高的可逆性,这有助于保持编解码之间的一致性。

量化后的系数,特别是高频系数,会有很多变为零,这为后续的熵编码提供了极大的便利。

熵编码(Entropy Coding)

经过变换和量化后的系数以及各种预测模式信息、块划分信息等,需要进行熵编码,以进一步去除统计冗余,实现无损压缩。H.264支持两种主要的熵编码方法:

  • CAVLC(Context Adaptive Variable Length Coding,基于上下文的自适应可变长编码):CAVLC是H.264 Baseline、Main和Extended Profile中使用的默认熵编码方法。它根据上下文信息为不同的语法元素选择不同的可变长码表。例如,对于量化后的变换系数,CAVLC会根据周围已编码系数的统计特性,自适应地选择码表,从而提高编码效率。
  • CABAC(Context Adaptive Binary Arithmetic Coding,基于上下文的自适应二进制算术编码):CABAC是H.264 High Profile及更高版本中引入的更高级的熵编码方法。它比CAVLC更复杂,但效率更高。CABAC通过将所有语法元素映射到二进制位流,并利用上下文模型进行概率估计,然后进行算术编码。由于其更精确的概率建模,CABAC通常能比CAVLC提供10%-20%的额外压缩增益。

熵编码是视频压缩的最后一步,它将所有经过处理的信息转化为比特流,以便存储或传输。

帧内压缩的优势与应用

H.264的帧内压缩技术带来了诸多优势:

  • 高压缩效率:通过精细的块划分、多样的预测模式、高效的变换和量化以及先进的熵编码,H.264在保持较高图像质量的同时,能够实现比MPEG-2等前代标准更高的压缩比。
  • 错误鲁棒性:I帧(仅使用帧内压缩的帧)是独立编码的,不依赖于其他帧。这意味着即使在传输过程中发生错误,导致某些P帧或B帧数据丢失,I帧也能独立解码,从而限制错误传播的范围,提高视频流的错误鲁棒性。这对于网络传输和存储非常重要。
  • 随机访问:由于I帧包含完整的图像信息,可以在I帧处进行快速跳转和随机访问,这对于视频编辑、快进/快退以及流媒体的起始播放非常有利。
  • 降低解码复杂度(对于I帧):I帧的解码只需要当前帧的信息,不需要查找参考帧进行运动补偿,因此相对P帧和B帧,I帧的解码复杂度较低。

H.264的帧内压缩技术广泛应用于:

  • 视频监控:许多DVR/NVR系统使用H.264编码,其I帧的错误鲁棒性对于监控录像的可靠性至关重要。
  • 视频编辑:在视频编辑工作流中,常常使用I帧为主的编码格式(如All-Intra格式),以方便精确剪辑和快速定位。
  • 流媒体的起始点:当用户开始观看一个流媒体视频时,通常会从最近的I帧开始解码,以确保能够快速显示图像。
  • 蓝光光盘和高清电视:H.264是这些高清视频应用的标准编码格式,其帧内压缩技术为高质量视频提供了基础。

总结

H.264的帧内压缩技术是其卓越性能的基石。它通过对图像内部空间冗余的深度挖掘和高效利用,实现了在单个视频帧层面的高压缩比和高质量重构。从灵活的宏块划分到精细的帧内预测,再到高效的整数变换、可控的量化以及先进的熵编码,H.264的每一个环节都经过精心设计和优化,共同构成了其在视频压缩领域的核心竞争力。理解这些技术细节,对于深入掌握H.264编码原理、优化编码参数以及进行视频系统设计都至关重要。

http://www.xdnf.cn/news/1156681.html

相关文章:

  • 【Vue进阶学习笔记】Vue 路由入门指南
  • 单线程 Reactor 模式
  • 动静态库的制作和原理
  • 【unitrix】 6.10 类型转换(from.rs)
  • [BUG]关于UE5.6编译时出现“Microsoft.MakeFile.Targets(44,5): Error MSB3073”问题的解决
  • 【软件测试】从软件测试到Bug评审:生命周期与管理技巧
  • VUE2 学习笔记2 数据绑定、数据代理、MVVM
  • 【数据结构】第一讲 —— 概论
  • 基于Arduino的智能寻迹小车设计
  • 剑指offer——链表:旋转数组的最小数字
  • 【OD机试】池化资源共享
  • 「Java案例」利用方法求反素数
  • Ubuntu挂载和取消挂载
  • LP-MSPM0G3507学习--07定时器之二定时节拍
  • ZYNQ平台深度剖析:EMMC/FLASH/SD卡性能测试与创新实践
  • 从磁记录到数据中心:磁盘原理与服务器架构的完整技术链路
  • 两个数据表的故事:第 1 部分
  • Spring之事务使用指南
  • Java行为型模式---解释器模式
  • Openlayers 面试题及答案180道(121-140)
  • Node.js Express keep-alive 超时时间设置
  • @import导入css样式、scss变量用法、static目录
  • Java中List<int[]>()和List<int[]>[]的区别
  • PAT 1049 Counting Ones
  • 医学图像超分辨率重建深度学习模型开发报告
  • 如何用immich将苹果手机中的照片备份到指定文件夹
  • Word for mac使用宏
  • UniApp 常用UI库
  • 机器视觉---深度图像存储格式
  • 闲庭信步使用图像验证平台加速FPGA的开发:第二十五课——正弦波图像的FPGA实现