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?
Lossy Data Compression: JPEG. Quantization is the process of reducing the number of bits needed to store an integer value by reducing the precision of the integer. Given a matrix of DCT coefficients, we can generally reduce the precision of the coefficients more and more as we move away from the DC coefficient.
Quantization of the transformed blocks is obtained by dividing the transformed pixel values by corresponding elements of a quantization matrix and rounding the ratio to the nearest integer.
Quantization matrices The quantization matrix is designed to provide more resolution to more perceivable frequency components over less perceivable components (usually lower frequencies over high frequencies) in addition to transforming as many components to 0, which can be encoded with greatest efficiency.
The quantization tables used for JPEG compression can also be used to help separate images that have been processed by software from those that have not. This loose classification is sufficient to greatly reduce the number of images an examiner must consider during an investigation.
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:
S
such that if (Q < 50)
, then S = 5000/Q
, else S = 200 – 2*Q
.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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With