9

I'm working on JPEG image compression where I investigated the use of the quantization matrix which is usually given in literature, but I want to write program so that when I vary the matrix, the number of bits per pixel to represent should also vary so that i can plot the graph for bits per pixel versus PSNR.

The base quantization matrix that I have seen is defined as the following:

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]; 

How can I generalize creating the quantization matrix?

rayryeng
  • 102,964
  • 22
  • 184
  • 193
P.Bisoyi
  • 123
  • 1
  • 2
  • 10

1 Answers1

20

From what I've seen, there is no "general" method for calculating the quantization matrix. The quantization matrices are created in a way where after much experimentation, those numbers are the best that give a good SNR and gives good perceptual quality leveraging a decreased file size. Depending on who you talk to, or what product you're using, some use their own quantization matrices. For example, Adobe uses their own quantization matrices in products such as Photoshop and the generation algorithm is a trade secret - we don't know how they derived their quantization matrices.

However, there is currently one standard that has been around for a while... probably ever since JPEG was proposed.... that I know of that has an algorithm for computing the quantization matrix. This depends on what is known as the Q factor or Quality factor. This standard comes from the Independent JPEG Group or the IJG.

The basic algorithm is the following. You first provide a quality factor Q which is from 1 to 100. 1 is the "poorest" quality while 100 is the "highest" quality. 50 is the default setting. Next, you need to define the base quantization matrix. The base IJG quantization matrix, which we will call Tb, is the following:

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

You have probably noticed that this is the same matrix as you have defined in your question. That's because the matrix you have quoted is from the IJG. Once you have this matrix, the output quantization matrix can be found by the following steps:

  1. Define S such that if (Q < 50), then S = 5000/Q, else S = 200 – 2*Q.
  2. The output quantization matrix Ts[i,j] at each location of row i and column j is such that Ts[i,j] = floor((S * Tb[i,j] + 50) / 100)

Take note that the output is rounded down and all of the coefficients in the matrix are integer. Also, if you specified a quality factor of Q = 50, you should get the same base quantization matrix (i.e. no change), and is the default matrix.

Therefore, a very simple MATLAB program to do the above would look something like:

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

The last line of the code is very important. You may get a case where specifying a quality factor would result in 0 elements. This would mean that when you use the quantization matrix, problems will surface due to divide by zero errors. Therefore a final check would be to set those 0 elements to 1 so that the effect is ignoring these locations in the output result.

Now, as an example, if we set Q = 80, we get:

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

Therefore, set your quality factor accordingly, use it to compress your image, then you can check to see what the PSNR or SNR is from the compressed result. You should see that the lower the quality, the lower the PSNR or SNR should be.


For more information, here is a great set of slides that I referenced that talks about JPEG quantization matrices / tables in more detail:

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

Good luck!

rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • sir,here i m getting only on Ts value,i have to write a program such that the quality factor will increase/decrease according to that i can calculate number of bits per pixel value for plotting graph. – P.Bisoyi Mar 24 '15 at 02:40
  • 1
    Yes... that's the point of my post... getting the quantization matrix. Unfortunately, I don't know anything that relates quality factor to the number of bits per pixel. Sorry! – rayryeng Mar 24 '15 at 02:56
  • 1
    ok sir,can u help me in coding huffman coding used in jpeg compression without inbuilt function? – P.Bisoyi Mar 24 '15 at 03:37
  • sir,can i post my jpeg compression program i m unable to get the compressed and reconstructed image,so that u can help me out. – P.Bisoyi Mar 24 '15 at 03:45
  • You can post it. Not sure if I can help you out. – rayryeng Mar 24 '15 at 04:09
  • I m unable to post here the code as it is too long. – P.Bisoyi Mar 24 '15 at 05:41
  • sir, as u have taken the value of Q=80,if i vary the value from Q=60:90,it is showing error. – P.Bisoyi Mar 24 '15 at 06:01
  • @PrangyaBisoyi - No kidding. The script only takes **one** `Q` value... did you even read the code? – rayryeng Mar 24 '15 at 06:09
  • @PrangyaBisoyi - I saw the other post you wrote about your code. It's too long, and I can't be bothered to read it. – rayryeng Mar 24 '15 at 06:09
  • i have read the code ,i think u are unable to understand what i want to say. – P.Bisoyi Mar 24 '15 at 06:22
  • @PrangyaBisoyi - Bingo. – rayryeng Mar 24 '15 at 06:33
  • I think there must be a check for zero on the calculated Ts value. In my understanding there should be at least 1 as the matrix value. If you set 100% for quality you'll get a matrix full of 1's (see page 12 in the PDF of @rayryeng) – lumapu May 22 '17 at 09:47