DIIC - INC, 3 e année Module COMV TP 1 - Introduction au codage d image : manipulation des outils Gaël Sourimant, Luce Morin 18 octobre 2006 1 Introduction Le but de ce TP est d observer et de comparer les performances respectives de deux algorithmes de compression. Le premier objectif est d avoir une idée des taux de compression, des distorsions et des artefacts associés à chacun des algorithmes. Le second consiste à appréhender correctement la mesure de distorsion utilisée : son fonctionnement et ses limites. Avant de commencer à programmer, il vous est demandé de lire attentivement ce qui suit dans cette introduction. 1.1 Algorithme LZW L algorithme de Lempel-Ziv-Welch 1 (LZW) est un algorithme très populaire. Il permet une compression sans pertes et peut donc être utilisé pour la compression de données quelconques, comme du texte ou du code exécutable. On peut donc aussi l utiliser pour la compression d images sans pertes lorsque le contexte le requiert, par exemple en imagerie médicale, où la compression avec pertes est souvent interdite. Si le message à coder est vu comme une source de caractères, la technique de l algorithme LZW consiste à coder non pas les caractères eux-mêmes mais des séquences de chaînes de caractères successives. Lors du codage, une table de correspondance (un dictionnaire), construite en ligne (à la volée), permet d associer à chaque chaîne de caractères un mot de code de longueur fixe. La chaîne des codes est alors transmise. Plus les chaînes codées sont longues, plus le taux de compression est élevé. Le principe de codage est tel que le dictionnaire n a pas besoin d être transmis : il est reconstitué dynamiquement lors du décodage. Pour que l algorithme soit performant, il faut que le message comporte des chaînes qui présentent des caractéristiques particulières, c est-à-dire que certains types d images pourront être avantageusement compressées par cet algorithme, alors que d autres pourront même 1 voir, par exemple, http://www.alphabeta-net.com/lzw.html 1
subir une augmentation de volume. Sous Unix, la commande compress implante une variante du LZW. En image, le LZW est à la base du format de fichier 2 (GIF), figure parmi les algorithmes du format 3 (TIFF) et est utilisé dans le format POSTSCRIPT (Level 2). 1.2 Algorithme JPEG Le standard 4 JPEG définit une norme pour la compression des images. Cette norme utilise la DCT (transformée en cosinus discrète) suivie d une quantification des coefficients. En pratique, on utilise une DCT par blocs de taille 8 8 et une quantification uniforme des coefficients DCT. Aucun coefficient n est explicitement abandonné, mais l annulation de certains coefficients provient des termes d une matrice qui définit la quantification. Les coefficients, en vue de la transmission, sont disposés dans un ordre dit zig-zag. On obtient une suite monodimensionnelle de coefficients, rangés selon un ordre tel que, en moyenne, cette suite est décroissante. Ceci permet d effectuer de nombreux regroupements de coefficients nuls, et ainsi de coder efficacement chaque bloc par codage de plages (run-length). Ce schéma de compression est à peu près symétrique : les temps de compression et de décompression sont semblables. 1.3 Évaluation de la distorsion à l aide du PSNR Dans le but de fournir une mesure objective de la distorsion introduite par la compression, on utilisera le PSNR (Peak Signal to Noise Ratio). Soient respectivement I o et I r les images originale et reconstruite, de même taille M N. La valeur de l intensité lumineuse associée au pixel de coordonnées (i, j) d une image I est noté I(x, y). Le calcul du PSNR fait intervenir le calcul de l erreur quadratique moyenne, l EQM (ou MSE pour Mean Square Error) : EQM(I o, I r ) = Le PSNR est donné par l expression 1 M N M 1 i=0 N 1 j=0 [I o (i, j) I r (i, j)] 2. PSNR(I o, I r ) = 10 log 10 D 2 EQM(I o, I r ), où D est la dynamique couverte par les variations de l intensité lumineuse. Les pixels des images à traiter sont codés sur 8 bits, donc D = 2 8 1 = 255. L unité du PSNR est le décibel et est noté db. Plus celui-ci est important, plus les images comparées sont semblables. 1.4 Présentation de la librairie libit Tous les TP utiliseront la librairie libit 5. Celle librairie est écrite en C et permet de manipuler des objets et structures couramment utilisés en codage. Elle permet également de manipuler 2 http ://lappweb.in2p3.fr/infographie/gif.html 3 http ://lappweb.in2p3.fr/infographie/tiff.html 4 http ://lappweb.in2p3.fr/infographie/jpg.html 5 http://libit.sourceforge.net 2
des images, qui sont représentées comme des matrices (ou des tableaux à deux dimensions, selon l usage qui en est fait). Vous trouverez une documentation succincte à l URL http://libit.sourceforge.net/doc/libit.pdf Parcourez les sections 2.2 (Vectors) à 3.4 (Parser) de cette documentation (la section 3.3 ne vous servira pas). Cette librairie est installée dans le répertoire /share/diic3/local. Afin de pouvoir l utiliser, suivez les étapes suivantes. 1. Ajouter le répertoire /share/diic3/local/bin dans votre variable d environnement PATH. export PATH=$PATH:/share/diic3/local/bin 2. Ajouter le répertoire /share/diic3/local/man dans la variable d environnement MANPATH. export MANPATH=$MANPATH:/share/diic3/local/man Considérer ensuite l exemple ci-dessous. Il charge une image au format PGM 6 et en affiche le nom, les éventuels commentaires et les dimensions. Il le recopie sans modification sur le disque. #include <it/io.h> #include <it/mat.h> #include <it/parser.h> int main( int argc, char ** argv ) { /* Declaration and initialization of a parser with default values */ parser_t * parser = parser_init( argc, argv, "tp1.param", NULL ); } const char * filename_in = parser_get_string( parser, "-i" ); const char * filename_out = parser_get_string( parser, "-o" ); char pnm_type, comments[1000]; int width, height, maxval; imat m; /* Use the image file header */ pnm_info( filename_in, &pnm_type, &width, &height, &maxval, comments, 1000 ); printf( "Input file name = %s\npnm type = %c\n%dx%d -> maxval=%d\ncomments=%s\n", filename_in, pnm_type, width, height, maxval, "" ); /* Read the image from a file and display its dimensions */ m = imat_pgm_read( filename_in ); printf( "height = %5d\tmaxheight = %5d\nwidth = %5d\tmaxwidth = %5d\n", imat_height(m), imat_height_max(m), imat_width(m), imat_width_max(m) ); /* Write the image as a pgm into a file */ imat_pgm_write( filename_out, m ); /* Free the memory and return */ imat_delete(m); return 0; 6 Le format PGM(Portable GreyMap), est l un des formats PNM. Pour une description succincte de format, voir par exemple http ://astronomy.swin.edu.au/ pbourke/dataformats/ppm 3
Note : ce fichier ainsi que les fichiers associés sont disponibles dans le répertoire /share/diic3/inc_tpcomv/tp1. Remarquez que le programme nécessite la présence d un fichier de paramètres nommé /share/diic3/inc_tpcomv/tp1/tp1.param. En clair, récupérez les fichiers suivants et copiez les sur votre compte : tp1.c ; tp1.param ; Makefile. Regardez le fichier Makefile. Il vous servira pour voir comment compiler avec la librairie libit. 2 Manipulations à effectuer Vous allez compresser et décompresser (aux formats GIF/LZW et JPEG) des images brutes en niveaux de gris (au format PGM). Vous utiliserez pour cela des outils de manipulation d images disponibles en ligne de commande, tels que mogrify, pnmtojpeg ou jpegtopnm. Vous pouvez également utiliser si vous le souhaitez le logiciel xv. Les images de test sont les suivantes : simple.pgm (300 300) : image synthétique simple, sati.pgm (400 400) : image MétéoSat, cornouaille.pgm (720 576) : photo numérisée, barbara.pgm (512 512) : photo numérisée, lena.pgm (512 512) : photo numérisée. Ces images sont disponibles dans le répertoire /share/diic3/share/inc_tpcomv/images. 2.1 Compression sans pertes LZW Question 2.1. Copier les images d origine, listées ci-dessus, sur votre compte, puis enregistrez-les en GIF. Vous pouvez pour cela utiliser la ligne de commande : mogrify -format gif nom_image.ppm Question 2.2. Vérifiez visuellement que la compression se fait apparemment sans pertes et comparez les taux de compression selon les types d images. Question 2.3. Concluez sur le domaine d utilisation de cette méthode. 2.2 Compression avec pertes JPEG Question 2.4. Reprenez les images originales en PGM et enregistrez-les au format JPEG, en utilisant la commande : pnmtojpeg -baseline -quality=n image_in.pgm > image_out.jpg Nous ne nous intéresserons pas au paramètre -baseline utilisé ici, mais plus particulièrement à -quality=n, puisque N est un paramètre de qualité, qui détermine la matrice de quantification, et donc le taux de compression. N est un entier à valeurs dans {1... 100}. Pour avoir une idée de quels paramètres de qualité utiliser, reportez-vous à la question suivante. Question 2.5. Pour différentes images, notez dans un tableau les informations suivantes : le paramètre de qualité utilisé (on fixe dans le cadre de ce Tp N {2, 10, 20, 40, 60, 85}) ; 4
5 Imperceptible 4 Perceptible mais non gênant 3 Légèrement gênant 2 Gênant 1 Très gênant TAB. 1 Notes de qualité subjective la taille de fichier ; le taux de compression ; la qualité subjective de l image. Pour la mesure de qualité subjective de l image, attribuez une note entre 1 et 5 en fonction de l échelle fournie dans la table 1. Note : Conservez les images au format JPEG que vous avez obtenues. Elle vous serviront par la suite. Question 2.6. Déduisez les taux de compression limites correspondants à une erreur de reconstruction que vous jugerez imperceptible (et gardez ces images quelque part). Question 2.7. Décrivez et expliquez l effet visuel obtenu lorsque la qualité est mauvaise. 2.3 Autour du PSNR Dans cette partie, vous allez remplacer la mesure subjective précédemment utilisées par la mesure objective du PSNR. Question 2.8. Implantez 7 un programme psnr qui prend en entrée deux noms de fichiers au format PGM et qui renvoie la mesure du PSNR. Question 2.9. Complétez le tableau de la partie précédente en y ajoutant le PSNR calculé par votre programme. Note : Pour gagner du temps, transformez vos fichiers JPEG en fichiers PGM en utilisant le programme jpegtopnm : jpegtopnm image.jpg > image.pgm Question 2.10. Commentez votre tableau d une manière détaillée. En particulier, après avoir comparé les valeurs obtenues pour différentes images, concluez sur l interprétation de la valeur absolue de PSNR. Question 2.11. Tracez la courbe débit/distorsion pour les images simple.pgm, sati.pgm et lena.pgm. Note : Dans le cas présent le "débit" est considéré comme étant représenté par la taille des fichiers JPEG que vous avez généré. il vous est donc demandé de tracé la courbe psnr = f(taille_f ichier). Question 2.12. Une version "décalée" de lena.pgm vous est fournie dans /share/diic3/inc_tpcomv/tp1/lena_offset.pgm. Par rapport à l image originale, la première colonne disparaît, la deuxième devient la première, etc. sauf la dernière qui est dupliquée. Calculez le PSNR entre l original et sa version décalée. Commentez. 7 Utilisez pour cela le squelette de programme tp1.c et le Makefile qui sont fournis 5