信息论基础:算术编码

article/2025/9/16 2:20:56

1 引言

霍夫曼码是一种无损编码,而且是最优的符号码。但是,它有两个缺点:(1)每个符号至少需要一个比特;(2)当符号的概率分布变化时,使用不方便。

用一个例子来看看霍夫曼编码的第一个缺点(即每个符号至少需要1个比特)。

信源从符号集 A = { a 1 , a 2 , a 3 } A = \{a_1, a_2,a_3 \} A={a1,a2,a3}中选择独立同分布的符号,概率分布为𝑃(𝑎_1 )=0.95,𝑃(𝑎_2 )=0.02,𝑃(𝑎_3 )=0.03。它的熵为0.335比特/符号。才3个符号,所以这个霍夫曼码很简单,如下所示。

它的平均码长为1.05比特/符号,远大于熵(0.335比特/符号)。原因是符号 a 1 a_1 a1的信息量为
− log ⁡ 0.95 = 0.074 -\log{0.95}= 0.074 log0.95=0.074比特,远小于其码长(1比特)。给 a 1 a_1 a1分配长度为1的码是很浪费的。

为了减小平均码长,下面将两个符号(独立同分布的)合并为一个扩展符号,进行霍夫曼编码。扩展符号的概率分布如下图。

其霍夫曼码的构造过程如下图所示。

在这里插入图片描述

2个扩展符号的平均码长为1.222比特/扩展符号。相当于单个符号的平均码长为0.611比特,这比前面针对单个符号编码的平均码长短了许多,但是仍然很长,约为熵的2倍。

我们可以进一步扩展,当扩展为8个符号时,单个符号的平均码长与熵接近。但符号集大小为 3 8 = 6561 3^8=6561 38=6561。对于许多应用,如此规模的霍夫曼码是不现实的。

在这里插入图片描述
该例子表明,为符号序列(符号组)生成码字,比为单个符号生成码字,码率更优。但是,为了给长为 m m m的某符号序列指定霍夫曼码,需要为所有长为 m m m的符号序列构造编码树。即需要构建整个码本,其大小随 m m m指数增长!

而算术编码能做到:能为特定的符号序列(当前要压缩的数据)指定码字,同时又不需要为所有的符号序列(当前数据中不出现的)指定码字。当 m m m很大时,该属性很重要。

2 算术编码

对于信源输出的符号序列,算术编码是对整个符号序列进行编码。为了实现无损编码,不同的符号序列需要映射为不同的标签(tag)。我们可以用[0,1)区间的实数(二进制形式)作为标签。由于[0,1)区间有无穷多个实数,足够给每个序列分配一个唯一的标签。那么,如何将符号序列映射为[0,1)区间的实数?利用累积分布函数(CDF)。

一个随机试验(如抛硬币、扔色子)所有可能结果组成一个基本空间Ω。 随机变量𝑋是定义在基本空间Ω上的、取值为实数的函数。 即随机试验每个可能结果都有实轴上的点与之对应。 为了统一起见和方便起见,随机变量采用下面的映射: X ( a i ) = i , a i ∈ A X(a_i )=i, a_i \in A X(ai)=i,aiA。其中, A = { a 1 , a 2 , … , a n } A=\{a_1,a_2,…,a_n \} A={a1,a2,,an}为离散信源的符号集。

例如,随机抛硬币,可能的结果有正面朝上、反面朝上两种 。当正面朝上时, X X X取值1;当反面朝上时, X X X取值2。 又如,随机扔色子,所有可能结果是1点、2点、3点、4点、5点和6点, X X X分别取值1,2,3,4,5,6。 又如,随机从英文文本(已经过处理,只有小写字母和空格,无标点符号)中抽取字母,所有可能结果是abcd…z-,X分别取值1,2,…,27。

随机变量 X X X的概率函数为 P ( X = i ) = P ( a i ) P(X=i)=P(a_i) P(X=i)=P(ai)。累积密度函数 F X ( i ) = ∑ k = 1 i P ( X = k ) F_X (i)=∑_{k=1}^i P(X=k) FX(i)=k=1iP(X=k)

假设没有概率为0的符号,每个符号都对应一个唯一的 F X ( i ) F_X (i) FX(i)。可按照 F X ( i ) F_X (i) FX(i)对[0,1)区间切分。

