Huffman对字符串进行无损压缩示例

今天遇到一个问题,简要来说就是输入一串字符串,对其进行无损压缩,尽量做到压缩原始数据量。最先考虑到的方法是Huffman编码,将其实现过程简要描述。

第一步,输入一串字符串。

clear all;
clc;
%% 输入待处理字符串
text = 'aaaabbbbbbbbbccbbbcccaaaaaaaaaaaaaaaaaabccaab';
fprintf('原文为:\n');
disp(text);

第二步,计算字符串出现的字符个数与每个字符出现的概率。

text_unique = unique(text);
N = length(text_unique);
p = zeros(1,N);
for i = 1:length(text)
    for j = 1:N
        if(strcmp(text(i), text_unique(j)) == 1)
            p(j) = p(j)+1;
            break;
        end
    end
end
p = p/length(text);

第三步,根据概率计算huffman码表。生成原理不具体介绍,请自行百度。

%% 3.huffman码表确定
[code_list, L_av] = Huffman(p);
for i = 1:length(code_list)
    Huff_tab{i,1} = strtrim(code_list(i,:));
    Huff_tab{i,2} = text_unique(i);
end
fprintf('huffman 码表:\n');
disp(Huff_tab);

主函数Huffman的实现过程为:

function [h,l]=Huffman(p);
%HUFFMAN 	Huffman code generator
%[h,l]=huffman(p), Huffman code generator returns h the Huffman code matrix,
%                  and l the average codeword length for a source with probability vector p. 
%p=[0.4,0.2,0.2,0.1,0.1];
if length(find(p<0))~=0,
  error('Not a prob. vector, negative component(s)')
end
if abs(sum(p)-1)>10e-10,
  error('Not a prob. vector, components do not add up to 1')
end
n=length(p);
q=p;
m=zeros(n-1,n);
for i=1:n-1
  [q,l]=sort(q);
  m(i,:)=[l(1:n-i+1),zeros(1,i-1)];
  q=[q(1)+q(2),q(3:n),1];
end
for i=1:n-1
  c(i,:)=blanks(n*n);
end
c(n-1,n)='0';
c(n-1,2*n)='1';
for i=2:n-1
  c(n-i,1:n-1)=c(n-i+1,n*(find(m(n-i+1,:)==1))...
  -(n-2):n*(find(m(n-i+1,:)==1)));
  c(n-i,n)='0';
  c(n-i,n+1:2*n-1)=c(n-i,1:n-1);
  c(n-i,2*n)='1';
  for j=1:i-1
    c(n-i,(j+1)*n+1:(j+2)*n)=c(n-i+1,...
    n*(find(m(n-i+1,:)==j+1)-1)+1:n*find(m(n-i+1,:)==j+1));
  end
end
for i=1:n
  h(i,1:n)=c(1,n*(find(m(1,:)==i)-1)+1:find(m(1,:)==i)*n);
  l1(i)=length(find(abs(h(i,:))~=32));
end
l=sum(p.*l1);
end

 

第四步,对输入的字符串进行编码。

%% 4.将原文按码表进行编码
enc_stream = [];
for i = 1:length(text)
    for j = 1:length(Huff_tab)
        if strcmp(text(i),Huff_tab{j,2})
            enc_stream = [enc_stream Huff_tab{j,1}];
            break;
        end
    end
end
fprintf('编码结果为:\n');
disp(enc_stream);

第五步,对已编码的二进制序列进行解码。

%% 5. 解压
dec_stream = [];
I = [];
for i = 1:length(enc_stream)
    I = [I enc_stream(i)];
    for j = 1:length(Huff_tab)
        if strncmp(I, Huff_tab{j,1}, length(Huff_tab{j,1}))
            dec_stream = [dec_stream, Huff_tab{j, 2}];
            I = [];
            break;
        end
    end
end
fprintf('解码结果为:\n');
disp(dec_stream);

处理结果为:

原文为:
aaaabbbbbbbbbccbbbcccaaaaaaaaaaaaaaaaaabccaab
huffman 码表
    '1'     'a'
    '01'    'b'
    '00'    'c'

编码结果为:
111101010101010101010100000101010000001111111111111111110100001101
解码结果为:
aaaabbbbbbbbbccbbbcccaaaaaaaaaaaaaaaaaabccaab

 

当然,也可以随机生成字符串统计huffman编码的压缩效率~~

你可能感兴趣的:(图像处理)