C11.4 : TD Rotation d'une image d'un quart de tour

Présentation

But du TP

Dans ce TD, on souhaite coder et comparer deux algorithmes qui permettent de faire tourner une image d'un quart de tour :

Dans toute l'activité, on travaillera avec une image carrée dont le côté contient un nombre de pixels égal à une puissance de 2.

Deux stratégies sont envisageable : la modification en place de l'image ou la création d'une nouvelle image. On choisi la modification en place de l'image.

Voici deux images carrées de 512 pixels de côté :

La librairie PIL

La classe Image

• La librairie PIL permet de disposer d'une classe Image.

Image.open(chemin_fichier) permet de créer une instance de la classe Image à partir d'un fichier.

obj_img.save(chemin_fichier, extension) permet d'enregistrer un fichier à partir l'instance obj_img de la classe Image.

=> Exemple :

from PIL import Image
obj_img = Image.open("chat.png")
obj_img.save('chat_copie.png','png')

Quelques méthodes de base de la classe Image

size permet de récupérer un tuple contenant la largeur et la hauteur de l'image

width et height renvoient respectivement la largeur et la hauteur de l'image

=> Exemple :

from PIL import Image
obj_img = Image.open("chat.png")
largeur, hauteur = obj_img.size

Jouer avec les pixels

• Les coordonnées des pixels sont repérés de la façon suivante :

• Les couleurs des pixels sont des tuples RGB avec des entiers entre 0 et 255.

• Méthodes de la classe Image :

Jouer avec des morceaux d'images

sous_obj_img = obj_img.crop((g,h,d,b)) permet de créer l'instance sous_obj_img de objet_image à partir de la zone comprise entre les pixels (g, h) et (d, b).

obj_img.paste((x,y), sous_obj_img) permet de coller sous_obj_img dans obj_img en faisant coïncider l'angle supérieur gauche de sous_obj_img avec le pixel (x,y) de obj_img.

Algorithme avec déplacement direct des pixels

Écrire un programme qui permet de tourner une image carrée d'un quart de tour en déplaçant, successivement, tous les pixels quadrant par quadrant comme le montre l'image ci-dessous.

Algorithme diviser pour régner

Avec une approche "diviser pour régner", on peut imaginer l'algorithme suivant :

Écrire un programme récursif qui permet de tourner une image carrée d'un quart de tour en se basant sur l'approche "diviser pour régner".

On observera que la rotation d'une image de 1 pixel de côté correspond à ne rien faire.

def rotation(obj_img):
    n = obj_img.width
    if ...:  # condition d'arrêt
        pass # cas de base : rien à faire
    else:
        # Diviser : découper l'image

        # Régner (récursivement)

        # Combiner : déplacement des blocs

            

Comparaison de l'efficacité des deux algorithmes

1) Déterminer le nombre de fois que chaque pixel est déplacé dans l'algorithme du II.

2) Déterminer le nombre de fois que chaque pixel est déplacé dans l'algorithme du III.

3) Conclure.