在Matlab中使用dct后将向量转换为二进制字符串

时间:2014-05-08 16:58:30

标签: matlab math vector dct

我正在使用dct来变换频域中的矢量(矢量可以是来自更大矩阵的8x8窗口的行)我希望后面能够在类似于jpeg压缩的过程中量化该矢量,因为dct返回浮点数,这对我的任何进一步操作都没有帮助。任何有关如何做到这一点的帮助非常感谢

感谢。

1 个答案:

答案 0 :(得分:1)

如果您想知道JPEG / MPEG量化是如何工作的,在每个8 x 8块计算出其DCT之后,有一个量化矩阵应用于这些DCT编码块中的每一个。

量化如何工作是量化矩阵也是8×8。通过在原始DCT块和量化矩阵之间进行逐点划分来计算量化DCT块。之后,将值四舍五入为最接近的整数,以允许有效压缩。如果要将DCT系数(量化后)转换为二进制序列,则通过以Z字形顺序访问块内的系数,将系数重新排序为系数的1D流(阵列)。在这次重新排序之后,采用了霍夫曼编码或某种无损压缩算法。

JPEG标准中的常见量化矩阵如下。这是为了在量化后实现50%的图像质量(使用MATLAB语法):

 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];

一旦你有了这个量化矩阵,你可以在MATLAB中做这样的事情。我们假设in是一个8 x 8 DCT编码块。

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

现在,如果你想恢复量化块以最终恢复重建的DCT块,你只需要进行逐点乘法并截断所产生的任何小数。

假设in是一个8 x 8 量化的块。你可以在MATLAB中做这样的事情:

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

请记住,这是有损压缩,因为您无法通过量化获得原始DCT块。封装这个想法的完整MATLAB函数脚本可能如下所示:

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

您将使用2个参数运行此脚本:

  • 一个8 x 8 DCT块,无论是否量化
  • 一个标志:flag=f用于前进(原始到量化),flag=b用于向后(量化到重建)

输出是量化块或重建块,具体取决于您为flag指定的内容。

如果您想了解更多信息,请查看以下链接:

  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
  3. 链路#2具有不同的量化矩阵,使得重建图像的质量更高。您可以选择不同的量化矩阵以获得更高的质量,但显然图像尺寸会更大,因为在执行无损压缩时可能会有更少的利用。