TP – Image

 

Dans ce TP nous aurons besoin de la bibliothèque Pillow. C’est une bibliothèque permettant de travailler sur les images.

Documentation : https://he-arc.github.io/livre-python/pillow/index.html

Ce n’est pas une bibliothèque standard (contrairement à turtle), cela signifie qu’il faut l’installer…

Pour l’installer lancez cmd.exe (barre de recherche Windows) et tapez la commande suivante : pip install  Pillow

C:\Users\Olivier>pip install Pillow

Maintenant créez un dossier TP_image. Nous travaillerons dans ce dossier.

Dans cette activité, nous allons travailler avec l’image ci-dessous « IMAGE.jpg ».

Télécharger cette image et la copier dans un répertoire « TP_image »

 Lenna

Lenna

Pour en savoir plus sur l’origine de cette photo : https://fr.wikipedia.org/wiki/Lenna

1. Quelques rappels sur les images :

  • Une image est constituée de pixels (points), la définition d’une image L x H (par exemple 330 x 330 pour l’image considérée correspond au nombre de pixels de l’image (L : la largeur de l’image en pixel, H : la hauteur de l’image en pixel).
  • Chaque pixel est constitué de 3 éléments (chacun est appelé aussi canal) : un rouge, un vert et un bleu (RVB). C’est la somme de ces 3 couleurs qui permet d’obtenir un grand nombre de couleurs (synthèse additive).
  • Classiquement, à chaque canal, on associe un nombre binaire codé sur 8 bits (soit donc 24 bits par pixel).
  • Pour chaque pixel, on aura donc une valeur pour le rouge (comprise entre 0 et 255 puisque codé sur 8 bits), une valeur pour le vert (comprise entre 0 et 255) et une valeur pour le bleu (comprise entre 0 et 255).
    Quelques exemples : (0,0,0) => noir ; (255,0,0) => rouge ; (255,255,255) => blanc ; (0,255,0) => vert…

Remarque : Il peut exister un 4e canal en plus du canal rouge, canal vert et canal bleu, le canal « alpha » qui permet de gérer la transparence du pixel (par exemple, les images au format .png gèrent la transparence). Chaque pixel est donc codé sur 32 bits (4 x 8).

 

Partant du principe que l’image que vous avez copiée possède une définition de 508*512, que chaque pixel est constitué de 3 éléments (RVB) chacun codé sur 8 bits = 1 octet, calculez la taille (ou poids) de cette image en kilo octet (ko).
Rappel : 1 ko = 1024 octets ; 1 octet = 8 bits
Si vous regardez la taille réelle de l’image en ko, vous allez sans doute trouver une valeur inférieure à celle que vous venez de calculer. Ceci est tout à fait normal, car le .jpeg est un format compressé (le taux de compression est compris entre 10 : 1 et 25 : 1).
Vous pouvez convertir cette image en .PNG avec « paint » ou « photofiltre » et comparer sa nouvelle taille à la taille précédente.

2. Fonctions de base

  1. La fonction open vous permet d’ouvrir un fichier image
    image = open("IMAGE.jpg")
  2. Saisissez, analysez et testez ce code :
    from PIL.Image import *
    image = open("IMAGE.jpg")
    image.save("resultat.jpg", "JPEG")

    Attention ! Pour que cela fonctionne votre fichier .py doit se trouver dans le même dossier que votre image !

    La ligne « image.save(« resultat.jpg », »JPEG ») » permet de sauvegarder une image. L’image sera sauvegardée dans le dossier courant (le même dossier que « IMAGE.jpg ») et aura pour nom « resultat.jpg ».

  3. La méthode getpixel((x,y)) renvoie un tuple (un tuple ressemble beaucoup à une liste, à l’exception près, qu’un tuple, une fois créé, n’est pas modifiable.) contenant les trois composantes : rouge, verte et bleue du pixel situé aux coordonnées x, y (sachant que le pixel de coordonnées 0, 0 se situe en haut à gauche de l’image).Saisissez, analysez et testez ce code :
    from PIL.Image import *
    image = open("IMAGE.jpg")
    (r,v,b) = image.getpixel((100,100))
    print(r,v,b)

    Si tout se passe correctement, vous devriez avoir à l’écran (dans la console) : (175, 68, 76). Nous pouvons donc affirmer que le pixel de l’image « IMAGE.jpg », ayant pour coordonnées (100, 100), a pour composantes : Rouge=>175 ; Vert=>68 ; Bleu=>76. Encore une chose importante sur les tuples : si vous voulez récupérer une valeur du tuple, cela se passe exactement comme avec les listes. Si vous reprenez l’exemple ci-dessus, tu [0] est égal à 175 et tu [2] est égal à 68. Vous remarquerez que la méthode getpixel prend en paramètre un tuple : (100,100).

  4. Autre fonction très utile : putpixel. Cette méthode permet de modifier les canaux Rouge, Vert et Bleu d’un pixel. La méthode putpixel prend deux paramètres (2 tuples) : le premier paramètre correspond aux coordonnées du pixel que nous voulons modifier (tuple avec 2 éléments : (x, y)). Le second paramètre correspond aux valeurs à attribuer aux canaux R, V, B (tuple avec 3 éléments : (255,255,255), ici un pixel blanc).Saisissez, analysez et testez ce code :
    from PIL.Image import *
    image=open("IMAGE.jpg")
    image.putpixel((312, 444), (0, 0, 255))
    image.save("resultat.jpg", "JPEG")

    Cherchez maintenant le pixel bleu sur l’image. (vers l’épaule 🙂 )

  5. Récupérer la définition d’une photo
    (L,H)= image.size
  6. Redimensionner une photo
    image=image.resize((L,H))

    L et H étant les nouvelles dimensions de « image »

  7. Visualiser une image
    image.show() 

3. Modification d’une photo

Très souvent il est nécessaire de parcourir les pixels d’une image.  Voyons un exemple permettant de transformer tous les pixels en bleu :

from PIL.Image import *
image=open("IMAGE.jpg")
(L,H)= image.size
for i in range(H): # On parcours les lignes de pixels de l'image
    for j in range(L): # On parcours les pixels de la ligne i
        image.putpixel((j, i), (0, 0, 255))
image.save("resultat.jpg", "JPEG")

Le résultat n’est pas très intéressant… Regardons des manipulations plus intéressantes :

1) Écrire et commenter le programme permettant de d’assombrir l’image. (soustraire 50 à chaque canal, par exemple)

2) Écrire et commenter un programme en Python qui permettra de transformer une image couleur en son négatif.

3) Écrire et commenter un programme en Python qui permettra de transformer une image couleur en une image en niveau de gris (souvent improprement appelée « noir et blanc », car une image « noir et blanc » est uniquement composée de pixel noir et de pixel blanc).
Une des façons d’obtenir du gris est de prendre les fractions suivantes pour les composantes RVB : (rouge=0.299 ;
verte=0.587 ; bleue=0.144), la somme faisant 1.

Remarque : en Python, int(x) permet de prendre la valeur entière de x.

4) Transformer une image en sa symétrique par rapport à l’axe de symétrie « vertical » (principal) de la fenêtre graphique.

 

Exemple de mini-projet :  Exemples de mini-projets sur les images numériques