range-coder使用

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)
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
将这段代码改写成python#include <iostream> #include "string.h" using namespace std; #define N 4 struct node { char c; double probablity; node* next; }; //输入节点的符号以及出现频率 node* Input() { node* p,*head; double pro = 0.0; //a head = new node; head->c = 'a'; head->probablity = 0.1; p = new node; //b head->next = p; p->c = 'b'; p->probablity = 0.4; p->next = new node; //c p = p->next; p->next = p; p->c = 'c'; p->probablity = 0.2; p->next = new node; //d p = p->next; p->next = p; p->c = 'd'; p->probablity = 0.3; p->next = NULL; /* head->c = 'a'; cin >> pro; head->probablity = pro; p = new node; head->next=p; for (int i = 1; i < N; i++) { p->c = 'a' + i; cin>>pro; p->probablity = pro ; //cout <<i<< p->c << '\t' << p->probablity<<endl; p->next = new node; p = p->next; } cout << endl; p->next = NULL; */ //打印链表 p = head; /*for (int i = 0; p != NULL; i++) { cout << p->c << '\t' << p->probablity << endl; p = p->next; }*/ return head; } //编码 double encoding(node* head) { node* p; p = new node; p = head; double low = 0.0, high = 1.0; double range; double range_high_low[2][N]; double prob = 0.0; //各字符范围 for (int i = 0; i < N; i++) { range_high_low[0][i] = prob; range_high_low[1][i] = p->probablity + prob; prob = range_high_low[1][i]; p = p->next; //cout << range_high_low[0][i] << '\t' << range_high_low[1][i] << endl; } //输入压缩信息a~d //注:double精度会缺失; char ch[] = {"cadacdb"}; //找到对应的概率值 for (int j = 0; j < 9; j++) { p = head; for (int i = 0; p!=NULL; i++) { if ((int(ch[j])-int(p->c))==0) { cout << p->c << '\t'; int n = ch[j] - 'a'; //编码 range = high - low; high = low + range * range_high_low[1][n]; low = low + range * range_high_low[0][n]; cout << low << '\t' << high << endl; } p = p->next; } } return low; } int main() { node* head,*p; head = Input(); p = head; double coder=encoding(p); cout << coder; return 0; }
06-03

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值