天天看点

图像编解码器

基于图像的编解码器是编码或解码单独一副图像或者视频序列中的一帧图像,而图像编解码器是由变换编码和量化以及熵编码所构成的

下图为图像编解码过程

图像编解码器

###############################################################################

变换编码

变换编码是将图像从空间域(spatial domain)变换到其他域,以便使其更适合于压缩。此变换可用于图像的离散块(块变换)或整幅图像

1.块变换

图像空间的样本用离散块的形式进行处理,典型的块大小是8x8或者16x16。每一个块用一个二维变换产生一个变换系数的块。为图像压缩而进行的块变换的效果取决于去除每一个块中信息的相关性的程度。

KL变换

KL变换(the Karhunen-Loeve transform, KLT)是任何基于块的图像变换中效果最好的。

KL变换产生的系数被去相关并且块中的能量被集中在最少数的系数上。但是,KL变换计算的效率最低,而且不实用,因为执行变换所需的方程(基本方程)必须预先计算出来并且每幅图像都要将该方程传给编码器。

离散余弦变换(the discrete cosine transform, DCT)

DCT变换和KL变换的效果很接近而且计算效率高。

例如一个16x16块的图像样本,由DCT变换产生相应的系数块。在原始块中,能量分布在256个样本中并且后部很明显地具有高的相关性。在系数块中,能量集中在少量的重要系数中(在左上方),且系数是不相关的,这意味着数值比较小的系数可以被忽略(例如通过量化),而不会对解码端重建图像快的质量造成较大的影响。

2.图像变换

基于实用的考虑,DCT变换通常被用于小的、离散的图像块上。相比较而言,图像变换则可以应用在一整幅的视频图像(或者是图像内的一个大块)上。

这种类型最常见的是离散小波变换(Discrete Wavelet Transform).

一个二维的离散小波变换被应用在原始图像上以便把一系列步骤分解成一系列滤波的“子带”(sub-band)图像。这个过程由一系列分量组成,每个分量包含了图像空间频率的一个子集。左上方是一个原图经低通滤波的样本,往右下方,每一个分量逐渐包含了图像细节的高频信息。很明显,高频的分量相对而言比较少,也就是说这些分量中的很多数值(或系数)是零或者不重要。因而,小波变换是一种有效的方法,它可以去除相关性或将重要信息集中到少数有意义的系数上。

小波变换对于静态图像的压缩特别有效,目前已经被JPEG-2000标准所采纳。

###################################################

量化

以上介绍的块和图像变换本身并没有实现任何的压缩。但是,它们在另一个域中表示图像,在那里图像数据被分解成对图像质量有不同“重要性”的分量。

量化的目的是为了去除变换后对图像的视觉质量不重要的数据分量并且保持视觉上重要的数据分量。一旦非重要的分量被去除,它们就不能重新恢复,因此量化是一个有损的过程。

量化过程的“粗糙度”可以改变(利用量化的“比例因子”或“步长”)。“粗糙”的量化往往忽略大部分的系数只留下最重要的,而“精细”的量化往往留下量化块中大部分的系数。粗糙量化通常以牺牲图像质量为代价得到更高的压缩率。量化的比例因子或步长通常是在图像或视频编解码器(CODEC)中控制图像质量和压缩率的主要参数。

########################################################33

熵编码

一个典型的图像块在块编码和量化后常包含少量重要的非零系数和大量的零系数。那些剩余的非零系数可以用统计压缩的方法进行有效的压缩(“熵编码”)。

1.量化系数的重新排列。一个典型图像块的非零量化趋向于聚集在“左上角”,也就是说在低频区的附近。通过重新排序64个系数,例如Z字形扫描排序(Zigzag Scanning Order),这些非零的数据可以被依次组合在一起。扫描是采用从左上方(低频)到右下方(高频)的Z字形顺序,组合了重要的低频系数。

2.Run-level编码。重新排序的系数数组通常很稀疏,由一组非零系数和随后的零组成(也偶尔有一些较高频率的非零系数)。这种数组可以用一系列(run,level)对来紧凑地表示。(run,level)对的第一个数字表示连续零的个数,第一个数字表示一个非零的数值。

3.熵编码。统计编码的算法被用在这些(run,level)数据上。熵编码算法的目的是用短的编码表示经常出现的(run,level)对,而用长的编码表示不经常出现的(run,level)对。用这种方法,run-level数据可以被压缩成很少数目的比特。

3.1.哈夫曼编码。哈夫曼编码(Huffman Coding)用包含变比特数的码字来代替每个符号(例如,(run,level)对)。这些码字的分配基于符号的统计分布。每一个码字被安排为“唯一可解的”,以便解码器可以毫无错误的提取出一系列变长的码字。哈夫曼编码很适合实际情况并且很实用。

3.2.算术编码。算术编码(Arithmetic Coding)把一系列符号映射到分数,然后转换到二进制数并进行传输。算术编码具有比哈夫曼编码更高压缩率的潜力。每一个符号可以用分数数目的比特数来表示(而不是只用整数数目的比特数),这意味着每个符号分配的比特可以更精确,而且可以与编码数据的统计分布相吻合。

##########################################################

解码

熵编码器的输出是一个二进制编码的序列,用压缩形式表示原始图像。为了重建图像,必须解码这个序列,解码的过程几乎与编码的过程相反。

熵解码器从比特序列中提取出run-level符号。这些符号被转化为一系列的系数,并被重新排序成一个量化系数块。到这里,解码的操作和相对应的编码操作正好相反。每一个系数乘以一个整数的比例因子(rescaled),这通常被称为“反量化”,但实际上,由量化造成的精度损失并不能被恢复,因此重新比例化后的系数(rescaled coefficients)和原来变换后的系数并不相等。

重新比例化后的系数经反变换重建一幅解码图像。由于量化过程中的数据的丢失,解码图像与原来并不完全相同:差别的大小在于量化的粗糙程度。

继续阅读