0

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

谢谢。

4

1 回答 1

1

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

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

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

链路#2具有不同的量化矩阵,因此重建图像的质量更高。您选择不同的量化矩阵以获得更高的质量,但显然图像大小会更大,因为在执行无损压缩时可利用的更少。

于 2014-05-09T17:46:37.650 回答