Pergunta

I am using dct to transform a vector in the frequency domain (the vector could be a row from an 8x8 window of a larger matrix) i would like afterwords to be able to quantize this vector in a process similar to jpeg compression because dct returns floats and that does not help me for any further operations. Any help on how this can be done is greatly appreciated

Thanks.

Foi útil?

Solução

If you want to know how JPEG/MPEG quantization works, after each 8 x 8 block has its DCT computed, there is a single quantization matrix applied to each of these DCT coded blocks.

How the quantization works is that the quantization matrix is also 8 x 8. A quantized DCT block is calculated by doing a point by point division between the original DCT block and the quantization matrix. After, the values are rounded to the nearest integer to allow for efficient compression. If you want to convert the DCT coefficients (after quantization) into a binary sequence, the coefficients are reordered into a 1D stream (array) of coefficients by accessing the coefficients within the block in zig-zag order. After this reordering, Huffman encoding or some kind of lossless compression algorithm is employed.

A common quantization matrix in the JPEG standard is the following. This is to achieve a 50% image quality after quantization (using MATLAB syntax):

 quant_matr = [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];

Once you have this quantization matrix, you can do something like this in MATLAB. Let's assume that in is an 8 x 8 DCT encoded block.

in = double(in); % // Ensure double precision
out = round(in ./ quant_matr);

Now, if you want to recover the quantized block to ultimately recover the reconstructed DCT block, you would simply do a point by point multiplication and truncate any decimals that result.

Let's assume that in is an 8 x 8 quantized block. You can do something like this in MATLAB:

in = double(in); % // Ensure double precision
out = floor(in .* quant_matr);

Bear in mind that this is lossy compression as you will not be able to get the original DCT block back because of the quantization. A full MATLAB function script that encapsulates this idea could look something like this:

function [out] = JPEGQuantize(in, flag)
[M,N] = size(in);
if(M ~= 8 && N ~= 8) 
    error('Image must be an 8 x 8 patch');
end

if(nargin == 1)
    flag = 0;
elseif(nargin == 2)
    if(strcmpi(flag,'f'))
        flag = 0;
    elseif(strcmpi(flag,'b'));
        flag = 1;
    else
        error('Please specify the right parameter for quantization: (f)wd or (b)wd');
    end
else
    error('Please specify the right amount of parameters');
end

% // Ensure double precision
in = double(in);

quant_matr = [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];

if(flag == 0) % Quantize
    out = round(in ./ quant_matr);
else
    out = floor(in .* quant_matr); % Truncate any decimals
end

You would run this script with 2 parameters:

  • An 8 x 8 DCT block, whether it was quantized or not
  • A flag: flag=f is for going forwards (Original to quantized) and flag=b is for going backwards (Quantized to reconstructed)

The output is either the quantized block or the reconstructed block, depending on what you specified for flag.

If you want more information, check out the following links:

  1. http://en.wikipedia.org/wiki/Quantization_matrix#Quantization_matrices
  2. http://cs.stanford.edu/people/eroberts/courses/soco/projects/data-compression/lossy/jpeg/coeff.htm

Link #2 has a different quantization matrix so that the quality of the reconstructed image is higher. You choose different quantization matrices for higher quality, but obviously the image size will be greater as there is less to exploit when performing lossless compression.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top