视频编码之算术编码

        视频的压缩编码的最后一步是熵编码,而熵编码的方法有很多。其中有一类编码叫做算术编码,算术编码的思路实在是精美绝伦,因此写此文记录一下。

一、算术编码的本质思想

        与很多其他编码思想一样,如哈夫曼编码,算术编码的本质思想也是对于高频的字符进行短编码,即是高频的字符占用的字节少。

        比如字符串AAABBCAAACAABAAACB,其中A出现的频率最高,那么希望编码的时候表达A的字符占用的字节最少。这也是类似哈夫曼编码的核心做法。对于算术编码来说,本质思想也是如此,但是算法编码使用的编码方法和过程,却是非常的独特。

二、算法编码的编码过程

        假如我们要压缩这样一段字符:AABABCABAB

        如果不进行压缩,则这个字符串所占空间大小为20个bit;其中A字符出现频率是50%,B字符出现频率是40%,C字符出现频率是10%;那么算术编码会对0-1的区间对A,B,C进行一个范围划分:

A:[0,0.5]
B:[0.5,0.9]
C:[0.9,1.0]

        接下来我们需要对字符串的每一个字符依次根据它所在的区间再对A,B,C进行一个范围划分。过程如下:

        (1)、字符串的第一个字符是A,则我们需要对A的区间[0,0.5]来进行一个区间划分:

A:[0,0.25]
B:[0.25,0.45]
C:[0.45,0.5]

        (2)、字符串的第二个字符还是A,则我们需要对新的A区间[0,0.25]来进行一个区间划分:

A:[0,0.125]
B:[0.125,0.225]
C:[0.225,0.25]

        (3)、第三个字符是B,那我们这次就需要对新的B区间[0.125,0.225]来进行一个区间划分:

A:[0.125,0.175]
B:[0.175,0.215]
C:[0.215,0.225]

        (4)、重复上述的步骤,一直到最后一个字符,如下:

扫描二维码关注公众号,回复: 14348282 查看本文章
当前字符 当前目标区间
A [0, 0.5]
A [0,0.25]
B [0.125,0.225]
A [0.125,0.175]
B [0.15,0.17]
C [0.168,0.17]
A [0.168,0.169]
B [0.1685,0.1689]
A [0.1685,0.1687]
B [0.1686,0.16868]

        (5)、完成上述操作后,最终区间为[0.1686,0.16868],我们在这个区间内任意选一个小数,就可以作为最终的编码小数。我们还需要对小数转成二进制,才是最终存储的格式。因为我们要尽可能地最短压缩,所以我们希望从这个区间里选择一个二进制表示出来最短的小数。这里我们选定为:0.16864013671875,二进制为:0.00101011001011,去掉整数位 0 以及小数点后,最终的二进制编码为 00101011001011,bit 长度为 14 bit,比不压缩的20bit,减少了6bit。

三、算术编码的解码过程

        解码过程与编码过程是相逆的。大致如下:

        (1)、获取到存储信息00101011001011,加上小数点还原后为.00101011001011,对应的十进制编码小数是 0.16864013671875。

        (2)、我们先从初始区间中定位第一个字符:

A:[0,0.5]
B:[0.5,0.9]
C:[0.9,1.0]

        因为小数0.16864013671875落在A的区间中,所以第一个字符可以确定为A

        (3)、接下来定位第二个字符:

        第二个区间是:

A:[0,0.25]
B:[0.25,0.45]
C:[0.45,0.5]

        小数0.16864013671875仍然是落在A的区间中,因此第二个字符也是A

        (4)、接下来第三个字符:

        第三个区间是:

A:[0,0.125]
B:[0.125,0.225]
C:[0.225,0.25]

        看到0.16864013671875是落在B的区间中,因此第三个字符是B

        (5)、以此类推,最终就可以根据小数0.16864013671875将整个字符串解析出来

这就是算术编码的解码过程。

四、算术编码的原理

        算法编码为什么能够压缩数据呢?

        算术编码的压缩本质,就是在保留字符排列顺序的同时,对于更高频出现的字符,也就是概率更大的字符,赋予更大的小数区间。

        算术编码的目的,是要在最终的目标区间内,找一个二进制最短的小数作为最终编码。

        那么怎么去找到这样一个目标区间呢?最终目标区间的范围更大,可容纳的小数精度就越低,意味者我们最终的二进制编码更短。比如在低精度的 [0.1, 0.2) 和 高精度的 [0.1111111111, 0.1111111112) 之间各找一个最短编码的二进制进行比较,肯定是 [0.1, 0.2) 中找到的的最短二进制编码更短。

        所以算术编码的实现途径就是:尽量使最终目标区间的范围更大。由于高频字符出现次数多,区间较大,而低频字符出现次数少,区间小。所以在遍历完所有字符之后,我们最终得到目标区间就更大,也就是小数精度更低。

五、总结:

        通过上述讲解,我们就大体了解了什么是算术编码,以及算术编解码的过程。

        而算法编码的原理可以总结为:

        1、为了使最终二进制编码更短,就需要使得最终目标区间的范围更大。

        2、为了使最终目标区间的范围更大,就需要赋予高频字符更大的区间,低频字符更小的区间。

        算法编码的步骤过程,以及原理,我们都能去了解和掌握。但是令人想不到的是,这算法编码的这种方式,是如何想到的呢?这点不得不佩服算法编码的发明者。

猜你喜欢

转载自blog.csdn.net/weekend_y45/article/details/124995485