H.264 中的指数哥伦布编码(Exponential-Golo

2019-03-14  本文已影响0人  smallest_one

目录

  1. 参考
  2. 概述
  3. H.264 中的指数哥伦布编码规则
  4. Golomb编码家族
  5. 为什么使用Golomb编码
  6. 总结

1. 参考

2. 概述

指数哥伦布编码(Exponential-Golomb coding, Exp-Golomb)是一种通用的压缩编码方法。Teuhola在1978年提出[4]。

3. H.264 中的指数哥伦布编码规则

下面展示了指数哥伦布(Exp-Golomb)编码的码字(codeword)前面的一部分,code_num为codeword的序号。

code_num ⇒ code_medium ⇒ codeword
 0 ⇒ 1 ⇒ 1
 1 ⇒ 10 ⇒ 010
 2 ⇒ 11 ⇒ 011
 3 ⇒ 100 ⇒ 00100
 4 ⇒ 101 ⇒ 00101
 5 ⇒ 110 ⇒ 00110
 6 ⇒ 111 ⇒ 00111
 7 ⇒ 1000 ⇒ 0001000
 8 ⇒ 1001 ⇒ 0001001

可以根据以下规则从code_num得到codeword:

  1. 把code_num+1写成2进制的形式。
  2. 假设2进制表示使用的比特数量为n,增加n-1个0在之前的比特前面。

可以看出codeword的结构是有规则的:

  1. codeword长度随着code_num的增加而增加。
  2. 每个codeword不需要查找表,可以逻辑地构造出来。

1个Exp-Golomb的codeword有以下的结构:
[Zero prefix] [1] [INFO]

  1. codeword由M个前缀0组成,M>=0。
  2. 前缀0之后有一个1。
  3. 1之后是INFO。

每个codeword可以通过以下函数推导出来:
M = floor(log2(code\_num + 1))

INFO = code\_num + 1 - 2^{M}

相反的,
code\_num = 2^{M} + INFO - 1

注意len(codeword) = 2M + 1

示例:
(a) code_num = 107

(b) codeword = 000000011100011

表(Mappings to code num)

Mapping type Description
ue 无符号数:code_num = k.
使用于宏块类型、参考帧index等。
te 截断方式:如果编码变量k<=1,则发送一个比特 b, b = !code_num,如果k>1则,使用ue的方式。
se 有符号数:使用于MVD, delta QP等。
编码变量k与num的对应关系如下:
code_num = 2|k| (k ≤ 0)
code_num = 2|k| − 1 (k > 0)
k = (−1)^{code\_num+1}ceil(code\_num / 2)
me 映射表:k与code_num的对应关系通过标准中特定的映射表确定.

示例
在Baseline Profile设置下,一个帧内编码的宏块各符号的编码情况如下[2]:

Symbol name Mapping Notes
mb_type ue(v) Macroblock type; unsigned mapping to Exp-Golomb code with variable number of bits.
ref_index_l0 te(v) Reference picture index, one per macroblock partition; truncated unsigned mapping to Exp-Golomb code.
mvd_l0 se(v) Motion vector difference, two per macroblock partition;
signed mapping to Exp-Golomb code.
coded_block_pattern me(v) Identifies 8 × 8 blocks containing non-zero coefficients;
mapping to Exp-Golomb code according to specific table(s) in H.264 standard.
mb_qp_delta se(v) Differentially coded quantizer parameter;
signed mapping to Exp-Golomb code
Residual. . . Residual data coded using CAVLC.

4. Golomb 编码家族

Golomb Coding由Solomon W. Golomb于1960年发明。

Golomb Code 家族包括:

4.1 Unary Code(Comma Code)

使用“n个1和1个0”(或者“n个0和1个1)来编码1个非负整数。

image.png

编码实现

UnaryEncode(n) {
    while (n > 0) {
        WriteBit(1);
        n--;
    }
    WriteBit(0);
}

解码实现

UnaryDecode() {
    n = 0;
    while (ReadBit(1) == 1) {
        n++;
    }
    return n;
}

4.2 Golomb Code

image.png

码字(codeword)

n = qm + r = \lfloor\frac{n}{m}\rfloor m + r

注:其中r=n%m。

对q使用unary code


image.png

对r使用固定长度编码,有两种情况要考虑

  1. 如果m=2^k,比如m=8,则r的码字为{000, 001, ......, 111}。
  2. 如果m!=2^k, 对更小的r分配\lfloor log_{2}m\rfloor个比特,对更大的r分配\lceil log_{2}m\rceil个比特,比如m=5,则r的码字为{00, 01, 10, 110, 111}
image.png

4.3 Golobm-Rice Code

m=2^k的一种特殊的Golobm code。

编码实现

GolombEncode(n, RBits) {//RBits表示r使用的比特个数,比如m=8时,r=3,
    q = n >> RBits;
    UnaryCode(q);
    WriteBits(n, RBits);//输出低RBits的表示
}

解码实现

GolombDecode(RBits) {
    q = UnaryDecode();
    n = (q << RBits) + ReadBits(RBits);
    return n;
}

4.4 指数哥伦布编码(Exponential Golomb Code, Exp-Golomb)

在Exp-Golomb中,组的大小是指数型增长的。


image.png image.png
ExpGolombDecode() {
    GroupID = UnaryDecode();
        if (GroupID == 0) {
        return 0;
    } else {
        Base = (1 << GroupID) - 1;
        Index = ReadBits(GroupID);//读取GroupID个比特
        return (Base + Index);
}

5. 为什么使用Golomb编码

5.1 几何分布

P(n) = p^{n}(1-p), n>=0。
在一系列独立的Yes/No实验(伯努利试验)中,假设每次一次实验失败的概率为p,则直到第n+1次才成功的概率可以用上式表示。

几何分布对图像/视频压缩非常有用

示例1: 游程编码(run-length coding)

几何分布是指数分布的离散类比


image.png

双边的几何分布是拉普拉斯(Laplacian)分布(也叫双指数分布,double exponential distribution)的离散类比


Laplacian distribution.png

Golomb编码的重要性

对于几何分布P(X=n) = p^{n}(1-p)

当p>1/2时,如何设计最优编码?

寻找自适应Golomb编码的目标:对于给定的数据寻找最佳的m使得p^{m}<=1/2

如何从过去的统计数据找到p

image.png image.png

6. 总结

指数哥伦布编码是一种通用的熵编码方式,编码规则比较简单,不需要知道编码数据的概率分布。

但是压缩效率是怎么而来的呢,还没有找到参考

上一篇 下一篇

猜你喜欢

热点阅读