P.S. You should know that the best answers I found so far are in another thread of the Digital Image Processing Forum. The best "all purpose" luma quantization table I have found so far is discussed in http://imagemagick.org/discourse-server ... 22&t=20427
I'm not quite done with chroma, and with the exploitation of progressive scan to improve the quality of images which are enlarged. However, the "stupid pet tricks" discussed in http://imagemagick.org/discourse-server ... 22&t=20402 are immensely promising (at least for large images) and even though the ones shown there are not quite "finalized versions", there is much to gain in using them, esp. if you expect users to zoom in the images you put out.
The current thread documents my early attempts and presents some heuristics that eventually led to progress.
-----
I've scoured the web/literature for better JPEG quantization tables and eventually settled for trying to improve them myself.
In the process, I discovered why there is not a plethora of better tables "out there". (Understatement.)
For one thing, the original quantization tables (determined through experiments involving human test subjects) are amazing.
For another, the Discrete Cosine Transform (DCT) is quite good at ironing out small differences, and consequently things don't jump at you if you make small changes.
With this disclaimer out of the way, here is my current best. It's likely to change, although probably not by a lot.
I'd love to get feedback (or, even better, a superior set of quantization tables for quality settings in the neighbourhood of 75 using the cjpeg convention).
The tables are tuned for 2x2 subsampling (more or less conceptually equivalent to box filtering the blue and red channels prior to encoding, and using 16x16 blocks instead of 8x8 for these two channels, with known unfortunate consequences (basically, chroma bleeds from one luma block to another), but considerable file size reduction). I have another set, not quite as mature, for 1x1.
We are certainly not talking about a huge win, but it appears to me that they represent a small bang/buck improvement.
When I started working on this I thought I could get mileage by exploiting the fact that the human psychovisual system is less sensitive to small blue features than red ones, and consequently experimented with the use of a more "compressing" blue channel table, but so far I have not managed to make this a big win, and consequently have (temporarily?) abandoned this direction. So, there are only two tables, like in the ITU standard.
Code: Select all
# Nicolas Robidoux's better (?) JPEG quantization tables v.2012.02.14
# Remix of ISO-IEC 10918-1 : 1993(E) Annex K
# Recommended for use with cjpeg -sample 2x2
# Luma
16 12 13 16 22 33 51 69
12 13 14 19 25 47 63 76
13 14 17 24 39 57 76 83
16 19 24 30 54 78 91 96
22 25 39 54 70 104 123 129
33 47 57 78 104 124 159 154
51 63 76 91 123 159 193 201
69 76 83 96 129 154 201 248
# Chroma
17 18 24 47 99 128 192 256
18 21 26 66 99 192 256 512
24 26 56 99 128 256 512 512
47 66 99 128 256 512 1024 1024
99 99 128 256 512 1024 2048 2048
128 192 256 512 1024 2048 4096 4096
192 256 512 1024 2048 4096 8192 8192
256 512 512 1024 2048 4096 8192 8192
For the sake of comparision, here are the standard quantization tables, copied from the jcparam.c file of the JPEG club's jpeg-8d (most recent) source:
Code: Select all
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
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
};
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
Code: Select all
cjpeg -optimize -baseline -quality 75 -qtables robidoux.txt -qslots 0,1,1 -sample 2x2 -dct float -outfile out.jpg in.ppm