Manipulation d'image avec Python
Le code suivant permet de télécharger une image et de l'afficher dans Basthon.
Par défaut, l'image sélectionnée est celle-ci :
Elle est issue de pexels.
lien_image="https://images.pexels.com/photos/39899/rose-red-tea-rose-regatta-39899.jpeg"
from PIL import Image
import requests
from io import BytesIO
response = requests.get(lien_image)
img = Image.open(BytesIO(response.content))
img.show()
Essayez d'executer ce code. Il doit normalement afficher l'image, après une seconde ou deux, dans la partie graphique de basthon, accessible en cliquant sur le bouton 1. Vous pouvez revenir à la console en cliquant sur le bouton 2.
Dans la suite, nous allons travailler avec le code ci-dessous qui vous est fourni, et qui vous permet d'appliquer une transformation à chaque pixel.
lien_image="https://images.pexels.com/photos/39899/rose-red-tea-rose-regatta-39899.jpeg"
def rouge(pixel):
return pixel[0]
def vert(pixel):
return pixel[1]
def bleu(pixel):
return pixel[2]
def pixel(r, v, b):
return (r, v, b)
# Cette fonction est à modifier
def transformation(p):
r = rouge(p)
v = vert(p)
b = bleu(p)
return pixel(r, v, b)
from PIL import Image
import requests
from io import BytesIO
response = requests.get(lien_image)
img = Image.open(BytesIO(response.content))
ratio = max(500/img.width, 500/img.height)
img.resize((int(img.width * ratio), int(img.height * ratio)), Image.Resampling.NEAREST)
for x in range(img.width):
for y in range(img.height):
px = img.getpixel((x, y))
r = transformation(px)
img.putpixel((x,y), r)
img.show()
La fonction transformation
prends en paramètre un pixel p
, et retourne la nouvelle valeur de p
à mettre dans l'image.
Les fonctions rouge
, vert
,et bleu
prennent en paramètre un pixel et retournent la valeur de son canal rouge, vert et bleu respectivement.
La fonction pixel
prends en paramètre les valeurs des canaux rouge, vert, et bleu d'un pixel et retournent la valeur du pixel.
La transformation actuelle :
# Cette fonction est à modifier
def transformation(p):
r = rouge(p)
v = vert(p)
b = bleu(p)
return pixel(r, v, b)
Ne fait aucun changement sur le pixel.
Essayons de changer la ligne
en
Ce qui inverse les valeurs des canaux bleu et vert de chaque pixel de l'image. Observez le résultat.
Seuillage selectif
On va essayer de ne garder que la rose, et de passer le reste de l'image en noir.
Dans un premier temps, on va passer tous les pixels en noir.
Activité
Maintenant, essayons de rendre noirs le pixels qui n'appartiennent pas à la rose, c'est à dire qui ne sont pas rose.
Activité
Modifiez la transformation pour qu'elle passe tous les pixels en noir, sauf ceux qui appartiennent à la rose.
Dans notre image, la rose est la seule partie qui a un canal rouge avec une valeur supérieure à 145.
Il vous faut utiliser un If, et vérifier que le canal rouge est au dessus de la valeur minimale.
Désaturation ...
La désaturation consiste à transformer les couleurs en nuances de gris, sous forme d'une valeur de luminosité qui sera la même pour chaque canal.
Pour calculer cette valeur, on peut commencer par faire la moyenne des des canaux rouge, vert, et bleu.
Activité
On peut voir que certains pixels, en particulier ceux de la rose, apparaissent trop lumineux. Pour corriger ça, on va pondérer chaque canal dans le calcul de la moyenne.
Activité
Modifiez la transformation pour qu'elle passe les pixels en nuances de gris, en utilisant une moyenne pondérée.
Par exemple, vous pouvez utiliser : - 0.3 pour le rouge - 0.6 pour le vert - 0.1 pour le bleu
N'hésitez pas à changer ces trois valeurs pour voir ce qui change dans le résultat.
Attention, en fonction de comment vous choisissez les poids de votre moyenne, à bien tout ramener à une valeur entre 0 et 255.
... sauf la rose
Activité
Modifiez la transformation pour qu'elle passe les pixels en nuances de gris, en utilisant une moyenne pondérée, tout en préservant la couleur originale de la rose.
Extension
- Essayez de colorer aléatoirement certains pixels. C'est ce que l'on appelle du bruit.
- Essayez d'appliquer des traitements similaires à d'autres images.
- (Difficile !) Essayez de modifier le code de façon à ce que la fonction
transformation
reçoive les dimensions (hauteur et largeur) de l'image et les coordonnées du pixel en plus de sa valeur. Trouvez un traitement qui utilise ces informations.