10.1- TP - Traitement d'image
Ce travail a pour objectif la programmation de plusieurs algorithmes de traitement d'images.
Vous allez travailler sur des images en niveaux de gris qui seront des listes de listes d'entiers compris entre 0 et 255.
La première cellule de code utilise la bibliothèque PIL pour charger trois images qui vous serviront de tests. Ces images au format PIL sont converties en liste de listes, donc vous n'avez pas à vous préoccuper du fonctionnement de la librairie.
Pour afficher ces images vous utiliserez la fonction imshow définie dans cette première cellule.
Vous devrez donc toujours exécuter cette cellule au début de votre travail.
Loading editor...
imshow(guepiers)
I. Préliminaires
Q1
Compléter la fonction dim, qui prend en argument une image et renvoie le couple d'entiers (h, w), w étant la
largeur de l'image, et h sa hauteur (en nombre de pixels).
On pourra ainsi dans la suite utiliser (h, w) = dim(img) pour récupérer les dimensions d'une image.
Loading editor...
def dim(image) :
...Dans la plupart des questions suivantes, on vous demandera d'écrire une fonction qui réalise une opération sur une image. Vous ne devez pas modifier les images originelles (par exemple "guepiers"). Si vous avez besoin de réaliser la copie d'une image, vous pouvez utiliser la ligne suivante :
copie = [[pixel for pixel in ligne] for ligne in image] Q2
Écrivez une fonction inverse(image) qui renvoie l'image avec son contraste inversé (un pixel blanc doit devenir noir, et vice-versa).
Loading editor...
II. Les convolutions
Beaucoup d'opérations de traitement d'images utilisent des convolutions. C'est une opération très générale, qui consiste à appliquer un "filtre" à une image.
Chaque pixel de sortie est la somme des 9 pixels autour, multipliés par les coefficients du filtre.
On se donne une image, et un filtre (qui est une matrice 3x3 dans notre cas). Chaque pixel de l'image de sortie est la somme des 9 pixels qui l'entourent, multipliés par les cofficients contenus dans le filtre.
Pour vous aider à visualiser cette opération, vous pouvez utiliser ce site.
On va s'intérésser à la réalisation d'une fonction permettant de réaliser une convolution.
Q3
Écrivez une fonction filtre_un_pixel(image, filtre, y, x) qui applique le filtre à l'image à la position (y, x), et renvoie le pixel résultat. On suppose
On veut ainsi renvoyer la somme :
image[y-1][x-1]*filtre[0][0] + image[y-1][x]*filtre[0][1] + image[y-1][x+1]*filtre[0][2] +
image[y][x-1]*filtre[1][0] + ...
... + image[y+1][x+1]*filtre[2][2]
NB : écrire la somme en entier fonctionne, mais mieux vaut utiliser des boucles...
Loading editor...
Q4
En déduire une fonction convolution(image, filtre) qui renvoie la convolution de l'image par le filtre. Vous pouvez ignorer les bords (en enlevant les premières lignes et colonnes, ou bien en mettant des pixels noirs).
Loading editor...
Q5
Appliquer les filtres suivants sur les images donnés, et décrivez leur effet en une phrase.
Filtre 1 :
Loading editor...
Filtre 2 :
Loading editor...
Filtre 3 :
Loading editor...
III. Réduction d'image
Dans cette partie, on va essayer de réduire des images dans le sens de la largeur.
A. Réduction naïve de moitié
Q6
Écrire une fonction reduction_moitie_ligne, qui prend
en argument une liste de longueur paire
Loading editor...
Q7
Écrire une fonction reduction_moitie_image, qui prend
en argument une image (ayant une largeur paire) et en construit une nouvelle en appliquant à chaque ligne
l'opération décrite dans la question précédente.
Loading editor...
Q8
Quelle est sa complexité en fonction du nombre de lignes
Testez, et constatez la déformation obtenue. (Justifier la complexité)
Loading editor...
# tests
B. Calcul de l'énergie d'un pixel
Si l'on note
Cette quantité est d'autant plus petite que le pixel est dans une zone uniforme de l'image, et d'autant plus grande qu'il est dans une zone de forte variation du niveau de gris (par exemple au niveau d'un contour).
Il s'agit en fait d'une version discrétisée de
Q9
- Complétez la fonction
energie, qui prend en argument une image, et renvoie une nouvelle image correspondant à son énergie (les pixels n'auront plus nécessairement une valeur entière).
On réfléchira en particulier à comment adapter la formule ci-dessus à un pixel situé sur un bord de l'image. - Testez, et affichez l'image des énergies obtenue.
Loading editor...
def energie(img):
'''Calcule l'énergie d'une image img.'''
(h, w) = dim(img)
return eLoading editor...
C. Deux algorithmes
Nous disposons d'une image et de son énergie.
Nous allons programmer deux algorithmes pour réduire l'image en utilisant l'énergie
- Pour réduire la largeur d'une image d'un pixel, nous allons simplement enlever un pixel d'énergie minimale dans chaque ligne.
- Pour réduire la largeur d'une image d'un pixel, nous allons supprimer la colonne de moindre énergie
Q10
Écrire une fonction indice_min qui renvoie l'indice de la valeur minimale d'une liste.
Loading editor...
def indice_min(L):
...Loading editor...
Q11
Écrire une fonction enlever, qui prend en argument une liste L et un indice i compris entre 0 et la longueur de L moins 1, et renvoie une nouvelle liste correspondant à L dont l'élément d'indice i a été supprimé. On pourra utiliser des extractions de tranches et concaténations de listes.
Loading editor...
def enlever(L, i):
...Loading editor...
Q12
Écrire le code de la fonction reduction_par_ligne, qui prend en arguments une image img et son énergie, et la modifie en supprimant un pixel d'énergie minimale dans chacune de ses lignes.
Votre fonction devra aussi enlever le pixel correspondant du tableau énergie.
Loading editor...
def reduction_par_ligne(img, e):
...Loading editor...
Q13
Écrire le code de itere_reduction_par_ligne, qui prend en arguments une image img et un entier img. On ne veut calculer l'energie qu'une seule fois au total !
Loading editor...
def iterer_reduction_par_ligne(img, n):
...Loading editor...
Q14
- Quelle est sa complexité?
- La tester. (On pourra par exemple réduire de 100 pixels la largeur de l'image
flamants: au-delà, le calcul risque de dépasser la limite de 15 secondes.) - Expliquez les distorsions observées.
Loading editor...
# tests
Question 15 : Programmation de l'algorithme 2
L'énergie d'une colonne est la somme des énergies des pixels de la colonne.
- Écrire une fonction
meilleure_colonnequi renvoie l'indice de la colonne d'énergie minimale d'une image. - Écrire le code de
itere_reduction_colonne, qui prend en arguments une imageimget un entier , et supprime n fois la colonne d'energie minimale. Votre fonction devra calculer une seule fois l'energie. - Testez, et expliquez qualitativement pourquoi les résultats obtenus sont «bons» sur les images
guepiersetflamants, mais pas surrue.
Loading editor...
def meilleure_colonne(img, e):
passLoading editor...
Loading editor...
def itere_reduction_colonne(img, n):
passLoading editor...
#tests
Entrez le code donné en cours pour accéder à la solution :