如果只需对单个符号编码,那么在对应子区间随便取一个值作为标签(码字即二进制表示)。

2.1 生成标签

例如,某信源的符号集为 A = { a 1 , a 2 , a 3 } A=\{a_1,a_2,a_3 \} A={a1,a2,a3},概率为 P ( a 1 ) = 0.7 P(a_1 )=0.7 P(a1)=0.7, P ( a 2 ) = 0.1 P(a_2 )=0.1 P(a2)=0.1, P ( a 3 ) = 0.2 P(a_3 )=0.2 P(a3)=0.2

编码开始前,没有任何符号,我们只知道标签对应的是整个[0,1)区间。当收到第1个符号后,区间缩小到该符号对于的子区间。然后,按照累积分布函数对该子区间做同样的切分。当收到第2个符号后,区间缩小到子区间中的子区间。对于所有符号依次做以上区间切分,直到最后一个符号,就得到一个很小的子区间,该子区间内任何一个数字(后面讲,用哪个数字的压缩率高)都可以作为序列的标签(其二进制表示即编码结果)。

前面对确定符号序列的标签所在区间,做了直观解释。下面给出具体的计算公式。假设取区间的中点作为标签。先考虑单个符号。 符号 a i a_i ai的标签为 T X ( a i ) = ∑ k = 1 i − 1 P ( X = k ) + 0.5 P ( X = i ) = F X ( i − 1 ) + 0.5 P ( X = i ) T_X (a_i )=∑_{k=1}^{i−1} P(X=k) +0.5P(X=i) =F_X (i−1)+0.5P(X=i) TX(ai)=k=1i1P(X=k)+0.5P(X=i)=FX(i1)+0.5P(X=i)

下表为掷色子时单个符号的标签。
在这里插入图片描述

长为𝑚的符号序列 x i x_i xi的标签为 T X ( m ) ( x i ) = ∑ y < x i P ( y ) + 0.5 P ( x i ) T_X^{(m)} (x_i )=∑_{y<x_i} P(y)+0.5P(x_i) TX(m)(xi)=y<xiP(y)+0.5P(xi) 其中, y y y是排在 x i x_i xi之前的等长序列。

以色子为例,𝑚=2。序列的排序方法如下:11,12,13,14,15,16,21,22,23,…,64,65,66。例如,色子序列13的标签为 T X ( 2 ) ( 13 ) = P ( x = 11 ) + P ( x = 12 ) + 0.5 P ( x = 13 ) = 1 ∕ 36 + 1 ∕ 36 + 1 ∕ 72 = 5 ∕ 72 。 T_X^{(2)} (13)=P(x=11)+P(x=12)+0.5P(x=13)=1∕36+1∕36+1∕72=5∕72。 TX(2)(13)=P(x=11)+P(x=12)+0.5P(x=13)=1∕36+1∕36+1∕72=5∕72

如果序列很长,求和项包含的序列非常多(指数增长)。上述式子不适合计算。

对于序列 x = ( x 1 x 2 . . . x n ) x=(x_1 x_2 ... x_n) x=(x1x2...xn),可用递归的方法计算区间的上下限。
下限 l ( n ) = l ( n − 1 ) + ( u ( n − 1 ) − l ( n − 1 ) ) F X ( x n − 1 ) l^{(n)}=l^{(n-1)}+(u^{(n-1)}-l^{(n-1)})F_X(x_n-1) l(n)=l(n1)+(u(n1)l(n1))FX(xn1)
上限 u ( n ) = l ( n − 1 ) + ( u ( n − 1 ) − l ( n − 1 ) ) F X ( x n ) u^{(n)}=l^{(n-1)}+(u^{(n-1)}-l^{(n-1)})F_X(x_n) u(n)=l(n1)+(u(n1)l(n1))FX(xn)
标签为上下限的中点。

例如, A = { a 1 , a 2 , a 3 } A=\{a_1,a_2,a_3 \} A={a1,a2,a3},概率为 P ( a 1 ) = 0.8 P(a_1 )=0.8 P(a1)=0.8, P ( a 2 ) = 0.02 P(a_2 )=0.02 P(a2)=0.02, P ( a 3 ) = 0.18 P(a_3 )=0.18 P(a3)=0.18
对于序列𝟏𝟑𝟐𝟏,计算其标签。

