I. Bien ranger ses affaires. Traitement d'image ou Programmer des fonctions de logiciels de retouche d'images! Pour bien travailler il est très important de savoir où sont rangées ses affaires. On va travailler dans un dossier dont l'adresse sera c:/isn/trait_img On peut créer ce dossier manuellement ou le faire faire par python : On a alors besoin de la bibliothèque os : import os #import de la bibliothèque os qui contient les fonctions #permettant de travailler sur des fichiers try: #essai de création du dossier os.makedirs('c:/isn/trait_img') #le dossier est créé avec les dossiers intermédiaires! print ("Dossier créé!") except (FileExistsError): print ("Le dossier existe déjà") #le dossier a déjà été créé, pas la peine de recommencer rep_cour=os.getcwd() #rep_cour est le répertoire courant (celui où le prg travaille actuellement) if ((rep_cour)!=("c:/isn/trait_img")): #si on n'est pas dans le dossier isn/trait_img os.chdir("c:/isn/trait_img") #alors on y va! print ("Répertoire de travail actuel : ",os.getcwd()) #affichage du répertoire courant pour vérifier #qu'on est où on veut II. Les images. Il existe de nombreux formats d'images (bmp, jpeg, pgm, etc). Nous allons travailler sur des images au format pgm (Portable Grey Map) qui sont des images en 256 niveaux de gris (0 = noir, 255 = blanc). Le langage python utilise une bibliothèque très utile pour le traitement d'images : PIL (Python Imaging library) Installer la bibliothèque en lançant l'executable Pillow-2.1.0.win32-py3.3.exe On va travailler sur une image test nommée img_base.pgm (ce fichier sera placé dans le dossier "c:/isn/trait_img") B M-L 1/8
III. Le traitement d'images. III.1. Ouvrir un fichier et lire ses propriétés. On va supposer que le dossier "c:/isn/trait_img" a été créé et qu'il est notre répertoire courant. Une petite vérification avec os.getcwd() peut être utile ;-) Ne jamais hésiter à regarder les informations sur une fonction grâce à help! exemple : help(image) import os from PIL import Image #bibliothèque pour le travail sur les dossier #bibliothèque pour le travail sur les images rep_cour=os.getcwd() #répertoire courant print ("répertoire courant :",rep_cour) if rep_cour!="c:/isn/trait_img": #si on n'est pas dans le bon print ("on se déplace vers ") os.chdir("c:/isn/trait_img") #on s'y déplace! print(os.getcwd()) #vérification print ("tout est en ordre!") #Nous allons ouvrir le fichier image img_base nom_image=("img_base.pgm") #pour ouvrir une autre image il suffira de changer le nom img_in=image.open(nom_image) #img_in "contient" le fichier image print ("Nom de l'image :",nom_image) print("format de l'image :",img_in.format) #Portable PixMap print ("Taille de l'image :",img_in.size) #tuple (Colonnes,Lignes) print ("Mode de l'image :",img_in.mode) #niveaux de gris img_in.show() #affichage de l'image On a donc récupéré beaucoup d'informations (en particulier la taille de l'image)! On va maintenant créer une nouvelle image qui soit de la même taille que la première et que nous rangerons dans le dossier c:/isn/trait_img B M-L 2/8
III.2. Créer une copie à l'identique. On va "construire" un fichier img_out ayant les mêmes propriétés que le fichier img_in! Le principe va être le suivant : Balayer le fichier img_in sur les L lignes et C colonnes Récupérer la valeur de chaque pixel (p=img_in.getpixel(x,y)) Recopier la valeur du pixel dans la nouvelle image (img_out.putpixel(x,y),p) Il va de soi que le fichier img_out sera créé avant d'être rempli : (img_out=image.new(img_in.mode,img_in.size) Une fois ce travail effectué, on sauvegardera la nouvelle image : img_out.save("img_copie.pgm) III.3. Passer du niveau de gris au noir et blanc. On va maintenant produire une image de sortie différente de celle d'entrée. L'image de sortie sera en noir et blanc. On sait que chaque pixel a une valeur comprise entre 0 et 255 (du plus foncé au plus clair). Ecrire un programme qui produise une image en noir et blanc pour laquelle on aura choisi le seuil (entre 50 et 200). Cette image sera sauvegardée sous le nom img_nb Seuil = 75 Seuil = 175 B M-L 3/8
III.4. Effet négatif. L'effet négatif consiste à remplacer chaque valeur de pixel par son complémentaire à 255. On obtient alors un effet similaire à celui des négatifs d'appareils photos argentique. Ecrire le programme qui permet de réaliser cet effet et de sauvegarder l'image sous le nom img_neg.pgm. III.5. Effet miroir. Cette fois on va générer une image qui sera une réflexion par rapport à un axe vertical. On la sauvegardera sous img_refv.pgm On peut s'amuser à faire un reflet par rapport à un axe horizontal. Sauver sous img_refh.pgm III.6. Réduction d'une image. On va diviser par 2 la taille de l'image. Pour cela on peut donner au nouveau pixel la valeur moyenne des pixels constituant le carré de 2 x 2 qu'il remplace. On sauvegardera le résultat sous img_reduite.pgm On peut s'amuser à programmer cette réduction en choisissant le taux de réduction (de 1 à 10 par exemple). Sauvegarder sous img_reduite_taux.pgm B M-L 4/8
III.7. Effet photomaton. On a compris qu'ici on allait réduire l'image puis la recopier quatre fois. Celle là on va l'appeler img_photomaton.pgm III.8. Effet de bord. Afin de localiser des objets dans une image, il est nécessaire de localiser les bords de ces objets. Le principe va consister à comparer les valeurs de pixels voisins. Si ces valeurs sont très différentes, il est probable qu'on se trouve sur le bord d'un objet! Par exemple sur l'image ci contre, le pixel "a" se trouve en bordure d'objet alors que le pixel "b" est à l'intérieur de l'objet. 155 Pour un pixel en position a : 60 a 140 e 50 b 35 d a b 40 On calcule un nombre t= ((b d) 2 +(c e) 2 ) c Exemple : pour "a", t= ((140 60) 2 +(35 155) 2 ) 144,2 et pour "b", t= ((35 50) 2 +(40 60) 2 )=25 On va donc estimer que si le nombre est supérieur à 25 (par exemple) alors le pixel se trouve en bordure. On l'affichera en noir et si le nombre est inférieur à 25 on l'affichera en blanc. Ecrire une fonction qui prend en argument 4 nombres b, c, d, e et qui retourne le nombre ((b d) 2 +(c e) 2 ) Mettre en œuvre la transformation et sauver le résultat sous le nom img_bord.pgm B M-L 5/8
IV. Travail sur des images en couleurs (format jpg). On va travailler dans un dossier c:/isn/trait_img/jpg IV.1. Format d'un pixel. Dans le cas du format jpg, chaque pixel est un tuple constitué de 3 valeurs (R,G,B). Chacune de ces valeurs représente le niveau de Rouge, de Vert et de Bleu constituant le point. Ces valeurs sont comprises entre 0 et 255. Le noir correspond au tuple (0,0,0) et le blanc à (255,255,255). Ecrire un programme qui va afficher la valeur du pixel de coordonnées (10,20) de l'image img_base.jpg. IV.2. Transformation en niveaux de gris. Pour transformer une image couleur en image en niveaux de gris, on peut faire la moyenne des 3 couleurs et affecter le résultat au pixel de l'image nouvellement créée. On doit prendre soin de définir le mode de la nouvelle image comme étant "L" : img_out=image.new("l",img_in.size) Sauvegarder l'image produite sous img_niv_gris.pgm IV.3. Transformation en négatif couleur. On reprendra le même principe que pour le négatif noir et blanc en agissant sur chacune des trois couleurs R, G et B. Sauvegarder sous img_neg.jpg B M-L 6/8
V. Scripts utilisés. V.1. Copie d'une image.pgm à l'identique. import os from PIL import Image #bibliothèque pour le travail sur les dossier #bibliothèque pour le travail sur les images rep_cour=os.getcwd() #répertoire courant print ("répertoire courant :",rep_cour) if rep_cour!="c:/isn/trait_img": #si on n'est pas dans le bon print ("on se déplace vers ") os.chdir("c:/isn/trait_img") #on s'y déplace! print(os.getcwd()) #vérification print ("tout est en ordre!") #Nous allons ouvrir le fichier image img_base print ("Ce programme va recopier à l'identique l'image img_base et sauvegarder la copie") nom_image=("img_base.pgm") #pour ouvrir une autre image il suffira de changer le nom img_in=image.open(nom_image) taille=img_in.size #tuple (Colonnes,Lignes) des dimensions de l'image col=taille[0] lgn=taille[1] print ("image de",col,"colonnes par",lgn,"lignes") img_out=image.new(img_in.mode,img_in.size) #création du fichier de sortie for l in range(lgn): for c in range(col): #print(l,c) p=img_in.getpixel((c,l)) img_out.putpixel((c,l),p) img_out.save("img_copie.pgm") img_in.show() img_out.show() #affichage de l'image de départ #affichage de l'image créée B M-L 7/8
V.2. Transformation d'une image couleurs en niveau de gris. import os #bibliothèque pour le travail sur les dossier from PIL import Image #bibliothèque pour le travail sur les images rep_cour=os.getcwd() #répertoire courant print ("répertoire courant :",rep_cour) if rep_cour!="c:/isn/trait_img/jpg": #si on n'est pas dans le bon print ("on se déplace vers ") os.chdir("c:/isn/trait_img/jpg") #on s'y déplace! print(os.getcwd()) #vérification print ("tout est en ordre!") #Nous allons ouvrir le fichier image img_base print ("Ce programme va trnsformer une image couleurs en image en niveaux de gris et sauvegarder la copie") nom_image=("img_base.jpg") #pour ouvrir une autre image il suffira de changer le nom img_in=image.open(nom_image) taille=img_in.size #tuple (Colonnes,Lignes) des dimensions de l'image col=taille[0] lgn=taille[1] print ("image de",col,"colonnes par",lgn,"lignes") img_out=image.new("l",img_in.size) #création du fichier de sortie for l in range(lgn): for c in range(col): #print(l,c) p=img_in.getpixel((c,l)) p=(p[0]+p[1]+p[2])/3 img_out.putpixel((c,l),p) img_out.save("img_niv_gris.pgm") img_in.show() #affichage de l'image de départ img_out.show() #affichage de l'image créée B M-L 8/8