算术编码

算术编码不是简单的将每个信源符号映射成一个码字,而是对整个输入序列分配一个码字,所以平均意义上可以为每个信源符号分配长度小于1的码字。

算术编码操作简单,下面以一个实例讲解算术编码的原理:

设信源有a,b,c,d四种符号,概率分别为0.2,0.2,0.4,0.2,输入序列"abccd"。

符号 a b c d
概率 0.2 0.2 0.4 0.2
初始区间 [0,0.2) [0.2,0.4) [0.4,0.8) [0.8,1)
  1. 第一个被压缩的符号为“a”,其初始间隔为[0, 0.2);

  2. 第二个被压缩的符号为“b”,由于前面的符号“a”的取值区间被限制在[0, 0.2)范围内,所以“b”的取值范围应在前一符号间隔[0, 0.2)的[0.2, 0.4)子区间内, 所以“b”的实际编码区间在[0.04, 0.08)之间。

  3. 第三个被压缩的符号为“c”,其编码取值范围应在[0.04, 0.08)区间的[0.4, 0.8)的子区间内,所以“c”的实际编码区间在[0.056, 0.072)之间。

  4. 第四个被压缩的符号为“c”,其编码取值范围应在[0.056, 0.072)区间的[0.4, 0.8)的子区间内,所以“c”的实际编码区间在[0.0624, 0.0688)之间。

  5. 第五个被压缩的符号为“d”,其编码取值范围应在[0.0624, 0.0688)区间的[0.8, 1)的子区间内,所以“c”的实际编码区间在[0.06752, 0.0688)之间。

  6. 至此,数据序列“abccd”已被描述为一个实数区间[0.06752, 0.0688),或者说在此区间内的任一实数值都唯一对应该数据序列。这样,就可以用该区间内的任意实数表示整个符号序列,如0.0688就可以用来表示整个符号序列。

整个过程如下图所示:

解码过程如下:

译码判决 译码区间 译码符号
0.0688在[0,0.2)内 [0,0.2) a
0.0688在[0,0.2)的第4个1/10区间内 [0.04,0.08) b
0.0688在[0.04,0.08)的第7个1/10区间内 [0.056,0.072) c
0.0688在[0.056,0.072)的第7个1/10区间内 [0.0624,0.0688) c
0.0688在[0.0624,0.0688)的第10个1/10区间内 [0.06752,0.0688) d

上面的例子假定编码器和解码器都知道消息的长度,所以解码过程不会无限进行下去。

算术编码存在以下几个问题:

  • 实际的计算机精度不可能无限长,所以会出现溢出。这个问题可以通过比例缩放实现。

  • 编码产生的码字是[0,1)间的一个实数,解码端必须收到实数的所有位后才能进行解码。

  • 算术编码对错误敏感,如果有一位错误则整个消息都错误。

感兴趣的请关注微信公众号Video Coding

发布了92 篇原创文章 · 获赞 109 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Dillon2015/article/details/104102004
今日推荐