如何在JPEG压缩中推广量化矩阵?

时间:2015-03-23 16:54:23

标签: image matlab image-processing image-compression

我正在研究JPEG图像压缩,我研究了量化矩阵的使用,这通常在文献中给出,但我想编写程序,这样当我改变矩阵时,每个像素代表的位数应该是也有所不同,以便我可以绘制每像素位数与PSNR的关系图。

我见过的基本量化矩阵定义如下:

qm = [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]; 

如何推广创建量化矩阵?

1 个答案:

答案 0 :(得分:12)

从我所看到的,没有用于计算量化矩阵的“通用”方法。量化矩阵的创建方式是经过大量实验后,这些数字是最好的,可以提供良好的信噪比,并利用减小的文件大小提供良好的感知质量。根据您的谈话对象或您正在使用的产品,有些人使用他们自己的量化矩阵。例如,Adobe在Photoshop等产品中使用自己的量化矩阵,生成算法是商业秘密 - 我们不知道他们如何推导出他们的量化矩阵。

然而,目前有一个标准已经存在了一段时间......可能自从JPEG被提出以来......我知道它有一个计算量化矩阵的算法。这取决于所谓的Q factor或品质因素。该标准来自Independent JPEG Group或IJG。

基本算法如下。您首先提供质量因子Q,其为1到100. 1是“最差”质量,而100是“最高”质量。 50是默认设置。接下来,您需要定义 base 量化矩阵。基本IJG量化矩阵,我们将称之为Tb,如下所示:

Tb =

    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

您可能已经注意到,这是您在问题中定义的相同矩阵。那是因为你引用的矩阵来自IJG。获得此矩阵后,可通过以下步骤找到输出量化矩阵:

  1. 定义S,如果(Q < 50),则为S = 5000/Q,否则为S = 200 – 2*Q
  2. Ts[i,j]和列i的每个位置的输出量化矩阵j都是Ts[i,j] = floor((S * Tb[i,j] + 50) / 100)
  3. 请注意输出向下舍入,矩阵中的所有系数都是整数。此外,如果您指定了品质因数Q = 50,则应获得相同的基本量化矩阵(即无更改),并且是默认矩阵。

    因此,执行上述操作的非常简单的MATLAB程序如下所示:

    Q = 80; %// Define Q factor
    
    %// Define base quantization matrix
    Tb = [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];
    
    %// Determine S
    if (Q < 50)
        S = 5000/Q;
    else
        S = 200 - 2*Q;
    end
    
    Ts = floor((S*Tb + 50) / 100);
    Ts(Ts == 0) = 1; % // Prevent divide by 0 error
    

    代码的最后一行非常重要。您可能会遇到指定质量因子会导致0个元素的情况。这意味着当您使用量化矩阵时,问题将因零除错误而浮出水面。因此,最后的检查是将这些0元素设置为1,以便效果忽略输出结果中的这些位置。

    现在,作为一个例子,如果我们设置Q = 80,我们会得到:

    Ts =
    
         6     4     4     6    10    16    20    24
         5     5     6     8    10    23    24    22
         6     5     6    10    16    23    28    22
         6     7     9    12    20    35    32    25
         7     9    15    22    27    44    41    31
        10    14    22    26    32    42    45    37
        20    26    31    35    41    48    48    40
        29    37    38    39    45    40    41    40
    

    因此,相应地设置您的品质因数,使用它来压缩图像,然后您可以检查压缩结果中的PSNR或SNR是什么。您应该看到质量越低,PSNR或SNR就越低。


    有关更多信息,我参考了一组很棒的幻灯片,它们更详细地讨论了JPEG量化矩阵/表格:

    http://dfrws.org/2008/proceedings/p21-kornblum_pres.pdf

    祝你好运!