算术编码实现



% 算术编码部分
symbol = ['songyim'];
pr = [0.15 0.14 0.13 0.1 0.18 0.16 0.14];
temp = [0.0 0.15 0.29 0.42 0.52 0.70 0.86 1.0];
orignal = temp;
in = input('input a string of songyiming: ', 's');
n = length(in);
for i = 1:n
    width = temp(8) - temp(1);
    w = temp(1);
    switch in(i)
        case 's'
            m = 1;
        case 'o'
            m = 2;
        case 'n'
            m = 3;
        case 'g'
            m = 4;
        case 'y'
            m = 5;
        case 'i'
            m = 6;
        case 'm'
            m = 7;
        otherwise
            error('do not input other character');
    end
    temp(1) = w + orignal(m) * width;
    temp(8) = w + orignal(m + 1) * width;
    left = temp(1);
    right = temp(8);
    fprintf('left=%.6f', left);
    fprintf('    ');
    fprintf('right=%.6f\n', right);
end
encode = (temp(1) + temp(8)) / 2;
decode = ['0'];
for i = 1:n
    fprintf('tmp=%.6f\n', encode);
    if(encode >= orignal(1) && encode < orignal(2))
        decode(i) = 's';
        t = 1;
    elseif(encode >= orignal(2) && encode < orignal(3))
        decode(i) = 'o';
        t = 2;
    elseif(encode >= orignal(3) && encode < orignal(4))
        decode(i) = 'n';
        t = 3;
    elseif(encode >= orignal(4) && encode < orignal(5))
        decode(i) = 'g';
        t = 4;
    elseif(encode >= orignal(5) && encode < orignal(6))
        decode(i) = 'y';
        t = 5;
    elseif(encode >= orignal(6) && encode < orignal(7))
        decode(i) = 'i';
        t = 6;
    elseif(encode >= orignal(7) && encode < orignal(8))
        decode(i) = 'm';
        t = 7;
    end
    encode = (encode - orignal(t));
    encode = encode / pr(t);
end
disp(['Decoded string: ', decode]);

% 图像压缩部分
[a] = imread('下载.png');
I = rgb2gray(a);
%I = ind2gray(a, b);
[x, y] = size(I);
I1 = zeros(x, y);
I2 = zeros(x, y);
k1 = 1;
k2 = 1;
I3 = zeros(x, 1);
all = 0;
for i = 1:x
    n = 1;
    for j = 1:y
        X = I(i, j);
        if j ~= y % 防止超出边界
            if X == I(i, j + 1)
                n = n + 1;
            else
                I1(i, k1) = I(i, j);
                I2(i, k1) = n;
                k1 = k1 + 1;
                n = 1;
                I3(i, 1) = I3(i, 1) + 1;
            end
        end
        if j == y
            I1(i, k1) = I(i, j);
            I2(i, k1) = n;
            k1 = k1 + 1;
            n = 1;
            I3(i, 1) = I3(i, 1) + 1;
        end
    end
    all = all + I3(i, 1);
    k1 = 1;
end
M = max(max(I2));
I4 = zeros(x, y);
m = 1;
for i = 1:x
    for k = 1:I3(i, 1)
        for j = 1:I2(i, k)
            I4(i, m) = I1(i, k);
            m = m + 1;
        end
    end
    m = 1;
end
I4 = uint8(I4);
subplot(1, 2, 1);
imshow(I);
title('原始图像');
subplot(1, 2, 2);
imshow(I4);
title('无损压缩后恢复出来的图像');

% 压缩比例计算
I = checkerboard(9, 9);
figure; imshow(I);
[m, n] = size(I);
J = [];
for i = 1:m
    value = I(i, 1);
    num = 1;
    for j = 2:n
        if I(i, j) == value
            num = num + 1;
        else
            J = [J num value];
            num = 1;
            value = I(i, j);
        end
    end
    J = [J num value 0 0];
end
disp('原图大小'); whos('I');
disp('压缩图像大小'); whos('J');
disp('压缩比例');
disp(m * n / length(J));

算术编码基本原理

将编码消息表示成实数0和1之间的一个间隔,消息越长,编码表示它的间隔就越小,

表示这一间隔所需的二进制位就越多。 算术编码用到两个基本的参数:符号的概率和它的编

码间隔。信源符号的概率决定压缩编码的效率,也决定编码过程中信源符号的间隔,而这些间隔包含在0到1之间。编码过程中的间隔决定了符号压缩后的输出。

实验代码如上所示。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值