【问题标题】:How to do quantization in JPEG compression?如何在 JPEG 压缩中进行量化?
【发布时间】:2017-11-09 16:45:23
【问题描述】:

我正在研究 JPEG 压缩算法。我按照一些简单的版本说明在 MatLab 中实现它,但我坚持量化过程。

所以在 JPEG 中,我使用 8x8 块作为一个单元来执行前向变换,然后根据量化矩阵对每个块进行量化(或为简单起见,在指令中除以数字 N)。

我自己实现了 DCT,它就像内置的 dct2 一样工作,所以我认为我的 DCT 代码没有问题。

function transformed_matrix = dctTransform(block, inverse)
m_size = size(block, 1);
A = zeros(m_size);

for i = 0:m_size - 1
    for j = 0:m_size - 1
        if i == 0
            a = sqrt(1 / m_size);
        else
            a = sqrt(2 / m_size);
        end            
        A(i + 1, j + 1) = a * cos(pi * (j + 0.5) * i / m_size);
    end
end

if inverse == true
    transformed_matrix = A' * block * A;
else
    transformed_matrix = A * block * A';
end

end

然后我开始我的量化实现,我做了一个简单的版本,如下所示(现在只是灰度..):

function quantized_matrix = quantize(block, quality, inverse, mode)
m_size = size(block, 1);
N = 16;
DEFAULT_QUANTIZATION_MATRIX = ...
    [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] * quality;

% check for input size and mode
if strcmp(mode, 'default') && m_size == 8
    if inverse == true
        quantized_matrix = block .* DEFAULT_QUANTIZATION_MATRIX;
    else
        quantized_matrix = round(block ./ DEFAULT_QUANTIZATION_MATRIX);
    end
else
    if inverse == true
        quantized_matrix = block * N;
    else
        quantized_matrix = round(block / N);
    end
end

end

我的主程序代码是

I = im2double(imread('../images/lena.bmp'));
block_size = 8;
fun = @(block_struct) quantize(dctTransform(block_struct.data, false), 1, false, 'defualt')
fun2 = @(block_struct) dctTransform(block_struct.data, false)
fun3 = @(block_struct) dct2(block_struct.data)
I2 = blockproc(I, [block_size block_size], fun2);
I3 = blockproc(I, [block_size block_size], fun3);
I4 = blockproc(I, [block_size block_size], fun);
subplot(2,2,1), imshow(I, []), title('The Original Image');
subplot(2,2,2), imshow(I2, []), title('The DCT Image');
subplot(2,2,3), imshow(I3, []), title('The builtin DCT Image');
subplot(2,2,4), imshow(I4, []), title('The Quantized Image');

我的 DCT 和内置 DCT 实现之间没有区别,所以我认为我的量化实现一定有问题。我检查了 DCT 计算的结果,矩阵中的大多数数字都非常小,这就是为什么我最终有一个黑色图像(四舍五入为 0)。我的实现对JPEG压缩有什么误解吗?

感谢任何帮助。

【问题讨论】:

    标签: matlab image-processing jpeg


    【解决方案1】:

    好的,我想通了。

    问题不在于算法和我的 DCT/量化实现。

    问题是我正在使用 im2double 来转换我的图像。 来自 MatLab 官方文档,

    I2 = im2double(I) 将强度图像 I 转换为双精度, 如有必要,重新调整数据。

    所以在I = im2double(imread('../images/lena.bmp'));之后 我实际上得到了一个缩放图像,因此像素值非常小(在 0 和 1 之间)。

    我刚换了

    I = double(imread('../images/lena.bmp'));

    【讨论】:

    • 如果您的质量值 > 1,您的图像中会出现很多零。
    • @user3344003 1 表示 100%,此值应在 (0, 1] 中。
    猜你喜欢
    • 2012-05-16
    • 2015-05-26
    • 2010-12-12
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多