L’objectif de ce TP est de construire un programme qui permet d’effectuer une rotation de 90° sur une image carrée. Pour cela, nous allons utiliser 2 approches différentes :
Pour manipuler les images, nous allons utiliser le module PIL et nous utiliserons l’image lion.jpg
pour effectuer vos tests.
PIL
Le module PIL
permet de manipuler les données des pixels d'une image. Pour l'installer, il faut utiliser la commande apt install pillow
. Pour l'importer dans votre programme, il faut écrire from PIL import *
.
Voici les fonctions que vous devrez utiliser :
Image.open()
Image.getpixel()
Image.putpixel()
Image.save()
Pour davantage de précision, voici une documentation simplifiée du module.
Question 1 - Écrire un programme permettant les actions suivantes :
lion.jpg
dans une variable.Question 2 - Écrire un programme permettant les actions suivantes :
lion.jpg
dans une variable.Question 3 - Écrire un programme permettant les actions suivantes :
lion.jpg
dans une variable.Pixel(50,50)
→ BleuPixel (200,200)
→ RougePixel (150,150)
→ VertPixel (0,0)
→ JauneVoici un schéma représentant la rotation d’une image.
Pour effectuer une rotation de 90°, voici la méthode mathématique.
Un pixel de coordonnées dans une image de taille a pour coordonnées avant rotation d’un quart de tour dans le sens horaire .
Question 1 - Trouver la formule permettant de trouver les coordonnées d'un pixel après rotation.
Question 2 - Écrire la fonction rotation_naive
. Cette fonction prend en paramètre le chemin d'une image. Elle retourne un objet Image
du module PIL
avec une rotation de 90° dans le sens horaire.
Question 3 - Essayer votre fonction avec l'image lion.jpg
et affiche l'image obtenue.
Dans cette partie, on utilisera des images dont la taille est égale à une puissance de 2.
Dans cet algorithme, la méthode « Diviser pour régner » se décompose en 3 parties :
On peut représenter le principe selon le schéma ci-dessous :
Pour concevoir cette méthode, nous allons écrire plusieurs fonctions outils.
Question 4 - Écrire une fonction echange_pixel
. Cette fonction prend en paramètre un objet de type Image
et les coordonnées sources et destination d'un pixel. Elle échange la couleur des pixels de coordonnées (x1,y1)
et (x2,y2)
dans l’image passée en paramètre.
def echange_pixel(image, x1, y1, x2, y2):
"""
:param x1, y1: (int) Coordonnées du pixel 1
:param x2, y2: (int) Coordonnées du pixel 2
:param image : (Image) Objet image du module PIL
"""
Question 5 - Écrire une fonction echange_carre. Cette fonction prend en paramètre un objet de type Image
, les coordonnées sources et destination d'un pixel et une taille de zone.
Cette fonction échange des parties de taille d’une image. Les coordonnées passées en paramètre indiquent les premiers pixels en haut en gauche de chacune des parties de l’image.
Cette fonction utilise la fonction précédente echange_pixel
.
def echange_carre(image, x1, y1, x2, y2, n):
"""
:param x1, y1: (int) Coordonnées du pixel 1
:param x2, y2: (int) Coordonnées du pixel 2
:param image: (Image) Objet image du module PIL
:param n : (int) Taille du carré de pixel
"""
Question 6 - Trouver la suite « d’échanges » (utilisation de la fonction echange_carre
) permet de passer de la 1ère image à la 2ème image, sachant qu’on ne peut échanger que 2 images à la fois.
L’image ci-dessous est de taille . Le premier pixel du carré a pour coordonnées .
Question 7 - Donner les coordonnées du premier pixel des carrés , , en fonction de , et .
Question 8 - Grâce aux questions précédentes et le principe « Diviser pour régner », écrire la fonction récursive rotation
. Cette fonction prend en paramètre le chemin d'une image, les coordonnées du premier pixel en haute à gauche et sa taille.
Cette fonction permet d’effectuer une rotation d’un quart de tour de manière récursive. On utilisera la fonction echange_carre
.
def rotation(image, x0, y0, n):
"""
:param x0, y0: (int) Coordonnées du premier pixel du carré
:param image: (Image) Objet image du module PIL
:param n : (int) Taille du carré
"""