TD de Programmation Orientée Objets TD 8 : Arbres à huit fils (octree) M. Bosc, J-M. Dischler et J. Lamy Le but de ce TD est de quantifier les couleurs d’une image RVB, chargée au format PPM. Quantifier signifie réduire le nombre de couleurs de l’image. On suppose que l’on veut créer des images ayant au maximum N couleurs. 1 Principes de l’algorithme L’algorithme est très simple : on parcourt chaque pixel de l’image. A chaque pixel est associée une couleur au format RVB. L’espace RVB peut être considéré comme un espace à 3 dimensions formant un cube de valeurs. Un octree est une structure de données adapté à ce type de représentation : un cube de coté un, peut être divisé en 8 cubes de coté 0.5, qui eux mêmes peuvent être divisés en 8 cubes, etc. Chaque couleur RVB peut être placée et stockée dans un octree, de profondeur 8 (puisque les couleurs sont codées avec des entiers allant de 0 à 255). Une fois la couleur du pixel placée dans l’octree, on vérifie si le nombre de feuilles est supérieur à N . Si c’est le cas il faut réduire l’octree en remontant d’un cran les feuilles les plus basses. A la fin de l’algorithme on est sûr d’obtenir un arbre ayant un nombre de feuilles inférieur ou égal à N . Ces feuilles correspondent aux couleurs de l’image finale. Il suffit de reparcourir l’image et d’associer à chaque pixel, la couleur de l’arbre la plus proche. Les classes à définir sont les suivantes : 1. ColRGBA, comme défini précédemment avec quelques opérations en plus, dont par exemple la recherche d’une plus proche couleur dans un tableau. 2. PictRGBA, avec un convertisseur en PictQ 3. octree 4. PictQ, qui correspond à une image quantifiée. 2 Exemple de fichier main #include "image1.h" #include "PictQ.h" #include "iostream.h" const int MAX_LEN=256; int main() { PictRGBA pi, pi2; char fname[MAX_LEN]; FILE *fd; double d; // lire un fichier ppm cout<<"nom du fichier image ppm: "; cin>>fname; fd = fopen(fname, "rb"); if (fd==NULL) { perror("error loading file"); exit(1); } pi.LoadPPM(fd); fclose(fd); // convertir en double, cad calculer le gris moyen d = pi; cout<<"moyenne:"<<d<<endl; // quantifier en 8 couleurs PictQ piq(pi,8); cout<<"quantification achevee..."<<endl; // reconvertir l’image quantifiee en image RGB pour sauvegarder pi2 = piq; // sauvegarder cette image cout<<"nom du fichier image quantifiee ppm: "; cin>>fname; fd = fopen(fname, "wb"); if (fd==NULL) { perror("error saving file"); exit(1); } pi2.SavePPM(fd); fclose(fd); return 0; }