Deuxièmes années Lycée Masséna TP : Traitement d’images noir et blanc avec Nump
Deuxièmes années Lycée Masséna TP : Traitement d’images noir et blanc avec Numpy 1 Images en noir et blanc et Numpy Une image grise au format PNG est simplement donnée par la luminosité de ses pixels, qui est un entier entre 0 et 255 (donc encodable sur 8 bits). Pour une image couleur, il y a trois composantes (rouge, verte et bleue) par pixel, ici nous n’aurons qu’une composante car nous traitons d’images en noir et blanc. Voici comment récupérer les pixels d’une image sous forme d’un tableau Numpy : from PIL import Image import numpy as np im=Image.open("lena_gris.png") #à télécharger sur le site web. Adapter le chemin sous Spyder. T=np.array(im) h,l=T.shape #hauteur, largeur de l'image Le résultat est un tableau Numpy, dont les éléments sont de type uint8 (pour unsigned integer, entiers non signés, sur 8 bits). T[i][j] donne la valeur du pixel à la i-ème ligne, et la j-ème colonne, indexées à partir de 0 (le pixel (0, 0) est le coin en haut à gauche). À l’inverse, on peut créer une image à partir d’un tableau Numpy au format uint8 via : Image.fromarray(tableau) Souvent, le tableau en question est obtenu à partir d’un tableau existant, mais on peut en créer avec np.zeros : avec h et l hauteur et largeur de l’image à créer, on écrirait np.zeros((h,l), dtype="uint8") pour créer un tableau idoine, qu’il suffit de remplir. Pour afficher une image, il suffit d’utiliser show. Par exemple im.show() via le code situé plus haut vous affiche l’image de Léna. 2 Quelques manipulations élémentaires 2.1 Histogramme Exercice 1. Histogramme d’une image. Écrire une fonction histo(im), qui prend en argument une image en niveau de gris. Cette fonction doit renvoyer une liste de taille 256 : en première position (indice 0), le nombre de pixels noirs (gris 0), en deuxième position (indice 1), le nombre de pixels gris 1, . . . , en dernière position (255), le nombre de pixels blancs (gris 255). Svartz Page 1/6 2017/2018 Deuxièmes années Lycée Masséna Appliquez votre code à l’image lena_gris.png, préalablement chargée. Vous utiliserez ensuite le module matplotlib pour tracer l’histogramme. Petit rappel pour tracer un graphe : import matplotlib.pyplot as plt plt.plot(X,Y) #X et Y sont les listes (ou tableaux numpy) d'abscisses et d'ordonnées des points à tracer plt.show() #pour afficher 2.2 Modifier la luminosité d’une image Pour augmenter la luminosité, il suffit d’ajouter une valeur fixe à tous les niveaux. Pour diminuer la luminosité il faudra au contraire soustraire une valeur fixe à tous les niveaux. Exercice 2. Écrire une fonction change_luminosite(im,d), qui prend en argument une image en niveau de gris et un entier entre 0 et 255, valeur du décalage du niveau de gris. Cette fonction renvoie une nouvelle image. Attention : on prendra garde que si l’on essaie de mettre un entier dans un tableau dont les éléments sont de type uint8, celui-ci est pris modulo 256. On convient que pour une valeur de pixel p, si p + d > 255 il faut stocker 255, et si p + d < 0, il faut stocker 0. Le résultat attendu pour lena_gris.png avec un décalage de 50 est donné ci-dessous. ⇝ Remarque : il est très mauvais d’augmenter ainsi la luminosité : avec un décalage de 50, il n’existera plus aucun point entre 0 et 50, et les points ayant une valeur supérieure à 205 deviendront des points parfaitement blancs, puisque la valeur maximale possible est 255. La nouvelle image contient des zones brûlées. Plutôt que d’utiliser la fonction p 7→ p + 50 si p < 205. 255 sinon. , il vaut mieux utiliser une fonction « presque bijective » de forte croissance au voisinage de 0 et de très faible croissance au voisinage de 255, comme sur le graphe ci-dessous : Transformation initiale Une meilleure transformation Exercice 3. Si le TP est terminé. Chercher une meilleur transformation ! 2.3 Augmentation du contraste par dilatation de l’histogramme Une méthode relativement simple pour augmenter les contrastes est de s’arranger pour que l’histogramme de la nouvelle image occupe toute la plage de valeurs [ [0, 255] ]. Pour ce faire, on peut, en considérant l’histogramme comme une fonction H : [ [0, 255] ] →N : — repérer dans l’histogramme de l’image initiale les indices imin et imax tels que pour i < imin ou i > imax, on ait H(i) < s, avec s un petit entier seuil (par exemple s = 3). Autrement dit, il y a strictement moins de s pixels de couleur gris i pour tous les i strictement inférieurs à imin ou strictement supérieurs à imax ; Svartz Page 2/6 2017/2018 Deuxièmes années Lycée Masséna — appliquer la transformation affine x 7→256×(x−imin) imax−imin à chaque pixel gris x de l’image, en arrondissant 1 à l’entier le plus proche et en remplaçant les valeurs négatives par 0 et les valeurs supérieures à 255 par 255. En appliquant cette transformation à l’image lena_gris.png, avec seuil s = 3, on obtient le résultat suivant 2 : ⇝ Ceci est très visible sur l’histogramme, voici comment celui-ci a été transformé : ⇝ Exercice 4. Écrire une fonction augmente_contraste(im,s) prenant en entrée une image en niveau de gris et le seuil s, et renvoyant l’image obtenue par le procédé décrit précédemment. Testez votre fonction avec l’image lena_gris.png. 3 Images en fichier texte Les formats d’image sont variés, dans cette section, on va s’intéresser à deux formats textuels : PBM et PGM. On pourra ouvrir le contenu avec le bloc note, par exemple. 3.1 Format PBM Le format PBM est un format textuel (ASCII) permettant d’encoder des images binaires (chaque pixel est soit noir, soit blanc). Voici un exemple de fichier au format PBM, encodant une image représentant la lettre « J » 3 P1 # Un exemple bitmap de la lettre "J" 7 10 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 Quelques précisions : — La première ligne contient simplement P1. — Tout ce qui suit un # est ignoré : ceci permet les commentaires. 1. la fonction round est là pour ça. 2. Mieux que l’originale ! 3. L’exemple a été honteusement pris sur Wikipedia. Svartz Page 3/6 2017/2018 Deuxièmes années Lycée Masséna — La deuxième ligne (sans compter les lignes de commentaires) contient largeur et hauteur de l’image. — À la suite se trouvent les valeurs des pixels, prise de haut en bas puis de gauche à droite, séparés par des espaces et des sauts de lignes. Les 1 correspondent à des pixels noirs, les 0 à des pixels blancs. Rien n’impose d’écrire une ligne de l’image par ligne du fichier, d’ailleurs les lignes sont normalement limitées à 70 caractères (caractères d’espacement inclus). Par exemple : P1 3 5 1 0 1 0 1 0 0 0 1 1 1 1 1 0 0 est un encodage tout à fait valide d’une image de hauteur 5 et de largeur 3. Rappel. Pour ouvrir un fichier en écriture, on utilise f=open("nom_du_fichier", "w") (le w signifie « write »). Pour écrire dans le fichier, on utilisera dans ce TP f.write(s) où s est une variable contenant une chaîne de caractères. Pour transformer un entier (ou autre chose) en chaîne, utiliser str. Pour concaténer des chaînes, utiliser +. Enfin, le saut de ligne s’encode comme "\n". Une fois votre fichier écrit, fermez-le 4 avec f.close(). Exercice 5. Conversion PNG vers PBM . Écrire une fonction conversion_PNG_PBM(im, f) prenant en entrée une image au format PNG (dont les pixels sont blancs (255) ou noirs (0), et écrivant dans un fichier f ouvert en écriture l’image au format PBM. En pratique, il faut ici ouvrir en écriture un fichier du style image.pbm (en dehors de la fonction), dans lequel on va écrire des lignes de texte comme ci-dessus. Essayez avec l’image QR_code.png. Modifier ensuite la fonction pour transformer une image en niveau de gris en image PBM : un pixel de valeur inférieure à 120 sera converti en pixel noir, autrement il sera converti en pixel blanc. Remarque : il n’est pas très évident de faire l’inverse (nombre arbitraire d’espaces, commentaires...), mais ce serait un bon exercice ! 3.2 Format PGM Vous pouvez passer cette section dans un premier temps. Le format PGM est très similaire au format PBM, mais il encode des images en niveau de gris. Voici le texte d’un fichier PGM 5 : P2 # Affiche le mot "FEEP" (exemple de la page principale de Netpbm à propos de PGM) 24 7 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 0 uploads/Litterature/ tp-images-spe.pdf
Documents similaires
-
20
-
0
-
0
Licence et utilisation
Gratuit pour un usage personnel Attribution requise- Détails
- Publié le Jul 13, 2022
- Catégorie Literature / Litté...
- Langue French
- Taille du fichier 1.4877MB