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

标签 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);

最佳答案

您的代码中有一个小错误。我假设您想计算遇到每个像素的概率,这是归一化直方图。你没有正确计算它。具体来说:

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/

相关文章:

matlab - 如何在 MATLAB 中将 3 列矩阵绘制为彩色图?

python - numpy 中的直方图反投影如何工作?

image - 有什么好的图像文本本地化算法吗?

c++ - 使用 openCV 查找图像轮廓

html - 列表图像之间的小方框

html - 是否可以仅使用 CSS 隐藏悬停图像并显示另一幅图像?

java - 如何将 int[] 转换为 OpenCV Mat? (反之亦然)

matlab - 在拟合高斯模型的示例中,钛是什么?

python - 相当于python中Matlab的gaminv

python - cv2 轮廓无法检测到某些形状