Il existe de nombreuses bibliothèques pour traiter les images en Python :
Nous mettons en œuvre ici la bibliothèque Pillow, pour modifier les couleurs et les positions des pixels.
Nous utilisons le module Image de la bibliothèque Pillow :
from PIL import Image img=Image.new("RGB",(300,200)) for x in range(0,300) : for y in range(0,200) : img.putpixel((x,y),(0,255,0)) for x in range(100,150) : for y in range(50,150) : img.putpixel((x,y),(200,60,60)) for x in range(60,240) : for y in range(100,120) : img.putpixel((x,y),(80,80,200)) img.save("dessin.png") img.show()
Résultat :
Les images de tournage vidéo peuvent être réalisées devant un fond vert. En post-production, ces pixels verts sont remplacés par des pixels d’une photographie, donnant une implantation du personnage dans un nouveau décor. Le but est de réaliser une opération similaire en insérant l'image d'un chat dans un paysage.
Téléchargez les deux images ci-dessous, nommées chat.png
et paysage.jpg
,
placez-les dans le même dossier que celui choisi pour sauvegarder votre code.
Testez le code ci-dessous permettant de connaître la valeur attribuée à un pixel.
from PIL import Image img=Image.open("chat.png") print(img.format) # png, gif... print(img.mode) print(img.size) print(img.size[0]) # largeur de l'image en pixels print(img.size[1]) # hauteur de l'image en pixels p=img.getpixel((10,10)) print(p) print(p[0]) # quantité de rouge print(p[1]) # quantité de vert print(p[2]) # quantité de bleu
Testez le code ci-dessous permettant de connaître la couleur d'un pixel.
Modifiez les coordonnées du pixel pour afficher : Le pixel n'est pas vert
.
from PIL import Image img=Image.open("chat.png") p=img.getpixel((10,10)) if p==(0,255,0) : print("Le pixel est vert") else : print("Le pixel n'est pas vert")
Le programme passe en revue chaque pixel de la première image. S'il n'est pas vert, alors il l'insère dans la deuxième image.
from PIL import Image img1=Image.open("chat.png") img2=Image.open("paysage.jpg") for x in range(0,300) : for y in range(0,200) : p=img1.getpixel((x,y)) if p!=(0,255,0) : img2.putpixel((x,y),p) img2.save("insertion.jpg") img2.show()
En adaptant le code de la première image, sauriez-vous dessiner le drapeau français?
En adaptant le code ci-dessus, sauriez-vous dessiner le petit chat devant le drapeau français?
Le chat se positionne en ajoutant ou en retranchant des valeurs aux coordonnées x et y. Par exemple :
p=img1.getpixel((x,y)) if p!=(0,255,0) : img2.putpixel((x-70,y-20),p)
Attention aux limites! Ci-dessous, pour déplacer le chat vers le bas, la valeur verticale se limite à 199 sous peine de générer une erreur.
p=img1.getpixel((x,y)) if p!=(0,255,0) : if y+30 < 200 : img2.putpixel((x,min(y+30,199)),p)
Ecrit autrement :
p=img1.getpixel((x,y)) if p!=(0,255,0) : img2.putpixel((x,min(y+30,199)),p)
Sauriez-vous dessiner le petit chat centré devant le drapeau français?
Les dimensions du chat se modifient en multipliant les coordonnées x et y par la même valeur.
La fonction int()
retourne la partie entière du nombre.
p=img1.getpixel((x,y)) if p!=(0,255,0) : img2.putpixel((int(x*0.6),int(y*0.6)),p)
Sauriez-vous dessiner le petit chat devant le drapeau français, en en diminuant la taille?
Le détourage réalisé reste imparfait. Des pixels verts bordent le contour du chat. Améliorez le résultat en apportant une plus grande tolérance au test :
p=img1.getpixel((x,y)) if p[0]>60 or p[1]<195 or p[2]>60 : img2.putpixel((x,y),p)
Agrandissements des rendus avec les pixels comparés aux verts pur et tolérancé :
Les quantités de rouge, vert ou bleu se calculent en fonction des coordonnées x et y. Il faut juste veiller à ce qu'elles soient des entiers compris entre 0 et 255.
from PIL import Image img=Image.new("RGB",(300,200)) for x in range(0,300) : for y in range(0,200) : img.putpixel((x,y),(0,int(x*255/300),0)) img.save("dessin.png") img.show()
from PIL import Image img=Image.new("RGB",(300,200)) for x in range(0,300) : for y in range(0,200) : img.putpixel((x,y),(0,int(y*255/200),0)) img.save("dessin.png") img.show()
from PIL import Image img=Image.new("RGB",(300,200)) for x in range(0,300) : for y in range(0,200) : img.putpixel((x,y),(int(x*255/300),int(y*255/200),0)) img.save("dessin.png") img.show()
Il existe une infinité de solutions pour fusionner deux images et obtenir une sorte de fantôme. Dans l'exemple ci-dessous, on prend les valeurs moyennes des couleurs.
from PIL import Image img1=Image.open("chat.png") img2=Image.open("paysage.jpg") for x in range(0,300) : for y in range(0,200) : p=img1.getpixel((x,y)) q=img2.getpixel((x,y)) if p[0]>60 or p[1]<195 or p[2]>60 : img2.putpixel((x,y),(int((p[0]+q[0])/2),int((p[1]+q[1])/2),int((p[2]+q[2])/2))) img2.save("insertionter.png") img2.show()
On obtient un résultat similaire en écrivant :
img2.putpixel((x,y),(max(p[0],q[0]),max(p[1],q[1]),max(p[2],q[2])))
Ou encore :
img2.putpixel((x,y),(min(p[0],q[0]),min(p[1],q[1]),min(p[2],q[2])))