案例学习
1. JPEG编码
2. MPEG编码
. 其他有损变换编码
1. 小波压缩
2. 分形压缩
3. 基于模型的压缩
1. 案例学习
在前面的课程中我们分别学习了好多种的有损和无损的压缩算法。现在我们把他们
结合在一起讨论一些实际应用中使用的压缩办法。
我们这里会讨论两个很流行的有损压缩编码:针对静态图像的JPEG和针对视频的MPEG.
1.1 JPEG
1.1 JPEG介绍
JPEG是一种针对彩色或者灰度图的压缩方法,它有很多的特性:
. 主要为自然的和实际的场景图片设计
JPEG对摄影图片以及自然的艺术图片有着很大的压缩率,而对卡通图片,线图
以及其他一些有着尖锐边缘的图片并不理想。
. 可调的有损压缩
JPEG在不同的阶段丢弃数据。实际上,是在一些人类视觉影响较小的地方数据被
丢弃。JPEG有着选项可以让你在压缩比和图像质量上进行平衡。
. 24色
JPEG维持着24色图像数据,而GIF则只维持8色图。实际应用中,这点意味GIF比
JPEG丢弃了更多的数据。
JPEG同时使用了很多不同的算法,因此是一个很好的压缩方面的学习案例,这些算法
包括:
. 变幻编码
. 标量量化
. 差分编码
. 运行时长编码
. Huffman编码或者算术编码
下面我们将在这些算法应用的时候强调这些算法。
1.1.2 JPEG压缩步骤
(可选) for each plane(scan) for each 8x8 block DCT Quant
RGB -> YIQ -------------------> -----------------> ----> ------>
|
|Zig-zag
Huffman或者算术编码 <-------DPCM---- |
01101... <-----------------------| |<-
<-------RLE-----
1. (可选)RGB转换成为YIQ
RGB是一种方便于硬件的3维颜色向量,而YIQ则是一种更加和人的视觉接近的
颜色空间。这里的I代表橙色和青色间的相对平衡,Q代表绿色和洋红之间的相对
平衡,而I和Q联合起来定义了像素的色调。这里的Y代表整个亮度,这个亮度是
根据人的视觉特征作了加权的:绿色的权值最大,红色则差不多折半,而蓝色则
影响最小。
当把图像转换成为YIQ表示的时候,我们必须为每个参数选择一个存储的bit数目
我们通常用表示IQ的bit数目的四倍的bit数目来表示Y,因为人的眼睛通常感觉
微小的亮度变化比感觉微小的色调变化要敏感一些。
顺便提及的是,NTSC的电视信号的传输编码就是使用的YIQ,而其大部分的带宽
都被用来传递亮度信号了。而且因为亮度信号使用独立的一个部分来表示,所以
黑白电视完全可以忽略其他两个部分而正确现实图像。
2. 将图片划分成为8x8的小块
小的固定大小的图片可以大大的简化后面的计算。
3. 对每个8x8的小块,使用离散的cosine变换产生一个8x8的拥有同样bit深度的块。
这步就是变换编码。
4. 通过一个缩放因子减小这个转换块的深度。
这步就是标量量化。量化中的损失就是JPEG压缩的最主要的损失部分。
我们可以简单的对快中的每项除以同一个系数,但是这样做经常得不到最好的效
果。当图片时给人看的时候,某些部分比另外一些部分更加的重要。这里,我们
可以从一个表中得到一个各个位置的变换系数。块中各个位置的元素都被除一个
表中对应的系数。这样做让我们可以选择丢弃那里的信息。
JPEG标准定义了两个这样的表,其中一个是针对(I,Q)的,而另外一个是针对Y的
后面一个表如下表所示。值得注意的是,最大的系数处于表的右小角,而最小的
系数则在左上角。这样做会丢弃高频部分的大部分bit,而相对对低频部分则丢弃
得较少一些。
16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 129 101
72 92 95 98 112 100 103 99
抽象的,这个表表示了图像中各个部分的重要性。如果我们把所有的系数都增大
一倍,我们仍然使用了相应的重要性衡量,但是我们可能丢弃了更多的bit数目。
因此这个表可以放大或者缩小来达到压缩率和图像质量间的平衡。
在大部分的JPEG压缩软件中,这个方缩因子是一个提供给用户的质量调节旋钮。
量化之后,DCT的系数将被压缩到很小的一个范围之内。这就减小了熵,并且使得
后续的压缩更为有效。事实上,很多高频部分相对低频部分来说基本上被减小到
0。
5. 对DC部分进行编码
这部分就是差分编码+Huffman或者算术编码。
DC部分包含了图像中的绝大部分信息。跨越整个图像,DC部分是很大的。但在一个
局部区域DC部分则经常和前面的值很接近。因此,我们不直接对DC进行编码,而是
对他们的差异进行编码。特别的,对每个8x8 DC块,我们对当前8x8块和前面的8x8
块的差别进行编码。
这里的差异应该很小,因此应该接近于熵。而这个差别流我们使用Huffman或者算
术编码进行进一步的处理。
6. 线性化AC部分
为了对8x8块的AC部分进行编码,我们首先需要把它表示成为一个1x64的向量。最
明显的办法是使用行主序或者列主序,但是一个更好的办法是使用Zig-zag序。
7. 对AC部分进行编码
1.2 MPEG
1.2.1 MPEG介绍
相关可以进一步提高压缩。我们一直反复使用的技巧是:一项技术越是能够探寻数据
之间的相关性,它就越能够有效的压缩数据。
这一点在MPEG中尤为突出。MPEG是用来对视频流进行压缩的。理论上,一个视频流是
一个静态图像的序列。但是实际应用中,相邻的图片往往是高度相关联的。MPEG正是
利用这些相关性从而达到了静态图片压缩所远不能及的高效压缩。
MPEG图像流中的每一帧是用下面三种方法中的一种进行编码:
I-帧:(内帧)使用静态图像编码技术。这样的帧不能够因为其他的帧而产生冗余
信息。
P-帧:(可预测编码帧)一个P-帧可以根据其前面的I-帧或者P-帧去处很多的冗余
信息。
B-帧:(双向可预测编码帧)一个B-帧可以根据其前面或者后面的I-帧或者P-帧去除
很多的冗余信息。
I-帧和P-帧在MPEG流中的出现很简单,都是按照时间顺序出现的。但是B-帧可能被向前
移动了,使得他可能出现在他的相邻的I-帧和P-帧的后面。这一点保证了一个帧支能够
出现在它所依赖的帧的后面。一个MPEG解码器可以通过缓冲最后出现的两个I-帧和P-帧
来达到解码的功能。
MPEG编码器可以把各种类型的帧人意的交错在一起。当场景相对比较静态的时候P帧和
B帧可以被使用,当主场景发生变化时,就可以使用I帧进行编码。实际应用中,编码
器常常采用一些固定的策略,比如I帧之间使用使用2到3个P帧,而它们之间有实用2到
3个B帧。比如下面所示:
I B B P B B P B B I
1.2.2 MPEG编码:I-帧
因为I帧是相对独立的,因此I帧可以被迅速和简单的编码而不用参考MPEG流中的其他
信息。因此I帧经常被用来作为随机定位,反向播放或者错误恢复等等的锚点。
I帧的编码使用了一个JPEG的变种。首先,每帧被转换成了YCrCb颜色空间(JPEG的
YIQ的一个变种)。然后帧被划分成了16x16的一些小块,被称为宏块。亮度数据Y
被完全表达(16x16被分成了4个8x8的小块进行表达),而Cr和Cb则使用1/4的分辨
率进行表达,也就是每个16x16的块仅仅使用8x8的子块来表达。
现在我们拥有了6个8x8的小块(Y 4个,Cr,Cb各一个)。使用前面的JPEG技术对这些
小块进行编码。每个小块都是用cosine变换,量化,zig-zag序列,运行时长编码,
最后是Huffman编码从而得到最后的bit流。
一个重要的不同在于MPEG的量化过程。在最开始的时候MPEG-1不支持JPEG变种的量化
表,而是表中的所有元素都采用一个常数值。MPEG-II则使用了变化的量化系数。
1.2.3 MPEG编码:P-帧
P帧使用上面同样的技术划分成了宏块。但是,我们并不直接对上面的宏块进行编码
我们尝试着对这个宏块和前面的相似的帧中的对应宏块的差异进行编码。
对当前帧中的每个宏块(目标),我们在前面的I-帧或者P-帧中(引用)找到一组
匹配的像素组。大部分情况下,我们可以在引用帧的相同位置找到一个很好的匹配。
如果场景使用的是静态北京,那么目标帧和引用帧中某些宏块很有可能一点都不变。
但是,我们希望能够适应运动。因此,我们在引用帧中更大的范围内来寻找一个目
标的好的匹配。最后,我们可以在偏移(x,y)出找到一个匹配最好的块。这个偏移
也就是运动向量则使用Huffman进行编码。
运动向量可以指引我们到最好的匹配位置,但是他并不能够指引我们到一个和目标
宏块完全一样的像素组去。因此我们还需要使用差分编码。我们生成一个代表目标
块和引用之间差别的宏块。这个差分宏块将使用在I-帧使用的JPEG技术进行编码:
DCT,量化,RLE等等。
实际上,在MPEG的编码中,寻找一个目标块的最好匹配往往是最难的一部分。在现在
的技术中,实时的MPEG编码只有借助用户的硬件帮忙才有可能。注意,虽然编码很难
但是如果给出一个运动向量,然后再缓存中去寻找对应的像素组则是很容易的,这就
是解码容易,编码难得道理。
最后一点:很有可能,给定一个宏块,我们在引用帧中找不到一个相似的区域。
如果这种情形出现,那么我们将放弃对这块进行差分编码。我们放弃差分向量而直
接使用JPEG对这块进行编码。某种意义上说,我们在这个宏块上有回到了原来的
I-帧的编码方式去了。
1.2.4 MPEG编码:B-帧
B-帧在MPEG之间的H.261中并没有出现。它被加入是由于下面的情形:一个P-帧的
一部分往往在前面的所有帧中都没有出现,但是可能出现在将来的帧中。比如:
考虑一个汽车从旁边进入场景。假设使用I-帧对汽车还没有出现的场景进行编码,
而另外一个I-帧对汽车完全进入场景进行编码。我们使用P-帧对中间场景进行编码。
但是,因为在第一个I-帧中,汽车的任何一部分都还没有出现,因此P-帧就不能够
重复利用这些信息。而汽车会在后面的I-帧出现这个事实并不能够帮助我们,因为
P-帧只能够看到过去的帧,而不能够看到将来的。
B-帧从两个方向来寻找可以使用的信息。而整个技术则和P-帧的技术完全一样。对
目标帧中的每个宏块,在引用帧中找相似的部分。但是,P-帧只在以往的I-帧或者
P-帧中寻找类似的块,而B-帧则可以在将来的I-帧或者P-帧中寻找。我们在过去的
和将来的帧中都寻找最好的匹配,然后过去的最好的匹配被编码成为向后预测运动
向量,而将来的最好的匹配泽被编码成为向前预测运动向量。
回忆前面的P-帧,他对目标和引用之间的差别进行编码。B-帧有两个运动向量,因
此有两个引用。我们简单的合并这两个引用,然后求平均,在和我们的目标块进行
差分编码。
和P-帧一样,B-帧可能在寻找匹配的时候不能够寻找到合适的匹配。这点发生时,
我们简单的丢弃对应的运动向量而仅仅考虑另外一个。如果两边都找不到,那么
就像I-帧一样,我们直接对目标块进行编码。
1.2.5 MPEG压缩效率
MPEG压缩效果如何呢?我们可以检查各种帧的典型的压缩率,然后进行加权求取
一个平均值。
使用356x260,24色的图像,MPEG-I的典型压缩率是:
类型 大小 压缩率
I 18Kb 7:1
P 6Kb 20:1
B 2.5Kb 50:1
----------------
Avg 4.8Kb 27:1
如果一个356x260的帧需要4.8Kb,那么MPEG需要多大的带宽才能够产生一个有意义
的每秒30帧的视频流呢?
30 x 4.8 x 8 = 1.2M bits/sec
这里,我们仅仅关注了MPEG的视频流,如果加上音频流数据(0.25Mbits/sec),
那么将需要约1.45Mbits/sec的带宽。
这个在1.5Mbit/sec的T1线路上很适合。事实上,这个特殊的限定正是MPEG的设计目
标。实际中MPEG编码器跟踪bit率,然后根据用户设定的限定实时的调整压缩质量。
这样的bit率控制在其他时候也很重要。比如在多媒体CD-ROM上的视频就要使用相对
较小的CD-ROM带宽。
1.2.6 实际应用中的MPEG
在实际中MPEG有很多的应用。
1. 直接卫星广播。MPEG的视频流被天线和解码器处理,然后调制成标准的NTSC的
电视信号。
2. 光缆电视信号。实验系统中使用光缆传送MPEG-II的电视信号。
3. 媒体仓库。
4. 实时编码。
2. 其他有损变换编码
2.1 小波编码
2.2 分形编码
2.3 基于模型的编码