F X ( 0 ) = 0 , F X ( 1 ) = 0.8 , F X ( 2 ) = 0.82 , F X ( 3 ) = 1 F_X (0)=0,F_X (1)=0.8, F_X (2)=0.82, F_X (3)=1 FX(0)=0,FX(1)=0.8,FX(2)=0.82,FX(3)=1
l ( 0 ) = 0 , u ( 0 ) = 1 l^{(0)}=0,u^{(0)}=1 l(0)=0,u(0)=1
l ( 1 ) = 0 + ( 1 − 0 ) 0 = 0 , u ( 1 ) = 0 + ( 1 − 0 ) 0.8 = 0.8 l^{(1)}=0+(1−0)0=0, u^{(1)}=0+(1−0)0.8=0.8 l(1)=0+(10)0=0,u(1)=0+(10)0.8=0.8
l ( 2 ) = 0 + ( 0.8 − 0 ) F X ( 2 ) = 0.656 l^{(2)}=0+(0.8−0)F_X (2)=0.656 l(2)=0+(0.80)FX(2)=0.656, u ( ( 2 ) ) = 0 + ( 0.8 − 0 ) F X ( 3 ) = 0.8 u^((2))=0+(0.8−0) F_X (3)=0.8 u((2))=0+(0.80)FX(3)=0.8
l ( 3 ) = 0.656 + ( 0.8 − 0.656 ) F X ( 1 ) = 0.7712 l^{(3)}=0.656+(0.8−0.656) F_X (1)=0.7712 l(3)=0.656+(0.80.656)FX(1)=0.7712,
u ( 3 ) = 0.656 + ( 0.8 − 0.656 ) F X ( 2 ) = 0.77408 u^{(3)}=0.656+(0.8−0.656) F_X (2)=0.77408 u(3)=0.656+(0.80.656)FX(2)=0.77408
l ( 4 ) = 0.7712 + ( 0.77408 − 0.7712 ) F X ( 0 ) = 0.7712 l^{(4)}=0.7712+(0.77408−0.7712) F_X (0)=0.7712 l(4)=0.7712+(0.774080.7712)FX(0)=0.7712,
u ( 4 ) = 0.7712 + ( 0.77408 − 0.7712 ) F X ( 1 ) = 0.773504 u^{(4)}=0.7712+(0.77408−0.7712) F_X (1)=0.773504 u(4)=0.7712+(0.774080.7712)FX(1)=0.773504
标签为 ( 0.7712 + 0.773504 ) / 2 = 0.772352 。 (0.7712+0.773504)/2=0.772352。 (0.7712+0.773504)/2=0.772352

2.2 解码

还是上面的例子。对于标签0.772352,解码原序列。按顺序一次确定一个符号。那么何时解码结束?已知序列长度或者使用特殊的结束符。

2.3 为什么可以压缩?

前面为了容易理解,用十进制小数表示标签;而具体实现时,用二进制表示。许多小数需要无限长二进制表示(如0.1,0.2),不能实现压缩。在⌈log 1/(𝑃(𝑥))⌉+1处截断,数字仍在同一区间内,所以仍唯一可译。

为什么数字仍在同一区间内?因为原始数字是区间的中点,区间的大小是𝑃(𝑥),截断误差2^(−(⌈log 1/(𝑃(𝑥))⌉+1) )≤0.5𝑃(𝑥)。假设信源为i.i.d.随机变量𝑋,𝑚个符号所构成序列的信息量log 1/(𝑃(𝑥))=𝑚𝐻(𝑋) ⌈log 1/(𝑃(𝑥))⌉+1≤𝑚𝐻(𝑋)+2。即𝑚个符号压缩为至多𝑚𝐻(𝑋)+2比特。

3 具体实现问题

3.1 比例调整

实际实现时,还有一个问题需要考虑。随着符号数增加,区间会越来越小,小数点后的数字越来越多。如何在计算机上存储极高精度的数字?用办法:比例调整编码时,按照一定规则对数字进行放大。解码时,用同样规则进行缩小即可。

3.2 自适应算术编码

算术编码可以是静态的或是自适应的。在静态算术编码中(前面介绍的),信源符号的概率是固定的。但是很多时候事先不知道精确的信源符号概率。需要自适应算术编码,根据编码时符号出现的频繁程度,动态修改符号概率。在编码期间,估算信源符号概率的过程叫建模(modeling)。

