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