在MATLAB中使用霍夫曼编码进行灰度图像压缩

时间:2014-09-22 03:07:52

标签: image matlab image-processing compression huffman-code

我试图在MATLAB中使用霍夫曼编码压缩灰度图像,并尝试了以下代码。

我使用了tif格式的尺寸为512x512的灰度图像。我的问题是压缩图像的大小(压缩码字的长度)变得比未压缩图像的大小大。压缩率小于1。

clc;
clear all;
A1 = imread('fig1.tif');
[M N]=size(A1);
A = A1(:);
count = [0:1:255]; % Distinct data symbols appearing in sig
total=sum(count);
for i=1:1:size((count)');                  
    p(i)=count(i)/total;
end

[dict,avglen]=huffmandict(count,p) % build the Huffman dictionary
comp= huffmanenco(A,dict);         %encode your original image with the dictionary you just built
compression_ratio= (512*512*8)/length(comp)   %computing the compression ratio

%% DECODING
Im = huffmandeco(comp,dict); % Decode the code
I11=uint8(Im);

decomp=reshape(I11,M,N);
imshow(decomp);

1 个答案:

答案 0 :(得分:4)

您的代码中存在轻微错误。我假设你想要计算遇到每个像素的概率,这是标准化的直方图。你没有正确计算它。具体做法是:

count = [0:1:255]; % Distinct data symbols appearing in sig
total=sum(count);
for i=1:1:size((count)');                  
    p(i)=count(i)/total;
end

total总结[0,255]这是不正确的。您应该计算图像的概率分布。您应该使用imhist代替。因此,您应该这样做:

count = 0:255;
p = imhist(A1) / numel(A1);

这将正确计算图像的概率分布。请记住,当您进行霍夫曼编码时,您需要指定遇到像素的概率。假设可以同样地选择每个像素,则通过计算图像的直方图来捕获,然后通过图像中的像素总数进行归一化。试试看,看看你是否有更好的结果。


但是,如果您经常出现符号,那么霍夫曼只能为您提供良好的压缩率 。你碰巧看了你的图像中的直方图或像素的扩散吗?

如果价差非常大,每箱的条目非常少,那么霍夫曼不会给你任何压缩节省。事实上,它可能会为您提供更大的尺寸。请记住,TIFF压缩标准仅使用Huffman作为算法的一部分。还进行了一些预处理和后处理以进一步减小尺寸。

作为另一个例子,假设我有一个由[0, 1, 2, ... 255; 0, 1, 2, ..., 255; 0, 1, 2, ..., 255];组成的图像我有3行[0,255],但实际上它可以是任意数量的行。这意味着遇到每个符号的概率是等概率的,或1/255,这意味着对于每个符号,我们每个符号需要8位...这实际上是原始像素值!

霍夫曼背后的关键是一组比特一起产生一个符号。经常出现的符号被分配较小的比特序列。因为我所谈到的这个特定图像具有等概率的强度,所以你每个强度只产生一个符号而不是一个组。有了这个,你不仅可以传输字典,而且实际上可以一次发送一个字符,这并不比发送原始字节流好。

如果您希望图像被原始霍夫曼压缩,则像素的分布必须倾斜。例如,如果图像中的大部分强度都很暗或很亮。如果您的图像具有良好的对比度,或者像素强度的扩散在整个图像中是平坦的,那么Huffman将不会给您任何压缩节省。