Version 2025-06
Licence CC–BY–NC–ND
TRANSFORMATION D'IMAGES
Christophe Schlick
schlick ಄ u-bordeaux • fr
L'objectif de cette feuille d'exercices est d'illustrer le principe de la transformation d'images par algorithmes. Les algorithmes de génération (présentés dans la feuille d'exercices A) permettent de créer une image en fonction d'un ensemble de paramètres numériques fournis par l'utilisateur, et destinés à contrôler le processus de création. A l'inverse, les algorithmes de transformation (présentés dans ce notebook) doivent impérativement partir d'une image existante qui servira de base pour la création de la nouvelle image. Il existe aujourd'hui un très grand catalogue d'algorithmes de transformations d'images permettant d'obtenir des effets visuels extrêmement variés, mais toutes ces techniques peuvent être classés en trois catégories principales :
- Transformations géométriques : La transformation appliquée à un pixel ne dépend que de sa position
- Transformations optiques : La transformation appliquée à un pixel ne dépend que de sa couleur
- Transformations par filtre : La transformation appliquée à un pixel dépend de sa position, de sa couleur, ainsi que des positions et des couleurs des pixels de son voisinage
Le package numpy pourrait évidemment être largement suffisant pour réaliser toutes les transformations d'images abordées dans cette feuille d'exercices. Néanmoins, le package Pillow fournit des outils de plus haut niveau, ce qui va grandement simplifier la plupart des opérations à mettre en oeuvre. Avant de commencer cette feuille d'exercices, il est donc fortement recommandé de relire le notebook 06-Pillow.ipynb qui contient les éléments de cours correspondants.
import numpy as np # import du package 'numpy' avec alias 'np'
import PIL.Image as pim # import du module 'Image' du package 'Pillow' avec alias 'pim'
import PIL.ImageOps as pio # idem avec module 'ImageOps'
import PIL.ImageChops as pic # idem avec module 'ImageChops'
import PIL.ImageFilter as pif # idem avec module 'ImageFilter'
import PIL.ImageDraw as pid # idem avec module 'ImageDraw'
from SRC.tools import show, view # import de deux fonctions du module 'tools'
import warnings; warnings.filterwarnings('ignore') # on ignore les 'warnings'
Exercice C1 - Transformations géométriques
Ecrire les instructions Python permettant de générer les 8 images de la figure ci-dessous. Chaque image individuelle est obtenue en appliquant une transformation géométrique sur l'image du tigre utilisée dans le chapitre 6 du cours (la zone noire visible sur certaines images correspond à la taille initiale de l'image, soit 640x480 pixels). Les transformations mises en oeuvre pour les 8 images (de gauche à droite et de haut en bas) sont les suivantes :
- double symétrie (verticale et horizontale)
- contraction horizontale à 50%
- contraction uniforme à 50%
- dilatation uniforme à 1600% (+ recadrage autour de l'oeil droit du tigre)
- rotation de 15° (sans modification de la taille de l'image finale)
- rotation de 15° (avec ajustement de la taille de l'image finale)
- cisaillement horizontal
- déformation projective
Vous aurez besoin des méthodes suivantes, définies pour la classe pim.Image utilisée par Pillow (à vous de trouver le rôle de chaque méthode et celui de leurs paramètres) :
img.transpose(method)img.resize(size, method)img.crop(box)img.rotate(angle, expand)img.transform(size, method, data)

tiger = pim.open('IMG/tiger.jpg') # lecture du fichier 'tiger.jpg' (mode = 'RGB')
img = tiger.copy() # création d'une copie de travail à partir de 'tiger'
# TODO
view(img) # affichage de l'image finale
Exercice C2 - Découpages et collages
Ecrire les instructions Python permettant de générer les 8 images de la figure ci-dessous. Chaque image individuelle est obtenue en appliquant une transformation géométrique, de type découpage et/ou collage, sur les images du tigre et du smiley. Les transformations mises en oeuvre pour les images (de gauche à droite et de haut en bas) sont les suivantes :
- collage périodique d'un rectangle noir
- extraction de la partie gauche de l'image, puis collage avec symétrie horizontale
- extraction de la tête du tigre, puis collage périodique horizontal et vertical
- collages multiples avec redimensionnement et rotation
- découpage de l'image en 12 blocs de 160x160 pixels, puis collage avec permutation aléatoire des blocs
- incrustation d'un smiley au niveau de l'oeil droit du tigre
- incrustation de 25 smileys avec des positions aléatoires sur l'image
- incrustation de 12 smileys, avec des positions aléatoires dans des blocs de 160x160 pixels
En plus des méthodes de l'exercice C1, vous aurez besoin des méthodes suivantes :
img.new(mode, size, color)img.paste(image, coords)

tiger = pim.open('IMG/tiger.jpg') # lecture du fichier 'tiger.jpg' (mode = 'RGB')
img = tiger.copy() # création d'une copie de travail à partir de 'tiger'
# TODO
view(img) # affichage de l'image finale
Exercice C3 - Transformations optiques
Ecrire les instructions Python permettant de générer les 8 images de la figure ci-dessous. Chaque image individuelle est obtenue en appliquant une transformation optique (sur les canaux R/G/B) sur l'image du tigre utilisée dans le chapitre 6 du cours. En plus des méthodes de l'exercice C1, vous aurez besoin des méthodes suivantes :
Ecrire les instructions Python permettant de générer les 8 images de la figure ci-dessous. Chaque image individuelle est obtenue en appliquant une transformation géométrique, de type découpage et/ou collage, sur les images du tigre et du smiley utilisées dans le chapitre 6 du cours. Les transformations mises en oeuvre pour les 8 images (de gauche à droite et de haut en bas) sont les suivantes :
- échange des canaux R et B
- combinaison linéaire des canaux RGB : $R' = 0.6R + 0.4G\;, G' = 0.2R + 0.8B\;, B' = B$
- combinaison barycentrique des canaux RGB : $L = 0.299R + 0.587G + 0.114B$
- inversion de l'image de luminance
- binarisation des valeurs de luminance
- binarisation des valeurs RGB
- quantification de la luminance sur 5 niveaux
- ajout de bruit puis quantification des valeurs RGB sur 3 niveaux
- assombrissement de l'image RGB
- éclaircissement de l'image de luminance
- augmentation du contraste de l'image RGB
- diminution du contraste de l'image de luminance
Toutes les transformations demandées peuvent s'effectuer en manipulant les images sous forme de matrice numpy

tiger = pim.open('IMG/tiger.jpg') # lecture du fichier 'tiger.jpg' (mode = 'RGB')
img = tiger.copy() # création d'une copie de travail à partir de 'tiger'
# TODO
view(img) # affichage de l'image finale
# définition des deux versions de 'gain' (augmentation ou diminution de luminance)
expo_gain = lambda t,p: t**((1-p)/(1+p))
ratio_gain = lambda t,p: (t+p*t)/(1-p+2*p*t)
# définition des deux versions de 'bias' (augmentation ou diminution de contraste)
expo_bias = lambda t,p: np.where(t < 0.5, 0.5*(2*t)**((1+p)/(1-p)), 1-0.5*(2-2*t)**((1+p)/(1-p)))
ratio_bias = lambda t,p: np.where(t < 0.5, (t-p*t)/(1+p-4*p*t), (t-2*p+3*p*t)/(1-3*p+4*p*t))
# note : le tracé des 4 fonctions pour différentes valeurs de 'p' se trouve sur la figure ci-dessous

Exercice C4 - Filtres et convolutions
Ecrire les instructions Python permettant de générer les 8 images de la figure ci-dessous. Chaque image individuelle est obtenue en appliquant un filtre ou un noyau de convolution sur l'image du tigre. Selon les transformations à générer, on pourra utiliser soit les fonctions de Pillow, soit les fonctions de numpy. Les transformations mises en oeuvre pour les 8 images (de gauche à droite et de haut en bas) sont les suivantes :
- conservation d'un seul canal de couleur (R en haut, G au milieu, B en bas)
- coloration de l'image de luminance avec dégradé bleu vers orange
- pixelisation de l'image (blocs de 16x16 pixels)
- application d'un masque circulaire sur l'image
- test de quelques filtres prédéfinis (par exemple, rehaussement des contours)
- application d'un flou gaussien sur les yeux du tigre
- utilisation d'une combinaison de filtres (par exemple, détection des contours et soustraction)
- composition entre l'image initiale et sa version monochrome floutée, en fonction d'un masque circulaire

tiger = pim.open('IMG/tiger.jpg') # lecture du fichier 'tiger.jpg' (mode = 'RGB')
img = tiger.copy() # création d'une copie de travail à partir de 'tiger'
# TODO
view(img) # affichage de l'image finale