Ceci est une ancienne révision du document !
L'objectif de ce TP est d'opérer des transformations sur une image, en manipulant les valeurs de pixels.
Rappelons au passage qu'une image en “couleurs vraies” et sans transparence est composée d'un mélange de rouge, de vert et de bleu (les trois composantes sont stockées dans cet ordre). La valeur de chaque composante est donnée par un nombre entier codé sur un octet (un nombre entre 0 et 255). Le mélange des couleurs se fait par synthèse additive : (rouge + vert) ⇒ jaune.
Commencez par choisir l'image sur laquelle vous allez travailler parmi celle qui sont proposées en lien ici :
Modifiez cette image de manière à obtenir finalement une image carrée de taille 256×256, non déformée, comportant éventuellement une partie seulement de l'image de départ choisie. Avec un logiciel de dessin, signez cette image, de manière visible, lisible (on doit reconnaître votre nom) et pas trop intrusive. Demandez conseil si vous n'êtes pas sûr de vous.
À partir de cette image, vous devrez en produire des versions modifiées, toujours avec la même résolution (256×256).
Toutes les images que vous utiliserez, et que vous rendrez doivent être au format PNG (attention, avoir l'extension .png ne signifie pas que le format est nécessairement PNG). Modifier l'extension ne change pas le format du fichier.
Une documentation est accessible pour vous expliquer comment manipuler et afficher des images : Travailler avec des images en Python.
Il existe plusieurs façons de procéder, chacune ayant ses avantages et ses inconvénients. Dans
ce TP, nous conseillons d'utiliser le module imageio
pour charger les images et ImageWindow
pour les afficher et faire une petite interface graphique.
L'utilisation de Pillow
pour charger les images, matplotlib
pour les afficher est aussi envisageable (mais déconseillée pour ce TP).
Voici un programme de départ utilisant imageio
et ImageWindow
. Il charge l'image nommée
img.png
et attend. Lorsque vous appuyez sur la touche Espace, un point rouge apparaît au centre de l'image.
from ImageWindow import Visu import imageio def pouet(img): mx, my = img.shape[1] // 2, img.shape[0] // 2 # On fait une copie de l'image img2 = img.copy() # On ajouter le point rouge img2[my, mx] = (255, 0, 0) return img2 def clavier(t): if t == ' ': # Si la touche appuyée est espace img2 = pouet(gimg) # Calculer l'image avec point rouge gwin.setImage(img2) # L'afficher dans la fenêtre return False gwin = Visu() # Création de la fenêtre gimg = imageio.imread("img.png") # Chargement d'une image avec imageio gimg = gimg[:,:,:3] # On enlève l'éventuel canal alpha gwin.setImage(gimg) # Affiche l'image chargée dans la fenêtre gwin.register("keyboard",clavier) # Appelle la fonction 'clavier' si on appuie sur une touche # Pas nécessaire depuis un shell interactif comme IEP (pyzo), mais # il faut le mettre dans une appli indépendante. # gwin.run()
Le parti pris, dans l'exemple qui précède est de ne pas modifier l'image d'origine, mais de créer une nouvelle image. L'avantage est qu'on peut alors tester plusieurs transformations toujours à partir de l'image d'origine. L'inconvénient est qu'on ne peut pas appliquer plusieurs transformations à la fois.
Vous pouvez réfléchir à un moyen de lever ces limitations.
S'il y a des choses que vous ne comprenez pas dans l'exemple qui précède, n'hésitez pas à demander.
Votre programme devra se nommer login_images.py
(où login
est votre login)
Votre programme doit comporter une fonction différente pour chaque transformation mentionnée ci-dessous.
imageio
contient une fonction imageio.imsave
qui permet d'enregistrer une image. Utilisez l'aide pour savoir comment vous en servir.: un pixel bleu deviendra rouge, un pixel rouge deviendra vert et un pixel vert deviendra bleu) |
![]() | ![]() |
Image assombrie, chaque composante est divisée par 4 | Image en négatif (inverse vidéo) |
![]() | ![]() |
Image «quantifiée», chaque composante ne peut prendre que 8 valeurs différentes, régulièrement réparties | Image floue, chaque point est obtenue en faisant la moyenne des valeurs de pixels dans un carré 5×5 centré en i,j |
![]() | ![]() |
Miroir vertical | Détection de contour (ici : Filtre_de_Sobel) |
Dans le cas de la détection de contours, vous n'êtes pas obligés de programmer le filtre de Sobel. Mais dans tous les cas, vous devez expliquer la méthode que vous aurez employée.
Parmi les transformations précédentes, certaines sont sujettes à de la perte d'information et d'autres non. Indiquez quelles sont les transformations qui perdent de l'information et quelles sont les transformations qui n'en perdent pas. Justifiez.