2017-06-08 50 views
3

我正在研究JPEG壓縮算法。我遵循一些簡單的版本指令在MatLab中實現它,我堅持量化過程。因此,在JPEG中,我使用8x8塊作爲一個單元來執行正向變換,然後基於量化矩陣(爲了簡單起見,在指令中用數字N除)來量化每個塊。如何在JPEG壓縮中進行量化?

我自己實現了DCT,它和內置的dct2一樣工作,所以我認爲在我的DCT代碼中沒有問題。

function transformed_matrix = dctTransform(block, inverse) 
m_size = size(block, 1); 
A = zeros(m_size); 

for i = 0:m_size - 1 
    for j = 0:m_size - 1 
     if i == 0 
      a = sqrt(1/m_size); 
     else 
      a = sqrt(2/m_size); 
     end    
     A(i + 1, j + 1) = a * cos(pi * (j + 0.5) * i/m_size); 
    end 
end 

if inverse == true 
    transformed_matrix = A' * block * A; 
else 
    transformed_matrix = A * block * A'; 
end 

end 

然後我開始我的量化執行,我做了一個簡單的版本看起來像下面(只爲灰度現在..):

function quantized_matrix = quantize(block, quality, inverse, mode) 
m_size = size(block, 1); 
N = 16; 
DEFAULT_QUANTIZATION_MATRIX = ... 
    [16 11 10 16 24 40 51 61 
    12 12 14 19 26 58 60 55 
    14 13 16 24 40 57 69 56 
    14 17 22 29 51 87 80 62 
    18 22 37 56 68 109 103 77 
    24 35 55 64 81 104 113 92 
    49 64 78 87 103 121 120 101 
    72 92 95 98 112 100 103 99] * quality; 

% check for input size and mode 
if strcmp(mode, 'default') && m_size == 8 
    if inverse == true 
     quantized_matrix = block .* DEFAULT_QUANTIZATION_MATRIX; 
    else 
     quantized_matrix = round(block ./ DEFAULT_QUANTIZATION_MATRIX); 
    end 
else 
    if inverse == true 
     quantized_matrix = block * N; 
    else 
     quantized_matrix = round(block/N); 
    end 
end 

end 

我的主要程序代碼是

I = im2double(imread('../images/lena.bmp')); 
block_size = 8; 
fun = @(block_struct) quantize(dctTransform(block_struct.data, false), 1, false, 'defualt') 
fun2 = @(block_struct) dctTransform(block_struct.data, false) 
fun3 = @(block_struct) dct2(block_struct.data) 
I2 = blockproc(I, [block_size block_size], fun2); 
I3 = blockproc(I, [block_size block_size], fun3); 
I4 = blockproc(I, [block_size block_size], fun); 
subplot(2,2,1), imshow(I, []), title('The Original Image'); 
subplot(2,2,2), imshow(I2, []), title('The DCT Image'); 
subplot(2,2,3), imshow(I3, []), title('The builtin DCT Image'); 
subplot(2,2,4), imshow(I4, []), title('The Quantized Image'); 

Result

我的DCT和內置的DCT實現沒有區別所以我認爲我的量化實現必定有問題。我檢查了DCT計算的結果,矩陣中的大部分數字都非常小,這就是爲什麼我最終有一個黑色圖像(全部舍入爲0)。我的實現有沒有對JPEG壓縮有任何誤解?

任何幫助表示讚賞。

回答

0

好的,我已經想通了。

問題不在於算法和我的DCT /量化實現。

問題是我使用im2double來轉換我的圖像。 從MATLAB正式文件,

I2 = im2double(I)轉換的強度圖像I爲雙精度, 如有必要重新縮放的數據。

所以後I = im2double(imread('../images/lena.bmp')); 事實上,我縮放圖像,因此像素值是非常小的(0和1之間)。

我只是如果你的質量值是> 1,你會得到很多零的圖像切換到

I = double(imread('../images/lena.bmp'));

+0

。 – user3344003

+0

@ user3344003 1意味着100%,這個值應該在(0,1)。 – Kulbear