每来一个符号,符号概率进行更新,区间切分随着概率的变化而变化。编码和解码的概率更新方法保持一致,即可正确解码。

4. 对比算术编码与霍夫曼编码

假设用两种编码方法对长度𝑚的符号序列进行编码,假设使用扩展符号(𝑚个符号)进行霍夫曼编码。算术编码码率范围为: H ( X ) ≤ l A ≤ H ( X ) + 2 ∕ m H(X)≤l_A≤H(X)+2∕m H(X)lAH(X)+2∕m。霍夫曼编码码率范围为: H ( X ) ≤ l A ≤ H ( X ) + 1 ∕ m H(X)≤l_A≤H(X)+1∕m H(X)lAH(X)+1∕m。相比之下,霍夫曼编码的上限更低。但是,对于算术编码,序列长度𝑚可以取很大;而霍夫曼编码的𝑚不能很大。因此,算术编码可以实现更高的压缩比。但是,算术编码的不足是算法复杂、专利多。因此,实际中二者的应用都很多。


http://chatgpt.dhexx.cn/article/fkikpZqO.shtml

相关文章

多媒体数据处理实验1:算术编码

1. 算法描述 功能&#xff1a; 给定概率字典以及待编码字符串&#xff0c;求出该字符串算术编码的结果&#xff08;最短二进制串&#xff09;&#xff0c;并能根据算数编码结果进行解码&#xff0c;得到原字符串。 2.算法流程&#xff1a; 算术编码流程&#xff1a; (1) 首先…

数字图像算术编码python_算术编码简介

上一篇讲了LZW编码&#xff0c;本篇讨论另一种不同的编码算法&#xff0c;算数编码。和哈夫曼编码一样&#xff0c;算数编码是熵编码的一种&#xff0c;是基于数据中字符出现的概率&#xff0c;给不同字符以不同的编码。本文也会对这两种编码方式的相似和不同点进行比较。 编码…

算术编码

文章首发于我的个人博客 前言 这篇博客主要总结大二下课程《信息论》实验的内容。主要包含固定模式的算数编码以及自适应模式的算术编码。我将首先介绍这两种算术编码的基本思想和实现思路&#xff0c;然后给出具体的python代码并对代码中的一些关键点进行解释说明。 固定模…

算术编码原理及其python实现

目录 1. 原理部分&#xff1a;2. 香农界理论分析&#xff1a;3. 代码实现&#xff1a;4.实验结果 1. 原理部分&#xff1a; 原理部分参考什么是算术编码 一个从信源序列到不可压缩二元序列的一个可逆映射&#xff0c;假设序列 { X 1 … X n } \{X_{1} \ldots X_{n}\} {X1​…X…

基本算术编码

1.基本思想 算术编码&#xff0c;就是用一个数编码一串字符串。它的思想是这样的:对一个需要编码的字符串&#xff0c;给出一个初始区间[0, 1),这个区间被分成n份&#xff0c;n是这串字符串中不同字符的个数&#xff0c;每一份占区间长度的比例与相应字符出现次数占整个字符串…

算术编码的基本概念

二、算术编码的基本概念 算术编码属于熵编码的一种重要的类型&#xff0c;其作用同变长编码等熵编码方法类似&#xff0c;用于压缩输入数据中的统计冗余&#xff0c;并且使用算术编码的压缩同样是无损压缩。 在本系列第1篇中讨论了典型的变长编码方法——哈夫曼编码。包括哈夫…

Otsu大津算法公式推导及python实现

目录 前言 一、类间平方差是什么&#xff1f; 二、公式推导及实现 1.求类间平方差 2.opencv-python编程实现 2.1 引入图像并灰度化 2.2 查看灰度值的分布情况 2.3 求全局平均阈值 2.4 求最大类间方差 3.算法的验证 总结 前言 OTSU&#xff08;大津算法&#xff09;是…

OTSU算法原理

OTSU算法原理及实现&#xff1a; 最大类间方差是由日本学者大津(Nobuyuki Otsu)于1979年提出&#xff0c;是一种自适应的阈值确定方法。算法假设图像像素能够根据阈值&#xff0c;被分成背景[background]和目标[objects]两部分。然后&#xff0c;计算该最佳阈值来区分这两类像素…

大津阈值分割算法(OTSU处理图像)

