PYTHON
TRAITER LES IMAGES - 1ère partie

Introduction

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.

Expérimenter

Dessiner une première image

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 :

Insérer une image dans une photographie

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.

   

Identifier un pixel

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)
print(img.mode)

print(img.size)
print(img.size[0])
print(img.size[1])

p=img.getpixel((1,1))
print(p)
print(p[0])
print(p[1])
print(p[2])

Testez le code ci-dessous permettant d'identifier un pixel.

from PIL import Image
img=Image.open("chat.png")

p=img.getpixel((280,180))

if p==(0,255,0) :
  print("Le pixel est vert")
else :
  print("Le pixel n'est pas vert")

Insérer l'image

Chaque pixel vert est remplacé par le pixel situé au même endroit de l’image paysage.jpg.

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()

Programmer

Drapeau français

En adaptant le code de la première image, sauriez-vous dessiner le drapeau français?

Chat devant le drapeau

En adaptant le code ci-dessus, sauriez-vous dessiner le petit chat devant le drapeau français?

Modifications

Déplacer le chat

La translation du chat s'obtient en ajoutant ou en retranchant deux valeurs aux coordonnées x et y. Testez...

p=img1.getpixel((x,y))
if p!=(0,255,0) :
  img2.putpixel((x-70,y-20),p)

Pour déplacer le chat vers le bas, la valeur verticale doit se limiter à 199, sous peine de générer une erreur.

p=img1.getpixel((x,y))
if p!=(0,255,0) :
  img2.putpixel((x,min(y+30,199)),p)

Changer la taille du chat

Les dimensions du chat se modifient en multipliant les coordonnées x et y par la même valeur. La fonction round() retourne l'entier le plus proche. Essayez de réduire la taille du chat.

p=img1.getpixel((x,y))
if p!=(0,255,0) :
  img2.putpixel((round(x*0.6),round(y*0.6)),p)

Améliorer le résultat

Le détourage réalisé est imparfait. Des pixels verts bordent le contour du chat. Améliorez votre résultat en donnant 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)

Pour aller plus loin

Des dégradés

Les quantités de rouge, vert ou bleu peuvent être calculées en fonction des coordonnées x et y. Il faut juste veiller à ce qu'elles soient des entiers compris entre 0 et 255.

Dégradé horizontal

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()

Dégradé vertical

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()

Dégradé multiple

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()

Fusionner des images

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])))