关键词: 视频 , 压缩
前言
视频压缩算法通过对视频信号的压缩处理可以极大地降低视频信号的存储和带宽需求,在此基础上尽可能多的获得最佳的图像质量。因此,了解视频压缩算法的基本原理对于嵌入式系统,处理器以及视频应用工具的开发人员来说,是非常必要的,例如在处理器选型以及软件优化的过程中,视频压缩算法的性能开销和存储空间占用就是其中非常关键的因素。
在本文中,我们将着重探讨视频压缩算法的特点和处理流程,我们将对基本的视频压缩算法进行解释,包括静态图像压缩、运动估计、图像去噪, 以及色彩空间转换,同时我们还将讨论视频压缩算法对处理器的性能需求以及由这些需求所带来的一系列影响。
静态图像压缩
视频剪辑也就是我们通常所说的动态图像序列,动态图像序列是由在时间轴上的若干幅静态图片组成的,在动态图像序列中的每一幅图片称之为“帧”。在动态图像的压缩算法中大量的使用了静态图像压缩的算法和技术,例如静态图像压缩标准JPEG。实际上简单的动态图像序列压缩的方法就是将此序列中的每一幅静态图片独立的压缩,忽略掉这些图片在时间上的相关性。在一些视频产品的应用中使用了这种方法,将每一幅图片都用JPEG标准进行压缩,我们称之为“运动JPEG”或者也叫MJPEG。
目前更为先进的视频压缩算法更多的利用了视频序列中连续的静态图像,也就是连续帧之间的时间相关性,利用运动估计和运动补偿算法获得更好的压缩比,当然这些先进的视频压缩算法也同样采用了静态图像压缩里面的一些基本算法,因此我们的讨论就从基于块变换的静态图像算法JPEG开始。
数字图像压缩的基本单元
块变换
在JPEG和大多视频压缩算法中所采用的压缩算法都是“有损压缩”,所谓有损压缩就是指从压缩后的数据中无法完全恢复重构出原始的压缩前图像,有损压缩会丢失掉一部分原始图像的信息,因此,有损压缩算法就需要尽量保证由信息丢失所造成的原始图像和重构图像之间的差异不被人眼所察觉。
对于JPEG和类似的图像压缩算法来说,压缩的第一步需要将图像分割为小块,同时将每个小块进行变换,使之由空域信号变换成为时域信号。这种空域到时域的变换多采用8x8的离散余弦变换(以下称DCT),经过DCT变换之后,8x8的空域像素矩阵变换成为 8x8的频域信号矩阵,DCT变换能够完整的保留所有8x8像素块的信息,因此反向离散余弦变换(以下称IDCT)也就能够从8x8频域信号矩阵中完整的恢复原始8x8像素矩阵。DCT变换后的频域信号矩阵中包含原始8x8像素矩阵的低频部分和高频部分,其中低频部分对应图像的重要信息,高频部分对应图像的细节信息,就人眼的特点来说,对于图像低频部分的感知要比对于图像高频部分的感知敏感很多,因此在DCT变换将图像的信息按照其人眼感知的敏感程度分离之后,后续的压缩步骤就是将其低频部分编码更多的比特,从而获得更高的精度,而对其高频部分编码更少的比特数或者不编码比特,从而在保留一定的视觉效果的同时,获得更好的压缩效果。在解码端,再用IDCT变换从频域信号矩阵中恢复出原始8x8像素矩阵。
IDCT变换和DCT变换的运算量基本一致,因此这两种变换对处理器的性能要求也基本类似。一个二维8x8 DCT变换和IDCT变换在典型的DSP平台上需要数百个指令周期完成,视频压缩算法的执行中每秒都需要进行大量的DCT和IDCT运算,以一个 MPEG4的解码器为例,在解码分辨率为CIF(352x288),帧率为30fps的视频序列时,需要每秒进行71,280次IDCT运算,在TI TMS320C55x DSP处理器平台上需要占用40MHz的处理性能(不考虑集成DCT加速器),这大概占用了整个视频解码器应用时处理器性能的30%。
由于DCT和IDCT运算的单位都是很小的图像块,因此相对于帧缓存以及图像压缩应用中的其他数据存储来说,其对存储资源的占用几乎可以忽略不计,正是基于其大运算量,低存储占用的特点,DCT和IDCT运算单元特别适合用专用的硬件加速协处理器来实现。
量化
DCT变换后的结果称为DCT系数,正如上文所说,编码器需要对于DCT系数中的重要的低频分量编码更多的比特,对于DCT系数中的次要的高频分量编码更少的比特,这种对系数的编码方法可以通过两步来实现:首先通过量化过程舍去次要的视频信息,然后利用统计学的方法尽可能少的对剩余的重要信息进行比特编码。
量化过程就是将每个DCT系数向若干预设值进行舍入的过程,例如,DCT系数是值介于-1 到1 之间的实数,将其用缩放因子20进行缩放,同时将结果舍入到最近的整数,于是DCT系数便量化成为值介于-20到20之间的整数,共有41个,在理想情况下,为每个DCT系数选择合适的量化因子可以使量化后的DCT系数在向右取整的过程中不至于引入明显的量化噪声。
在解码端,采用与编码端相反的反量化过程,就上文所属的例子来说,对量化后的DCT系数进行反量化,用1/20进行缩放,反量化值缩放到-1到1之间,注意此时的反量化值与原始的量化前系数已经不再相等,不过足够接近,以保证IDCT 变换以后不会引入明显的视觉差异。反量化大概需要占用整个视频解码器应用时处理器性能的3%-15%,与DCT和IDCT变化类似,量化和反量化对存储器的资源占用可以忽略不计。
编码
压缩的下一个步骤即是对量化后的DCT系数进行比特编码,使之成为传输比特流,为了尽可能少的编码比特数,达到数据压缩的效果,需要利用量化后的DCT系数的一些统计特性。
量化后的DCT系数的值大多是0值,特别是大量的高频DCT系数分量,一种叫做“游程编码”(以下称run-length编码)的技术可以很好的利用DCT 系数的这一特点,在这种编码技术中,并不对每个0值系数单独编码,而是将连续的0值(run)进行打包,然后再对这些连续0值系数的个数(length) 进行编码。
为了更大程度的利用run-length编码的特点,需要对8x8系数矩阵进行zig-zag扫描,保证先对低频系数分量进行编码,然后再对高频系数分量进行编码,这样做的目的是因为在高频系数分量中出现大量连续0值系数的概率更高。
Run- length编码完成后即进行变长编码(VLC),在变长编码中,每个可能出现的数据值作为一个符号(例如每种可能run-length值作为一个符号),出现概率大的符号值用比特数更少的码字表示,出现概率小的符号值用比特数更多的码字表示,变长码相对于定长码使用的比特数更少,(定长码是一种直接编码方法,例如直接将每个量化后DCT系数编码为其二进制表示),因此变长码在编码一幅图像时所消耗的平均比特数更少。在变长码编码中,哈夫曼编码是一种广泛使用的编码方法,基于每个符号的发生频率,哈夫曼编码可以获得更优的编码效果。
理论上,对一组符号序列来说,变长编码并不是最优的编码方法,相对于变长编码来说,“算术编码”的编码比特数更少,编码效果更好。变长编码为每个符号分配单独的码字,因此每个符号都需要整数个比特个数(即每个符号至少占用1个比特),算术编码将一组符号序列作为一个整体来进行编码,因此并不是每个符号都需要占用比特,因此可以获得更大的压缩率,但是算术编码的运算法杂程度远远大于变长编码,因此只在最近的一些商用视频压缩算法中获得应用,相对于算术编码,在很多应用中,run-length编码和变长编码的组合编码方法相对于算术编码运算复杂程度低,编码效率足够,因此时至今日变长编码仍然在大量的视频压缩协议中广泛应用。
变长编码通过对码字和其长度的查找表实现,完成查找后将码字取出填充进比特流输出,对应的解码端过程称之为变长解码(VLD),最直接的变长解码做法需要对每一个比特都要进行查表操作和判决,相对于变长编码对每一个符号所进行的查表操作来说,这种变长解码的方法运算量更加密集,平均每个比特需要进行11步操作,因此变长解码的处理性能需求是和解码器的解码码率成正比的,对于一些低分辨率和低码率的视频序列来说,变长解码往往占到整个解码器应用时处理器性能的 25%。
在一个典型的视频解码器中,上文所描述的这种最直接的变长解码方法需要占用数KB大小的存储空间用于存放查找表,为了获得更高的解码性能,可以采用一次处理一批比特的做法,当然,这种做法需要付出更大存储空间的代价。
变长编码的缺点在于,当编码后的图像或者编码后视频帧的比特流中出现误码时,解码端将无法正确恢复误码后的图像部分,一旦出现误码,解码端就无法识别误码所对应的正确码字的长度,因此也就无法识别下一个正确码字在比特流里的起始位置,也就无法继续解码图像。一种技术可以部分解决这个问题,该技术在编码比特流中预先插入“重同步标志”,重同步标志的插入位置和内容是事先定义好的,因此解码端在解码过程中能够对重同步标志进行正确定位,因此当误码发生的时候,解码器可以从误码位置向后搜索下一个重同步标志,然后可以从这个重同步标志以后解码出后续的图像部分。
此外,在MEPG4视频压缩标准中,还采用了称为“反向变长码”的技术,在反向变长码中,码字的选择保证了其不但能够从普通的正向进行解码,同时也能够从反向进行解码,因此当误码发生的时候,解码端可以向下搜索下一个重同步标志,搜索到了以后,再从重同步标志的位置反向解码至误码位置,因此解码端能够尽可能多的恢复图像数据。
到此为止,上面描述的所有技术都是针对一个独立的8x8的像素块,一幅图像所包含的信息远大于一个8x8像素块所能包含的信息,因此利用相邻块彼此的相关性可以应用更多更有效的压缩方法。
为了利用块与块之间的相关性,可以采用预测的技术,编码器在对DCT系数进行量化之前,可以基于周边块的DCT系数预测当前块的DCT系数,然后对预测值和当前实际值的差值进行量化,而不是直接对当前DCT系数进行量化,由于这个差值往往比较小,因此这项技术可以减少对DCT系数编码的比特数,对于解码端,采用相同的预测方法,然后将从码流解码出来的差值加上预测出来的预测值,就可以重构出实际的DCT系数值,需要注意的是,由于解码端只能够获得那些在当前块解码前已经解码的块的DCT系数,因此编码端必须保证只用到那些在编码当前块之前已经编码的块的DCT系数作为预测值。
对于最简单的情况,只对每个块的第一个系数进行预测,这个系数被称作“DC系数”,它代表 DCT系数里的最低频分量,等于所有块像素的均值,其余的系数被称作“AC系数”。这种最简单的做法是基于这样的假设,即当前块的DC系数等于左边相邻块的DC系数,这种做法利用了当前块和左边相邻块的空间相关性,对当前块和前一编码块的DC系数的差值进行编码,被称为“DC系数差分编码”,在JPEG图像压缩标准中得到了广泛的应用。
也有一些更为复杂的预测方法,例如对8x8块的每一行和每一列的第一个DCT系数进行预测,这样的方法被称作“AC-DC预测”,同上面所描述的差分编码的方法相比,这种方法采用了更为复杂的预测方法,首先,对预测值的计算采用了滤波的方法,而不是简单的等于相邻块对应的系数,其次,预测值的产生可能要考虑多个相邻块,预测值可能是基于多个块预测值的组合,同样,编码器会从多个预测块中选出一个来获得最好的预测效果,这样的话编码器就必须在码流中表明哪一个相邻块被选中,这样解码器才能够进行同样的预测过程正确重构DCT系数。
来源:Berkeley Design Technology, Inc.
评论
查看更多