介绍
- 最近研究 CABAC 熵编码原理,因此在剖析 CABAC 熵编码原理之前,先复习下算术编码的原理。
- 算术编码是图像压缩的主要算法之一。 是一种无损数据压缩方法,也是一种熵编码的方法。和其它熵编码方法不同的地方在于,其他的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码,而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0 ≤ n<1.0)的小数n。
算术编码原理
算术编码是一种数据压缩技术,它将信息源中的符号序列映射到一个单一的实数上。这种编码方法利用了符号的概率分布,将符号序列转换为一个在0和1之间的实数,这个实数的值与符号序列的概率成比例。算术编码的基本思想是将整个概率空间视为一个区间,然后根据每个符号的概率来划分这个区间。
以下是算术编码的一般步骤:
初始化:初始化一个区间,通常是[0,1)。
符号概率:确定信息源中每个符号的概率。
区间划分:根据每个符号的概率,将当前区间划分为子区间。每个子区间的长度与对应符号的概率成比例。
符号编码:当需要编码一个符号时,将当前区间调整为对应符号的子区间,并更新区间的端点。
重复:重复步骤4,直到所有符号都被编码。
输出:最终,编码过程结束时,区间的端点将非常接近,输出这个区间的端点之间的实数。
解码:解码过程是编码过程的逆过程。从输出的实数开始,根据每个符号的概率逐步确定原始符号序列。
算术编码的优点包括:
- 高效率:由于利用了概率信息,算术编码通常能够实现比传统编码方法更高的压缩比。
- 无长度限制:编码结果是一个实数,理论上可以无限长,不受编码长度的限制。
算术编码也有一些缺点:
- 实现复杂性:相比于其他编码方法,算术编码的实现更为复杂。
- 精度问题:由于涉及到实数运算,可能会遇到精度问题,特别是在处理非常大的数据集时。
算术编码在文本压缩、图像压缩和多媒体数据压缩等领域有广泛的应用。
算术编码示例
传统编码
传统的编码是通过符号映射实现,通过将符号和码字一一对应,比如下表的每个符号的码字,如果想编码"world"编成码流,则为:100 010 011 001 000
算术编码
- 算术编码与传统的编码不同,算术编码不是将单个符号映射成一个码字,而是从整个序列考虑,将输入的符号依据它的概率映射到[0,1)内的一个小区间上,如此递归地进行区间映射,最后得到一个小区间,从该区间内选取一个代表性的小数作为实际的编码输出。
- 如下表,每个符号的概率(假设),如果想编码的符号只有 d、l、o、r、w 这五个,那么它们的总概率就是 1,因此想要编码出“world”的码字的算术编码的过程如下:
- 根据概率设定各符号在[0, 1)区间上的初始区间:
- “world”的第一个符号 w 映射的区间在[0.7, 1) 之间,区间大小为 0.3;
- 需要根据该符号的概率分割[0.7, 1) 上的区间,如下:
- “world”的第二个符号 o 映射的区间在[0.76, 0.82) 之间, 区间大小为 0.06;
- 需要根据符号的概率进一步分割[0.76, 0.82) 上的区间;
- “world”的第三个符号 r 映射的区间在[0.784, 0.802)之间,区间大小为 0.018;
- 需要根据符号的概率进一步分割[0.784, 0.802)上的区间;
- “world”的第四个符号 l 映射的区间在[0.7858, 0.7876)之间, 区间大小为0.0018;
- 需要根据符号的概率进一步分割[0.7858, 0.7876)上的区间;
- “world”的第五个符号 d 映射的区间在[0.7858 0.78598 )之间,区间大小为0.00018;
- 从区间[0.7858 0.78598 )中任意取一个代表性的小数,比如 0.78585 就是最终编码“world”的输出值,再将小数转化为对应的二进制,去掉整数和小数点,即为最终的输出算术编码;
- 解码就是相反过程。
- 根据概率设定各符号在[0, 1)区间上的初始区间:
二进制算术编码
- 二进制算术编码和算术编码一样,但输入的只有“0”、“1”两个符号,即输入的是二进制串;
- 设输入符号串为s,中的符号分为两种:MPS(Most Probability Symbol),LPS(Low Probality Symbol),分别代表出现概率大小的符号,需要根据实际情况进行调整。如果输入的二进制串中的“0”较多,“1”较少,那么MPS = “0”,LPS =“1”;
- LPS 出现的概率 p_lps,则 MPS 的概率就为 1-p_lps;
- 接着按照算术编码的步骤编码输入的符号串;