TP : Traitement d'images

Cette activité est très inspirée des activités de Gilles Lassus et Stéphane Colomban.

Travail préparatoire

  1. Installez la bibliothèque Pillow.
  2. Téléchargez dans un même dossier (par exemple snt/photo/traitement les fichiers traitement-d-image.py et gere.jpg.
  3. Ouvrez le fichier traitement-d-image.py avec Thonny, exécutez-le, choisissez la photo gere.jpg puis l'action Symétrie haut-bas, et vérifiez que la symétrie a bien été effectuée.
  4. Complétez le programme pour mettre en œuvre autant des algorithmes suivants que possible. Réalisez-les dans l'ordre de votre choix, sachant qu'ils sont à peu près classés par ordre de difficulté croissant.
  5. Une fois votre travail terminé, déposez-le sur Pronote.

Explication du code

Chaque action (algorithme de traitement d'image) est défini dans une fonction, ressemblant à la fonction suivante.

def action_eclaircir(nom):
    """Éclaircit l'image"""
    source = Image.open(nom).convert('RGB')
    largeur = source.width
    hauteur = source.height
    dest  = Image.new('RGB', (largeur, hauteur))

    for x in range(largeur):
        for y in range(hauteur):
            rouge, vert, bleu = source.getpixel((x, y))
            dest.putpixel(
                    (x, y),
                    (0, 0, 0), # À compléter avec la couleur du pixel
                )

    dest.save("eclaircie.png")
    dest.show()

Dans les premières lignes (de source = … à dest = …), le programme lit le fichier source, lit la largeur et la hauteur de l'image (nous en auront besoin pour certains des algorithmes), et prépare l'image de destinantion. Vient ensuite la double boucle :

for x in range(largeur):
    for y in range(hauteur):
        rouge, vert, bleu = source.getpixel((x, y))
        dest.putpixel(
                (x, y),
                (0, 0, 0), # À compléter avec la couleur du pixel
            )

Dans cette double boucle, les variables x et y prennent successivement les coordonnées de tous les pixels de l'image source. Ensuite, les couleurs d'un pixel (sous la forme de trois nombres rouge, vert, bleu) sont lues avec la fonction source.getpixel(), puis un pixel est écrit avec la fonction dest.putpixel(). Cette fonction prend deux arguments : les coordonnées du pixel à écrire, et les couleurs du nouveau pixel.

Algorithmes

Voici les algorithmes que vous pouvez mettre en œuvre. Si vous avez d'autres idées, n'hésitez pas !

Extraire les trames verte et bleue

Ces deux actions sont définies dans les fonctions action_trame_verte() et action_trame_bleue().

Pour extraire la trame verte, les quantités de rouge et bleu sont mises à 0, alors que la quantité de vert est recopiée. Inspirez-vous de l'action action_trame_rouge(), qui fonctionne déjà.

Permuter les couleurs

Cette action est définie dans la fonction action_permuter().

Pour une couleur de départ (rouge, vert, bleu), la couleur d'arrivée sera (par exemple) (vert, bleu, rouge).

Assombrir l'image

Cette action est définie dans la fonction action_assombrir().

Pour assombrir une image, les couleurs de chaque pixel vont être rapprochées du noir (0, 0, 0). Pour cela, le nombre de chaque couleur va être divisé par 2. Attention : pour faire la division, utiliser l'opérateur // plutôt que /.

Convertir l'image en niveaux de gris.

Cette action est définie dans la fonction action_niveaux_de_gris().

Les trois couleurs de chaque pixel de l'image finale sont égale à la moyenne des trois couleurs de l'image initiale.

Inverser les couleurs

Cette action est définie dans la fonction action_inverse().

Pour chacune des trois couleurs, 0 devient 255, 1 devient 254, 2 devient 253, etc. À quelle opération cela correspond-il ?

Effectuer la symérie gauche-droite

Cette action est définie dans la fonction action_symetrie_gauchedroite().

Pour écrire cette fonction, adapter la fonction action_symetrie_hautbas().

Éclaircir l'image

Cette action est définie dans la fonction action_eclaircir().

C'est le même principe que pour assombrir l'image, sauf que les couleurs devront être rapprochées du blanc (255, 255, 255) au lieu du noir. Quelle opération faut-il alors effectuer ?

Pivoter l'image de 90° vers la gauche

Cette action est définie dans la fonction action_rotation90().

Les couleurs ne sont pas modifiées, mais il faut calculer à quel endroit le pixel d'origine doit être repositionné. Faites un schéma au brouillon pour vous aider.

Couleurs bizarres

Cette action est définie dans la fonction action_bizarre().

Ici, la nouvelle couleur est définie à partir de calculs sur la couleur de départ. Par exemple, la nouvelle quantité de rouge sera : rouge + 100, rouge - bleu, rouge * vert, bleu**2 / rouge, etc. Cela devrait produire une image aux couleurs apparemment aléatoires, mais dans laquelle l'image de départ est tout de même reconnaissable.

Attention ! Le résultat de nos calcul peut être n'importe quel nombre (négatif, plus grand que 256, à virgule, etc.), alors que seuls sont acceptés les nombres entiers compris entre 0 et 255. Pour remédier cela, nos calculs vont être entourés de la fonction round() (qui arrondit le nombre à l'entier le plus proche) et de % 256 (qui s'assure que le résultat est compris entre 0 et 255, par exemple : round(rouge * vert) % 256.