基于matlab的LZW图像压缩编码

LZW压缩
LZW压缩(LZW compression)是一种由Abraham Lempel、Jacob Ziv和Terry Welch发明的基于表查寻算法把文件压缩成小文件的无损压缩方法。LZW压缩使用的两个常用文件格式是用于网站的GIF图象格式和TIFF图象格式。LZW压缩是还适合压缩文本文件。
一个特殊的LZW压缩算法使用指定的长度的位的序列(例如,12位)并且在一个表(有时叫做“字典”或“译码本”)里为这个特殊的位模式产生一个条目创造一个词条,并把这个模式的本身和短代码结合起来。随着输入的读取,任何已经读取的模式将取代这些短的代码,有效的把输入压缩成一个更小的文件。
LZW通俗理解:http://blog.csdn.net/krossford/article/details/49157531
这个博主LZW的工作思路是错误的,下面的编码思路是正确的,比如abcabcabc编码后字节是6个,分别是a,b,c,ab,ca,bc,并不是博主上面说的3个字节。

主程序:

为什么要把int型转换成double型?
1 、有些函数支持double型,而不支持uint8的数据类型,所以要转换
2 、精度问题了,因为uint8进行数据处理的时候,容易造成数据溢出或精度不够。
为了节省存储空间,matlab为图像提供了特殊的数据类型uint8(8位无符号整数),以此方式存储的图像称作8位图像。
如果现在想imshow显示图像结果,就需要再转换成uint8格式。

clear;clc
I = rgb2gray(imread('DSC_0528.jpg'));
[m,n] = size(I);
x = double(I(:)'); % 转化格式类型
% LZW编码
[S,sz]=LZW(x);
% LZW解码
A =  [];
for i = 1:length(sz)
    A = [A S{sz(i)}];
end

A = [A zeros(1,m*n-length(A))];
II = uint8(reshape(A,m,n));
[M,N]=size(II);
b=length(S);
sum=M*N;
H=0;  %初始化信息熵
for i=0:255;
    [r,c]=find(II==i);  %统计每个灰度值的像素点总数
    num(i+1)=length(r);
    p(i+1)=num(i+1)/sum;  %统计每个灰度值的概率
    if p(i+1)~=0
        H=H-p(i+1)*log2(p(i+1));  %计算信息熵
    end
end

%计算平均码字长度
pjmc=b/sum
%计算编码效率
bmxl=H/pjmc
%计算压缩比
ysb=sum*8/b
disp('信息熵');disp(H);disp('平均码字长度');disp(pjmc);
disp('编码效率');disp(bmxl);disp('压缩比');disp(ysb);
subplot(121);imshow(I);
subplot(122);imshow(II);

定义LZW编码函数:

1、unique()函数:去掉矩阵中重复的元素
2、细胞数组:细胞结构可以把不同类型的数据纳入到一个变量中。普通数组中的每个元素都必须具有相同的数据类型,而细胞则没有此要求。

function [S,sz]=LZW(x)
% LZW词典编码
% x为输入序列  S为词典  sz为输出
n = length(x); % 序列长度
S = unique(x); % 初始化词典
x = num2cell(x); % 转化为细胞数组
S = num2cell(S); % 转化为细胞数组
sz = []; % 初始化输出序列
temp = []; % 当前序列
% 开始编码
for i = 1:n
    temp = [temp x{i}]; % 取一个元素放入序列中
    for j = 1:length(S)
        if isequal(S{j},temp) %判断S{j},temp两个数组是否相等
            flag = 1;
            break;
        else
            flag = 0;
        end
    end
    if flag == 1 % 如果当前序列在词典中
        continue;
    else % 如果当前序列不在词典中
        S = [S temp]; % 将当前序列加入词典
        for j = 1:length(S)
            if isequal(S{j},temp(1:end-1))
                T = j;
                break;
            end
        end
        sz = [sz T];
        temp = temp(end); % 重置temp
    end
end
for j = 1:length(S)
    if isequal(S{j},temp)
        T = j;
        break;
    end
end
sz = [sz T]; % 最后一位加入输出

你可能感兴趣的:(基于matlab的LZW图像压缩编码)