前几天,我们在课堂上学习数字媒体技术的时候,学习了音频压缩算法。针对音频我们有无损和有损
今天我们来研究一下无损压缩,一般来说,采取的无损压缩算法都是熵编码算法(即在编码过程中按熵原理不丢失任何信息的编码),主要的无损压缩编码有以下几种:
- 香农范诺(Shannon)编码
- 霍夫曼(Huffman)编码
- 算术编码(arithmeticcoding)
以上的三种算法中,前两种我先找机会说(老师在课上给我们讲过原理,没讲过代码实现,但是把第三种作为作业,,,尴尬),今天我们主要目光是聚焦在第三种上,即算术编码的原理及其代码实现
好,那么我们言归正传,来将这个算术编码一探究竟——
一、算术编码的历史
(以下的这一段落copy自csdn)
早在1948年,香农就提出将信源符号依其出现的概率降序排序,用符号序列累计概率的二进值作为对芯源的编码,并从理论上论证了它的优越性。1960年, Peter Elias发现无需排序,只要编、解码端使用相同的符号顺序即可,提出了算术编码的概念。Elias没有公布他的发现,因为他知道算术编码在数学上虽然成 立,但不可能在实际中实现。1976年,R. Pasco和J. Rissanen分别用定长的寄存器实现了有限精度的算术编码。1979年Rissanen和G. G. Langdon一起将算术编码系统化,并于1981年实现了二进制编码。1987年Witten等人发表了一个实用的算术编码程序,即CACM87(后用 于ITU-T的H.263视频压缩标准)。同期,IBM公司发表了著名的Q-编码器(后用于JPEG和JBIG图像压缩标准)。从此,算术编码迅速得到了广泛的注意。
二、算术编码的原理
A、编码
算术编码的基本原理是将编码的消息表示成实数0和1之间的一个间隔(Interval),消息越长,编码表示它的间隔就越小,表示这一间隔所需的二进制位就越多。
(一)步骤
这样说起来可能有点抽象,说的好理解一点实际上就是
- 首先的准备工作——按照各信源信号好出现的频率,将[0, 1)这个区间分成若干段,那么每个信号源就会有自己对应的区间了;
- 将[0, 1)这个区间设置为初始间隔;
- 然后编码过程就是,按照待处理的信号,一个一个信号源读入,每读入一个信号,就将该信号源在[0, 1)上的范围等比例的缩小到最新得到的间隔中。
- 然后依次迭代,不断重复进行步骤3,直到最后信号中的信源信号全部读完为止;
(二)伪代码
该过程编码的伪代码如下:
set lowLevel = 0
set highLevel = 1
input symbol
do
delta = highLevel - lowLevel
lowLevel = lowLevel + delta * symbol[i].lowLevel
highLevel = highLevl + delta * symbol[i].highLevel
while symbol traversed
output lowLevel