我正在使用 dct 转换频域中的向量(该向量可以是来自较大矩阵的 8x8 窗口的一行)我希望后记能够在类似于 jpeg 压缩的过程中量化该向量,因为 dct 返回浮点数这对我进行任何进一步的操作没有帮助。非常感谢有关如何完成此操作的任何帮助
谢谢。
如果您想知道 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 个参数运行此脚本:
flag=f
用于向前(原始到量化)和flag=b
向后(量化到重构)输出是量化块或重构块,具体取决于您为flag
.
如果您想了解更多信息,请查看以下链接:
链路#2具有不同的量化矩阵,因此重建图像的质量更高。您选择不同的量化矩阵以获得更高的质量,但显然图像大小会更大,因为在执行无损压缩时可利用的更少。