2014-09-22 90 views
3

我想在MATLAB中使用霍夫曼編碼來壓縮灰度圖像,並嘗試了下面的代碼。在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); 

回答

2

代碼中存在一個小錯誤。我假設你想計算遇到每個像素的概率,這是歸一化的直方圖。你沒有正確計算它。具體做法是:

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 = imhist(A1); 
p = count/numel(A1); 

這將正確地計算你的概率分佈的圖像。記住,當你做霍夫曼編碼時,你需要指定遇到像素的概率。假設每個像素可能同樣可能被選擇,這通過計算圖像的直方圖來捕獲,然後通過圖像中的像素總數進行歸一化。嘗試一下,看看你是否有更好的結果。


不過,霍夫曼只會給你很好的壓縮比如果你已經頻繁出現的符號。你碰巧看過你的圖像中的直方圖或像素點的擴散嗎?

如果傳播非常大,每個bin的條目很少,那麼Huffman不會給你任何壓縮節省。事實上,它可能會給你一個較大的大小。請記住,TIFF壓縮標準僅將Huffman作爲該算法的一部分。還有一些預處理和後處理來進一步降低尺寸。

作爲另一個例子,假設我有一個由[0, 1, 2, ... 255; 0, 1, 2, ..., 255; 0, 1, 2, ..., 255];組成的圖像,我有3行[0,255],但實際上它可以是任意數量的行。這意味着遇到每個符號的概率等於或等於1/255,這意味着對於每個符號,我們將需要每個符號8位......這基本上是原始像素值!

霍夫曼背後的關鍵是一組位一起產生一個符號。經常出現的符號被分配一個較小的位序列。因爲我提到的這個特定的圖像具有等概率的強度,那麼你只會產生一個符號而不是一個組。有了這個,你不僅可以傳輸字典,而且可以一次發送一個字符,這並不比發送原始字節流更好。

如果你想要你的圖像被原始霍夫曼壓縮,像素的分佈必須傾斜。例如,如果圖像中的大部分強度都很暗或很亮。如果你的圖像具有良好的對比度,或者像素強度的擴散在整個圖像中是平坦的,那麼Huffman不會給你任何壓縮節省。

+0

哇...差不多3年大聲笑。感謝你的接納。 – rayryeng 2017-08-18 05:38:49