当前位置: 首页 > 工具软件 > 4coder > 使用案例 >

range-coder使用

孟华晖
2023-12-01

Range coder的原理

Range coder的原理部分可以参考熵编码算法Range encoding工程原理和实现
比特流原理参考Range Coder编码比特流
本篇文章谈一谈range-coder的使用问题
代码参考

根据range coder的原理,我们在编码前需要提前知道编码数据的累计概率分布

from range_coder import RangeEncoder, RangeDecoder
from range_coder import prob_to_cum_freq, cum_freq_to_prob
prob = [4, 6, 8]
prob = np.asarray(prob, dtype=np.float64) / np.sum(prob)
cumFreq = prob_to_cum_freq(prob, 128)
cumFreq[-1] = 2**32
sequence = [2, 2]

这里自定了一个pmf作为频率统计,后做了一个归一化,然后使用prob_to_cum_freq将概率做了一个累计概率密度处理,注意这里处理后输出的结果为

print(cumFreq)
[0, 29, 72, 4294967296]

cumFreq 中只有4位数其代表的是只有三个概率区间,因此只能编0,1,2三个数。

如果需要改变累计概率密度函数,则重新输入累计概率密度函数,这样在编码区间划分时会按照这个区间进行划分。

filepath = mkstemp()[1]

# encoding one sequence should require 1 byte
cumFreq0 = [0, 4, 6, 8]
cumFreq1 = [0, 2, 5, 7, 10, 14]
data0 = [random.randint(0, len(cumFreq0) - 2) for _ in range(10)]
data1 = [random.randint(0, len(cumFreq1) - 2) for _ in range(17)]

encoder = RangeEncoder(filepath)
encoder.encode(data0, cumFreq0)
encoder.encode(data1, cumFreq1)
encoder.close()

完整的编解码示意

random.seed(0)

filepath = mkstemp()[1]

for _ in range(20):
	numSymbols = np.random.randint(1, 6)
	cumFreq = [0] + np.cumsum(np.random.randint(1, 10, size=numSymbols)).tolist()
	data = np.random.randint(numSymbols, size=np.random.randint(20)).tolist()

	encoder = RangeEncoder(filepath)
	encoder.encode(data, cumFreq)
	encoder.close()

	decoder = RangeDecoder(filepath)
	dataRec = decoder.decode(len(data), cumFreq)
	decoder.close()

	assert data == dataRec

os.remove(filepath)
 类似资料: