L'objectif de ce TP est d'opérer des transformations sur une image, en manipulant les valeurs de pixels.
Rappelons au passage qu'une image en “couleurs vraies” et sans transparence est composée d'un mélange de rouge, de vert et de bleu (les trois composantes sont stockées dans cet ordre). La valeur de chaque composante est donnée par un nombre entier codé sur un octet (un nombre entre 0 et 255). Le mélange des couleurs se fait par synthèse additive : (rouge + vert) => jaune.
Commencez par choisir l'image sur laquelle vous allez travailler parmi celle qui sont proposées en lien ici. Si possible, choisissez une zone de l'image où on distingue au moins 2 composantes.
Modifiez cette image de manière à obtenir finalement une image carrée de taille 256x256, non déformée, comportant éventuellement une partie seulement de l'image de départ choisie. Avec un logiciel de dessin, signez cette image, de manière visible, lisible (on doit reconnaître votre nom) et pas trop intrusive. Demandez conseil si vous n'êtes pas sûr de vous.
À partir de cette image, vous devrez en produire des versions modifiées, toujours avec la même résolution (256×256).
Toutes les images que vous utiliserez, et que vous rendrez doivent être au format PNG (attention, avoir l'extension .png ne signifie pas que le format est nécessairement PNG). Modifier l'extension ne change pas le format du fichier.
Une documentation est accessible pour vous expliquer comment manipuler et afficher des images : Travailler avec des images en Python.
Il existe plusieurs façons de procéder, chacune ayant ses avantages et ses inconvénients. Nous conseillons ici d'utiliser PIL et matplotlib pour charger et afficher les images. La méthode est détaillée dans le document cité plus haut.
Votre programme devra se nommer login_images.py
(où login
est votre login)
Votre programme doit comporter une fonction différente pour chaque transformation mentionnée ci-dessous. Chaque fonction doit prendre une image en paramètres (plus d'autres paramètres si vous en avez besoin) et renvoyer une image.
imageio
contient une fonction imageio.imsave
qui permet d'enregistrer une image. Utilisez l'aide pour savoir comment vous en servir.Par ordre de difficulté :
| {{arles.png}} | |
Parmi les transformations précédentes, certaines sont sujettes à de la perte d'information et d'autres non. Indiquez quelles sont les transformations qui perdent de l'information et quelles sont les transformations qui n'en perdent pas. Justifiez.
Il existe plusieurs [[https://fr.wikipedia.org/wiki/Espace_de_couleur|espaces de couleur]] pour représenter les couleurs des images.
en degrés dont la valeur est comprise entre 0 et 360 et représente la teinte, Value et Saturation sont des valeurs numériques comprises entre 0 et 1 et représentent respectivement la brillance (0 pour Value donne du noir) et l'intensité (lorsque Saturation diminue, la couleur devient fade)
Un des intérêts du modèle HSV est qu'il correspond mieux à une perception humaine des couleurs. De plus, une seule valeur correspond à la teinte, et il est donc facile de traverser tout le spectre des couleurs en faisant varier un seul paramètre : Hue.
Nous allons créer une fonction qui transforme une teinte en une autre, dans une image, en opérant une translation de toutes les valeurs de teintes. Il suffira pour cela de décaler toutes les valeurs de *Hue* d'un certain nombre de degrés. Par exemple, ajouter 120 à la teinte fera passer le jaune (60°) au cyan (180°). Naturellement, les autres couleurs seront modifiées aussi.
Pour réaliser cela, nous allons devoir, pour chaque couleur RGB d'une image, la transformer en HSV, opérer le décalage, puis retransformer en RGB pour stocker la nouvelle couleur.
Les outils à avoir à notre disposition sont donc une fonction qui passe de l'espace de couleurs RGB à HSV, et une autre fonction qui fait le contraire. Les formules permettant de passer d'un espace à un autre sont données ici : [[https://fr.wikipedia.org/wiki/Teinte_Saturation_Valeur#Transformation_entre_TSV_et_RVB|Transformation entre TSV et RVB]]. Nous les redonnons ci-dessous.
Soient $M=\max(R, G, B)$ et $m = \min(R, G, B)$. Si $M=m$, on prend $H = 0$. Sinon :
On obtient ainsi une valeur de $H$ entre 0 et 360. Puis on prend $V = M / 255$ (pour avoir une valeur entre 0 et 1 si les composantes RGB sont des entiers sur un octet) Et enfin, $S=(M-m)/M$ si $M$ est non nul et $S=0$ sinon.
Ce qui suit est valable pour H dans $[0, 360[$. On calcule en premier le sextant contenant la teinte, et la position dans le sextant :
puis :
Les 3 valeurs RGB (ici entre 0 et 1, il faudra les multiplier pour obtenir un entier stockable sur un octet) sont lors données par le tableau suivant :
$a$ | 0 | 1 | 2 | 3 | 4 | 5 |
R,G,B | $V,n,l$ | $m,V,l$ | $l,V,n$ | $l,m,V$ | $n,l,V$ | $V,l,m$ |
Écrivez une fonction qui prend une image et un angle en paramètres et fait tourner toutes les teintes de l'image de l'angle en question.