本节为opencv数字图像处理(15):图像压缩的第二小节,图像压缩中的编码方法:霍夫曼编码、Golomb编码、Rice编码、算术编码及其实现,主要包括:霍夫曼编码、Golomb编码、Rice编码、算术编码的原理与实现代码。
霍夫曼编码对每个信源符号产生可能最小数量的编码符号。第一步是通过对所考虑的符号的概率进行排序,并将具有最小概率的符号合并为一个符号代替下次信源化简过程的符号,从而创建一个简化信源系列,过程如下图所示,重复合并直到信源只有两个符号的简化信源为止:
第二步是对每个化简后的信源进行编码,从最小的信源开始,直到遍历原始信源。对两个符号信源的最小长度的二值码是0和1,这些符号被分配给最右边的两个符号(并不规定顺序,谁0谁1无所谓),整个过程如下图所示:
这样编码的平均长度为: L a v g = 0.4 ∗ 1 L_{avg}=0.4*1 Lavg=0.4∗1 + 03 ∗ 2 + 0.1 ∗ 3 + 0.1 ∗ 4 + 0.06 ∗ 5 + +03*2+0.1*3+0.1*4+0.06*5+ +03∗2+0.1∗3+0.1∗4+0.06∗5+ 0.04 ∗ 5 = 2.2 0.04*5=2.2 0.04∗5=2.2比特/像素。之后也可以通过从左到右的顺序对串中每个符号进行分析来解码,对于一个编码串010100111100进行从左到右扫描,对应上表中的编码,可以发现,第一个有效码字为01010,对应 a 3 a_3 a3,下一个是011对应 a 1 a_1 a1,最终完全解码的消息为 a 3 a 1 a 2 a 2 a 6 a_3a_1a_2a_2a_6 a3a1a2a2a6。
当对大量符号进行编码时,最佳霍夫曼编码的构造也比较复杂。对于有 J J J个信源符号的通常情况,需要 J J J个符号概率, J − 2 J-2 J−2次信源简化和 J − 2 J-2 J−2次编码赋值,当事先信源符号的概率可以估计时,使用预计算的霍夫曼编码可以达到接近最佳的编码,一些通用的图像压缩标准比如JPEG和MPEG,都规定了默认的霍夫曼编码表。同样适用霍夫曼编码的压缩标准还有CCITT、JBIG2、H.261、H.262、H.263、H.264等。
哥伦布编码时具有指数衰减概率分布输入的非负整数编码。给定一个非负整数和一个正整数除数m,表示为 G m ( n ) G_m(n) Gm(n)的n关于m的Golomb编码时商 下 取 整 n / m 下取整{n/m} 下取整n/m的一元编码和 n m o d m n mod m nmodm的二进制表示的一个合并, G m ( n ) G_m(n) Gm(n)构建如下:
例如 G 4 ( 9 ) G_4(9) G4(9), 下 取 整 9 / 4 = 2 下取整{9/4}=2 下取整9/4=2的一元编码110,令 k = 上 取 整 l o g 2 4 = 2 k=上取整{log_24}=2 k=上取整log24=2, c = 2 2 − 4 = 0 , r = 9 m o d 4 c=2^2-4=0,r=9 mod 4 c=22−4=0,r=9mod4, r ‘ = k − c = 2 r‘=k-c=2 r‘=k−c=2。所以最后的结果就是110和01的连接即 G 4 ( 9 ) = 11001 G_4(9)=11001 G4(9)=11001,可以看到这种编码计算上要比最佳霍夫曼简单很多。
当 m = 2 k , c = 0 m=2^k,c=0 m=2k,c=0时,产生的编码又称为Golomb-Rice编码或Rice码。当被表示的整数具有概率质量函数的集合分布时: P ( n ) = ( 1 − ρ ) ρ n , 0 < ρ < 1 P(n)=(1-\rho)\rho^n,0<\rho<1 P(n)=(1−ρ)ρn,0<ρ<1,可以证明Golobm码是最佳的,即当 m = l o g 2 ( 1 + ρ ) l o g 2 ( 1 / ρ ) m=\frac{log_2(1+\rho)}{log_2(1/\rho)} m=log2(1/ρ)log2(1+ρ)时, G m ( n ) G_m(n) Gm(n)为所有唯一可判度的编码提供了最短的平均码长。
算术编码也是一种熵编码但生成的是非块码,假设有一个来自四符号信源的五符号序列 a 3 a 1 a 2 a 3 a 4 a_3a_1a_2a_3a_4 a3a1a2a3a4,其中信源的概率分别为0.1、0.2、0.3和0.4,则按照信号的概率可以将 [ 0 , 1 ) [0,1) [0,1)区间划分为 [ 0 , 0.1 ) 、 [ 0.1 , 0.3 ) [0,0.1)、[0.1,0.3) [0,0.1)、[0.1,0.3)、 [ 0.3 , 0.6 ) 、 [ 0.6 , 1 ) [0.3,0.6)、[0.6,1) [0.3,0.6)、[0.6,1)四部分。然后读入信号,第一个符号 a 3 a_3 a3,占据区间 [ 0.3 , 0.6 ) [0.3,0.6) [0.3,0.6),这样编码间隔变为 [ 0.3 , 0.6 ) [0.3,0.6) [0.3,0.6);然后读入第二个符号 a 1 a_1 a1,占原始区间的前10%,则编码间隔进一步变化,变为 [ 0.3 , 0.33 ) [0.3,0.33) [0.3,0.33);然后读入 a 2 a_2 a2,占原始区间的10%—30%,则编码间隔进一步变化,变为 [ 0.303 , 0.309 ) [0.303,0.309) [0.303,0.309);然后读入 a 3 a_3 a3,占原始区间的30%—60%,编码间隔变为 [ 0.3048 , 0.3066 ) [0.3048,0.3066) [0.3048,0.3066);最后读入 a 4 a_4 a4,占原始区间的60%—100%,编码间隔变为 [ 0.30588 , 0.3066 ) [0.30588,0.3066) [0.30588,0.3066),然后从这个区间上任选一个数作为编码输出,比如取0.306。
解码的时候同样需要知道信源的概率0.1、0.2、0.3和0.4,编码输出为0.306,原始符号序列长度为5。开始解码:0.306在区间 [ 0.3 , 0.6 ) [0.3,0.6) [0.3,0.6),所以第一个符号为 a 3 a_3 a3;而0.306在 [ 0.3 , 0.6 ) [0.3,0.6) [0.3,0.6)的前10% [ 0.3 , 0.33 ) [0.3,0.33) [0.3,0.33),所以第二个符号为 a 1 a_1 a1;而0.306在 [ 0.3 , 0.33 ) [0.3,0.33) [0.3,0.33)的10%—30% [ 0.303 , 0.309 ) [0.303,0.309) [0.303,0.309)上,所以第三个编码为 a 2 a_2 a2;而0.306在区间 [ 0.303 , 0.309 ) [0.303,0.309) [0.303,0.309)的30%—60% [ 0.3048 , 0.3066 ) [0.3048,0.3066) [0.3048,0.3066),所以第四个符号为a_3;而0.306在区间 [ 0.3048 , 0.3066 ) [0.3048,0.3066) [0.3048,0.3066)的%60—100%,所以最后一个符号为 a 4 a_4 a4。
欢迎扫描二维码关注微信公众号 深度学习与数学 [每天获取免费的大数据、AI等相关的学习资源、经典和最新的深度学习相关的论文研读,算法和其他互联网技能的学习,概率论、线性代数等高等数学知识的回顾]