用MATLAB编写算术编码的原理及解决计算机电脑精度不够的问题

本文介绍了算术编码的主要思想,并通过分组以5个字符为一组进行编码和译码,实现了对长字符串序列的算术编码,解决了由于实际计算机的精度不可能无限长,运算中出现溢出的问题。

一、算术编码简介:

其是一种无损数据压缩方法,也是一种熵编码的方法,其不同的地方在于,其它的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码。而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0 ≤ n < 1.0)的小数n。

算术编码用到两个基本的参数:符号的概率和它的编码间隔。信源符号的概率决定压缩编码的效率,也决定编码过程中信源符号的间隔,而这些间隔包含在0到1之间。

二、算术编码的整体流程:

以下是代码实现,先用输入一段较短的英文序列:

clc;

clear;

fp=fopen('duanxulie.txt');%打开文件

首先,读取英文文本,读取字符种类和其对应的频率,也就是概率,之后进行处理,去除各种符号,将其放入一个字符串中

str1=textscan(fp,'%s');%读入字符

str1=str1';

str1=cell2mat(str1{:}');%将所有的单词放到一个字符串中

Newstr=regexprep(str1,'\W','');%去除各种符号,将其转化为空格

Newstr=lower(Newstr);

disp(Newstr);

b = unique(Newstr);

disp(b);

%统计每种字符的个数,放入数组a中

for i = 1 : length(b)

a(i) = length(strfind(Newstr, b(i)));

end

disp(a);

%排序,若数组b中的第一个元素为字符‘a’, 则数组a中的第一个元素为字符‘a’出现的次数

for i = 1 : length(a)-1

for j = i+1 : length(a)

if b(i) > b(j)

t1 = a(i); a(i) = a(j); a(j) = t1;

t2 = b(i); b(i) = b(j); b(j) = t2;

end

end

end

%统计每种字符出现的频率,放入数组fre中

for i = 1 : length(a)

fre(i) = a(i) / sum(a);

end

disp(fre);

%根据频率分配概率范围,范围高值放入H中,范围低值放入L中

Li(1) = 0; Hi(1) = fre(1);

for i = 2 : length(fre)

Li(i) = Hi(i-1);

Hi(i) = Li(i) + fre(i);

end

三、算术编码的主要思想:

(1)对一组信源符号按照符号的概率从大到小排序,将[0,1)设为当前分析区间。按信源符号的概率序列在当前分析区间划分比例间隔。

(2)检索“输入消息序列”,锁定当前消息符号(初次检索的话就是第一个消息符号);找到当前符号在当前分析区间的比例间隔,将此间隔作为新的当前分析区间;并把当前分析区间的起点(即左端点)指示的数“补加”到编码输出数里;当前消息符号指针后移。

(3)仍然按照信源符号的概率序列在当前分析区间划分比例间隔。然后重复第二步;直到“输入消息序列”检索完毕为止。

(4)最后的编码输出数就是编码好的数据。

%编码

L =

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来回答你的问题。首先,算术编码是一种无损数据压缩技术,它可以将原始数据压缩成更小的数据,同时保持数据的完整性。在处理二维灰度图像时,我们可以运用算术编码原理编写 Matlab 函数来实现无损数据压缩。 下面是一个简单的示例函数,它可以将一个二维灰度图像进行算术编码压缩,并返回压缩后的数据: ```matlab function compressed_data = arithmetic_encoding(img) % img: 二维灰度图像 % compressed_data: 压缩后的数据 % 将图像转换为一维向量 img_vec = img(:); % 统计每个像素值出现的概率 counts = histcounts(img_vec, 0:255, 'Normalization', 'probability'); % 计算每个像素值的累积概率 cum_probs = cumsum(counts); % 初始化编码参数 low = 0; high = 1; range = 1; % 逐个像素进行编码 for i = 1:length(img_vec) % 获取当前像素值 pixel_value = img_vec(i) + 1; % 计算当前像素值在编码表中的区间范围 pixel_range = [low + range * cum_probs(pixel_value - 1), low + range * cum_probs(pixel_value)]; % 更新编码参数 low = pixel_range(1); high = pixel_range(2); range = high - low; % 如果编码区间过小,则需要进行缩放 while true if high < 0.5 compressed_data = [compressed_data, 0]; high = 2 * high; low = 2 * low; range = 2 * range; elseif low >= 0.5 compressed_data = [compressed_data, 1]; high = 2 * (high - 0.5); low = 2 * (low - 0.5); range = 2 * range; else break; end end end % 输出压缩后的数据 compressed_data = [compressed_data, low]; end ``` 以上是一个简单的算术编码函数,它可以将一个二维灰度图像进行算术编码压缩。需要注意的是,为了保证数据的完整性,我们需要将压缩后的数据存储在一个比特流中,以便在解码时能够正确还原原始数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值