1.算法原理简述 对于图像I(x,y)&#xff0c;前景(即目标)和背景的分割阈值记作T&#xff0c;属于前景的像素点数占整幅图像的比例记为ω0&#xff0c;其平均灰度μ0&#xff1b;背景像素点数占整幅图像的比例为ω1&#xff0c;其平均灰度为μ1。图像的总平均灰度记为μ&#xf…

[图像处理]14.分割算法比较 OTSU算法+自适应阈值算法+分水岭

参考文献&#xff1a; OTSU阈值分割孔洞填充海陆分离_SwordKii的博客-CSDN博客 drawContours函数_普通网友的博客-CSDN博客_drawcontours R329-opencv阈值分割算法——自适应阈值_Third Impact的博客-CSDN博客_opencv自适应阈值分割 分水岭算法的python实现及解析_进不去的…

OTSU算法 (大津算法)理解代码

OTSU算法&#xff1a;对图像进行二值化的算法 介绍 OTSU算法是一种自适应的阈值确定的方法&#xff0c;又称大津阈值分割法&#xff0c;是最小二乘法意义下的最优分割。 它是按图像的灰度特性&#xff0c;将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景…

Pr-快速上手-基本操作-教程

视频链接: Pr教程 视频设计到的知识点: 视频的剪辑bgm的管理添加字幕及弹幕的添加鬼畜视频的制作发布教程

Pr常用操作技巧

操作技巧持续更新中 1.premiere如何裁剪视频尺寸 视频尺寸怎么修改 1.将premiere左下角的视频素材直接向右拖动到编辑区中 2.鼠标左键单击视频,然后选择上方的【效果】 3.这时,页面左侧将弹出效果的菜单栏,依次选择效果→视频效果→变换→裁剪 4.鼠标左键按住【裁剪】不放,直接…

Premiere: 基本操作

1、首先进入编辑模式&#xff0c;使得视频能加效果 2、这时候能找到视频的效果添加&#xff0c;这里有视频的水平翻转&#xff0c;高斯模糊等&#xff0c;需要什么效果直接&#xff0c;把该效果抓到视频上就可以。

PR的入门基础教程

提示&#xff1a;这里只记述作者学习PR入门基础教程视频后的总结 文章目录 常用视频概念第1天学习总结第2天学习总结第3天学习总结 常用视频概念 第1天学习总结 第2天学习总结 第3天学习总结

Adobe Premiere Pro快速入门教程

简介&#xff1a; 适用于纯新手零基础&#xff0c;看完本教程即可完成常用视频编辑技巧。 采用Adobe Premiere Pro 2020版本 windows10操作系统 一、制作 照片音频字幕的视频 目标&#xff1a;把三张图片和一个音乐做成带字幕的视频。&#xff08;素材请自行准备&#xff0…

使用pr的8大技巧

许多小伙伴是通过pr这个软件进行素材剪辑的&#xff0c;当我们面对许多素材需要剪辑的时候&#xff0c;往往被这些素材弄得头昏脑涨&#xff0c;剪辑拼接的费时费力&#xff0c;最后出来的成品效果也不太好&#xff0c;下面就告诉大家一些pr使用的技巧&#xff0c;来提升我们的…

Premiere 零基础快速上手教程

关注并星标“高级农民工” 回复“视频”可获取视频剪辑软件和教程 在前几天的文章中&#xff0c;我分享了几款主流视频剪辑软件&#xff1a; 最主流的视频剪辑软件 简单来说就是&#xff0c;手机端用「剪映」这一款 app 就够&#xff0c;当你熟练到发现手机剪视频不方便&#x…

pr基础学习笔记

pr基础学习笔记&#xff08;正题&#xff09; 推荐几个小技巧 1.快速插入 2.快速移动小片段 2. 另&#xff1a;移动Ctrl是多轨移动移动CtrlAlt是单轨移动3.如何去除两个片段之间的空档&#xff1f; 4.两种选择工具的比较 附&#xff1a; pr快捷键 应用程序 选择工具…

pr基础入门

一、快速认识 PR 主界面并导入素材 修改 名称、位置&#xff0c;其他不用变&#xff0c;点击确定 进入界面如下&#xff1a; 认识、添加必要 窗口 导入素材方法 1.直接将文件拖入pr中 2.导入媒体以开始&#xff0c;部分右键创建 素材箱 进入素材箱&#xff0c;右键选择导入&a…