我正在尝试在 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);
最佳答案
您的代码中有一个小错误。我假设您想计算遇到每个像素的概率,这是归一化直方图。你没有正确计算它。具体来说:
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);
这将正确计算图像的概率分布。请记住,在进行霍夫曼编码时,您需要指定遇到像素的概率。假设每个像素都同样有可能被选中,这是通过计算图像的直方图,然后根据图像中的像素总数进行归一化来捕获的。尝试一下,看看是否能获得更好的结果。
但是,只有您有频繁出现的符号,霍夫曼才会给您良好的压缩率。您是否碰巧查看了图像中的直方图或像素分布?
如果传播非常大,每个 bin 的条目很少,那么 Huffman 不会给你任何压缩节省。事实上,它可能会给你一个更大的尺寸。请记住,TIFF
压缩标准仅将霍夫曼用作算法的一部分。还进行了一些预处理和后处理以进一步缩小尺寸。
再举一个例子,假设我有一张包含 [0, 1, 2, ... 255; 0, 1, 2, ..., 255; 0, 1, 2, ..., 255];
我有 3 行 [0,255]
,但实际上它可以是任意数量的行。这意味着遇到每个符号的概率是等概率的,或 1/255
,这意味着对于每个符号,我们需要每个符号 8 位……无论如何,这基本上是原始像素值!
霍夫曼背后的关键是一组位一起生成一个符号。频繁出现的符号被分配一个较小的位序列。因为我谈到的这个特定图像具有等概率的强度,所以你只会为每个强度生成一个符号而不是一组。这样一来,您不仅可以传输字典,还可以有效地一次发送一个字符,这并不比发送原始字节流好多少。
如果您希望您的图像通过原始霍夫曼压缩,像素的分布必须是倾斜的。例如,如果图像中的大部分强度是暗的或亮的。如果您的图像具有良好的对比度,或者像素强度在整个图像中的分布是平坦的,那么 Huffman 不会为您带来任何压缩节省。
关于image - 在 MATLAB 中使用霍夫曼编码进行灰度图像压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25966187/