指数哥伦布编码 java_Golomb及指数哥伦布编码原理介绍及实现

本文详细介绍了无损数据压缩方法Golomb编码,包括其基本原理、两个变种Golomb-Rice和Exp-Golomb编码,并提供了C++实现。Golomb编码适用于小数字出现频率较高的场景,通过分组编码减少码长。文章还阐述了编码的步骤,包括一元编码和二进制编码的应用,并提供了源代码下载链接。
摘要由CSDN通过智能技术生成

2017年的第一篇博文。

本文主要有以下三部分内容:

介绍了Golomb编码,及其两个变种:Golomb-Rice和Exp-Golomb的基本原理

C++实现了一个简单的BitStream库,能够方便在bit流和byte数字之间进行转换

C++实现了Golomb-Rice和Exp-Golomb的编码,并进行了测试。

在文章的最后提供了本文中的源代码下载。

Golomb编码的基本原理

Golomb编码是一种无损的数据压缩方法,由数学家Solomon W.Golomb在1960年代发明。Golomb编码只能对非负整数进行编码,符号表中的符号出现的概率符合几何分布(Geometric Distribution)时,使用Golomb编码可以取得最优效果,也就是说Golomb编码比较适合小的数字比大的数字出现概率比较高的编码。它使用较短的码长编码较小的数字,较长的码长编码较大的数字。

Golomb编码是一种分组编码,需要一个正整数参数m,然后以m为单位对待编码的数字进行分组,如下图:

27d3137f48084b95248ddeca4daeac94.png

对于任一待编码的非负正整数N,Golomb编码将其分为两个部分:所在组的编号GroupID以及分组后余下的部分,GroupID实际是待编码数字N和参数m的商,余下的部分则是其商的余数,具体计算如下:

\[ \begin{array}{c}

q = N / m \\ \\

r = N \% m

\end{array}

\]

对于得到的组号q使用一元编码(Unary code),余下部分r则使用固定长度的二进制编码(binary encoding)。

一元编码(Unary coding)是一种简单的只能对非负整数进行编码的方法,对于任意非负整数num,它的一元编码就是num个1后面紧跟着一个0。例如:

num

Unary coding

0

0

1

10

2

110

3

1110

4

11110

5

111110

其编解码的伪代码如下:

UnaryEncode(n) {

while (n > 0) {

WriteBit(1);

n--;

}

WriteBit(0);

}

UnaryDecode() {

n = 0;

while (ReadBit(1) == 1) {

n++;

}

return n;

}

使用一元编码编码组号也就是商q后,对于余下的部分r则有根据编码数字大小的不同有不同的处理方法。

如果参数m是2的次幂(这也是下面将要介绍的Golomb-Rice编码),则使用取r的二进制表示的低\(\log_2(m)\)位,作为r的码字

如果参数m不是2的次幂,如果m不是2的次幂,设\(b = \lceil{\log_2(m)}\rceil\)

如果\(r < 2^b - m\),则使用b-1位的二进制编码r。

如果\(r \geqq 2^b -m\),则使用b位二进制对\(r+2^b-m\)进行编码

总结,设待编码的非负整数为N,Golomb编码流程如下:

初始化正整数参数m

取得组号q以及余下部分r,计算公式为:\(q = N / m,r = N \% m\)

使用一元编码的方式编码q

使用二进制的方式编码r,r所使用位数的如下:

如果参数m是2的次幂(这也是下面将要介绍的Golomb-Rice编码),则使用取r的二进制表示的低\(\log_2(m)\)位,作为r的码字。

如果参数m不是2的次幂,如果m不是2的次幂,设\(b = \lceil{\log_2(m)}\rceil\)

如果\(r < 2^b - m\),则使用b-1位的二进制编码r。

如果\(r \geqq 2^b -m\),则使用b位二进制对\(r+2^b-m\)进行编码

说明:

\(\lceil a \rceil\) 大于a的最小整数 ceil运算

\(\lfloor a \rfloor\) 小于a的最大整数 floor运算

Golomb-Rice 编码

Golomb-Rice是Golomb编码的一个变种,它给Golomb编码的参数m添加了个限制条件:m必须是2的次幂。这样有两个好处:

不需要做模运算即可得到余数r,r = N & (m - 1)

对余数r编码更为简单,只需要取r二进制的低\(\log_2(m)\)位即可。

则Golomb-Rice的编码过程更为简洁:

初始化参数m,m必须为2的次幂

计算q和r,q = N / m ; r = N & (m - 1)

使用一元编码编码q

取r的二进制位的低\(\log_2(m)\)位作为r的码字。

解码过程如下:

bool b;

uint64_t unary = 0;

b = bitStream.getBit();

while (b)

{

unary++;

b = bitStream.getBit();

}

std::bitset<64> bits;<

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值