MP – Lycée Dessaignes Année scolaire 2016/2017 TP I NFORMATIQUE N O 5 T RAITEMENT D ’ IMAGES Ouverture et affichage On commence par importer le nécessaire import numpy as np import matplotlib.pyplot as plt import matplotlib.image as mpimg Ouvrons l’image, elle doit se trouver dans le répertoire courant, sous Pyzo il faut exécuter le script pour lui faire comprendre. mon_bitmap = mpimg.imread("victoire_samothrace.png") mon_bitmap est un tableau numpy tridimensionnel : on récupère ses dimensions : forme = mon_bitmap.shape print(forme) Vérifier en console : > mon_bitmap Pour l’afficher : plt.imshow(mon_bitmap) plt.show() Si on modifie le tableau mon_bitmap, pas de problème tant que n’enregistre pas l’image. Pour enregistrer une image (modifié) mpimg.imsave("nouvelle.png", nouveau_bitmap) Couleurs L’image ne semble pas très colorée, RGB vraiment ? Q.1 Pour s’en persuader on va supprimer tout le Rouge en mettant la première coordonnées à 0. On affiche ensuite l’image obtenue. for i in range(hauteur): for j in range(largeur): mon_bitmap[i,j,0]=0 plt.imshow(mon_bitmap) plt.show() Modifier ensuite la couleur à supprimer, ou deux, ou la mettre au maximum, enjoy. Opérations de base Rappel : Les points de l’image sont repérés par leur position hauteur / largeur (on part en haut à gauche). Q.2 Trait Tracer un trait blanc entre les points de coordonnées (0, 50) et (200, 100). Le blanc est le maximum de chaque couleur. Q.3 Morceaux On veut découper l’image et récupérer les points entre les abscisses 50 et 150 et les ordonnées 100 et 200. Cette nouvelle image s’appellera nouveau_bitmap. Sauver ensuite cette image. 1 Noir et Blanc moral : niveau de gris On va maintenant convertir l’image en niveau de gris, on prends motif = mpimg.imread("victoire_encadree.png") Q.4 Passage de couleur en niveau de gris Pour cela, on doit décider du niveau de gris : on va choisir une moyenne pondérée de chaque couleur : def average(pixel): return (0.299*pixel[0] + 0.587*pixel[1] + 0.114*pixel[2]) Ensuite on applique cette opération à tout le tableau : def convert(image): hauteur,largeur,_ = image.shape grey = np.zeros((hauteur,largeur)) for i in range(hauteur): for j in range(largeur): grey[i][j] = average(image[i][j]) return(grey) Et on affiche : grey = convert(motif) plt.imshow(grey, cmap = cm.Greys_r) # précise que l'image est en niveau de gris plt.show() Constater. Essayer de modifier la fonction average attention, il faut rester sur [0, 1] ! Q.5 Négatif On conserve l’image grey (juste neutraliser l’affichage). On veut construire le négatif de cette image. Construire alors une fonction negatif(im) réalisant cette opération. Q.6 Traitement ponctuel On veut modifier chaque pixel de l’image, cela reviens à modifier un taux de gris t par f (t ) avec f : [0, 1] → [0, 1]. On augmente le contraste : def f1(t): if t<0.25: return(0) if t>0.75: return(1) return(2*t-0.5) On diminue le contraste : def f2(t): return(0.25+0.5*t) Faire le travail, admirer le résultat. Pour rigoler essayez de mettre des fonctions trigo dans f . (C’est moins galère à écrire en vectorialisant la fonction, mais bon) Tout les traitements peuvent se faire sur une image en couleur en appliquant à chaque composante. 2 Floutage On va cette fois faire une opération plus globale sur les pixels, sur en plus une image en couleur ! Pour flouter une image, chaque composante d’un pixel sera la moyenne de ses 9 voisins, ou 25 voisins, ou plus. On pose donc un paramètre d pour faire la moyenne des (2d + 1)2 voisins. Pour éviter les problèmes de bord travailler que sur les pixels des positions [d , hauteur − d − 1] × [d , largeur − d − 1]. Comprendre le code suivant, notamment le slicing classe (on peut faire plus simple) : d = 3 flou = mon_bitmap[:,:,:] for i in range(d,hauteur-d): for j in range(d,largeur-d): for k in range(3): test[i,j,k]=np.sum(mon_bitmap[i-d:i+d+1,j-d:j+d+1,k])/(2*d+1)**2 Q.7 Tester (attention c’est long) Dilatation Q.8 On va cette fois faire une transformation globale de l’image en zoomant dans une zone et donc en contractant les pixels dans le reste. L’idée est donc de créer un nouveau tableau clone de même taille, et d’utiliser une fonction de déformation de deux variables f : (x, y) 7→ f (x, y). Chaque pixel (x, y) de clone sera le pixel de coordonnées ( f x (x, y), f y (x, y)) de l’image d’origine. Le choix de f est délicat on doit : - s’assurer qu’on reste bien dans les limites de l’image - réaliser ce que l’on veut : dilater un endroit et contracter un autre. Avec la fonction arctan bien paramétrée on peut réaliser cela. On commence par choisir le centre et le grossissement : x0 = 68 y0 = 158 gross = 4.0 Puis ensuite un code permettant de réaliser la transformation. En jouant sur le centre et le grossissement constater les évolutions de l’image. Je n’insiste pas sur les coefficients et la fonction, mais il est intéressant de vérifier que elle va bien de [0, l ar g eur ]× [0, haut eur ] sur [0, l ar g eur ] × [0, haut eur ]. 3