Consignes

La note ne valide pas seulement le résultat de votre programme, mais également son style :

Vérifiez ces points avant de demander à votre intervenant de valider votre code.

Liens utiles

Attention : les formats d'image utilisés dans ce TP (plain PBM, plain PGM et plain PPM) ne sont pas reconnus nativement par Windows XP. Pour visualiser vos images sous Windows, vous pouvez installer de petit utilitaire IrfanView téléchargeable localement ici.

Si vous utilisez Linux les images devraient être reconnues automatiquement.

1. Préliminaires

Nous allons utiliser une petite bibliothèque afin de manipuler des images (au format .ppm) comme des tableaux de pixels. N'oubliez pas de commencer par télécharger

Le code pour cette question (fonction jeDecouvreLaBibliothequeImage) est fourni.

  1. Décommentez les lignes progressivement et exécutez le code. Le but est de comprendre les fonctionalités de la bibliothèque image.py.

  2. Utilisez un éditeur de texte pour ouvrir le fichier question-1.ppm généré par la fonction de test, et vérifiez que les 2 premiers pixels de l'image sont corrects.

Pour tester votre code, il suffit de lancer votre programme avec Python (menu Run puis Run Module dans Idle, ou touche F5).

Par défaut, la fonction de test pour la question 1 sera lancée. Pour tester les autres questions, il faudra décommenter les lignes pertinentes à la fin du ficher...

2. Passage en noir et blanc

Le plus simple pour passer une image en noir et blanc est passer les pixels clairs en blanc, et les pixels foncés en noir. On prend la convention qu'un pixel est

Complétez la fonction imageBinaire qui transforme une image couleur en une image en noir ou blanc. C'est-à-dire que chaque pixel devient soit noir, soit blanc.

Si vous utilisez la fonction de test, vous devriez obtenir le résultat suivant :

TP1/moulin.jpg TP1/question-2.jpg
image originale image en noir et blanc

3. Passage en niveaux de gris

Les images uniquement en noir et blanc sont très "pixélisées". Il est beaucoup mieux d'utiliser plusieurs niveaux de gris (blanc, gris, noir) pour obtenir un meilleur résultat.

Par analogie à la distance euclidienne dans l'espace, on définit la distance entre deux couleurs (r1 , g1 , b1) et (r2 , g2 , b2) comme la racine carrée de (r1 - r2)2 + (g1 - g2)2 + (b1 - b2)2.

Complétez la fonction couleurDiff qui renvoie un entier indiquant à quel point deux couleurs sont différentes.

Une distance de 0 indique que les deux couleurs sont identiques ; et plus la valeur retournée est grande, plus les couleurs sont différentes. (Cette différence est simplement le carré de la distance entre les deux couleurs...)

Par exemple :

>>> couleurDiff( (0,0,0), (255,255,255) )
195075
>>> couleurDiff( (0,123,57), (22,45,58) )
6569

Complétez la fonction troisNuancesDeGris qui transforme une image couleur en une image en noir / gris / blanc.

Chaque pixel devient soit noir, soit gris, soit blanc.

Conseil : pour chaque pixel, calculez d'abord sa distance aux trois couleurs noir, gris et blanc, et choisissez la plus proche (c'est à dire la moins différente)...

Après exécution de la fonction de test, vous devriez obtenir le résultat suivant :

TP1/moulin.jpg TP1/question-4.jpg
image originale image en noir, gris et blanc

4. Simplifier les couleurs

On peut augmenter le nombre de niveaux de gris, ou choisir d'autre couleurs pour limiter la palette utilisée. Il faut pour ceci choisir, pour chaque pixel, la couleur la plus proche parmi celles autorisées.

Complétez la fonction plusSemblable qui détermine, parmi une liste de couleurs, laquelle ressemble le plus à une couleur donnée.

Complétez la fonction repeindre qui transforme une image en une image où chaque pixel est remplacé par la couleur qui lui ressemble le plus parmi la liste de couleurs donnée en argument.

Attention : cette fois-ci, le premier paramètre de la fonction repeindre est une variable de type Image et non une chaine de caractère indiquant le nom du fichier.

Par exemple, la fonction de test utilise la fonction repeindre avec la liste [ (0,0,0) , (127,127,127), (255,255,255) ], qui doit donc produire le même résultat que la fonction troisNuancesDeGris. L'autre liste utilisée doit fournir le résultat suivant :

TP1/fruits.jpg TP1/question-6b.jpg
image originale [blanc, noir, rouge, vert, bleu, jaune, gris, vertpomme]

Pour obtenir une image ne contenant que du gris, il faut utiliser une liste de gris d'intensités croissante.

Écrivez la fonction genKGris qui permet de générer une liste de k teintes de gris. Par exemple

>>> genKgris(2)
[(0, 0, 0), (255, 255, 255)]
>>> genKgris(3)
[(0, 0, 0), (127, 127, 127), (255, 255, 255)]
>>> genKgris(4)
[(0, 0, 0), (85, 85, 85), (170, 170, 170), (255, 255, 255)]

La fonction de test utilisera la fonction repeindre pour transformer l'image de départ avec 16 niveaux de gris. Vous devriez obtenir

TP1/moulin.jpg TP1/question-7.jpg
image originale 16 niveaux de gris

5. Effets : repeindre des morceaux d'image

Un prédicat est une fonction qui teste si un objet possède une propriété.

Dans le cadre de ce TP, on appellera prédicat une fonction qui prend en entrée deux coordonnées x et y et retourne un booléen indiquant si le pixel (x,y) satisfait un certain critère.

Le but de cet exercice est de reprendre le code de la fonction repeindre pour qu'il ne traite que les pixels satisfaisant un prédicat. On pourra ainsi repeindre seulement un dique au milieu de l'image.

Le prédicat sera passé en argument à la fonction repeindreSi dont vous devez écrire le code.

En Python, il est possible de donner des fonctions comme arguments d'autre fonctions :

def afficheResultat( x, fct ) :
    y = fct(x)
    print("le résultat de la fonction sur", x, "est", y)

def f( x ) :
    return 2*x

def g( x ) :
    return -x

donnera

>>> afficheResultat(1, f)
le résultat de la fonction sur 1 est 2
>>> afficheResultat(1, g)
le résultat de la fonction sur 1 est -1
>>> afficheResultat(12, f)
le résultat de la fonction sur 12 est 24
>>> afficheResultat(123, g)
le résultat de la fonction sur 123 est -123

Voici les images générées par la fonction de test :

TP1/question-8a.jpg TP1/question-8b.jpg
question-8a.jpg question-8b.jpg

Complétez la fonction faireNBandes qui utilise les fonctions précédentes pour tranformer une image en n bandes verticales telles que :

La fonction de test devrait produire les images suivantes :

TP1/vague.jpg
image originale
TP1/question-9a.jpg
3 bandes
TP1/question-9b.jpg
10 bandes