L'image à charger ici est une photographie de l'entrée du lycée au format ppm.
L'objectif de ce premier exercice est de lire les données dans ce fichier ppm et de créer un second fichier ppm
qui contiendra l'image en négatif (ce qui signifie que chaque entier apparaissant dans le code d'un pixel est transformé
en son complément à 255, c'est à dire x↦255-x).
Il s'agit donc de passer de l'image de gauche à l'image de droite :
Vous aurez éventuellement besoin des fonctions join() et split() pour lesquelles vous trouverez
une présentation ici.
Résolution de l'exercice "Négatif".
Une solution possible est présentée ci-dessous.
Prenez le temps de tester, de faire des modifications, d'ouvrir les fichiers
images associés...
#ouverture en lecture
# du fichier source
fsource=open('LyceeMonge.ppm','r')
# ouverture en écriture du fichier
# à créer
fbut=open('invLyceeMonge.ppm','w')
# on recopie les 3 lignes d'entête
# de la source vers le but
for i in range(3) :
L=fsource.readline()
fbut.write(L)
#les lignes suivantes sont des chaînes constituées
# d'entiers entre 0 et 255
# et terminées par '\n'
L=fsource.readline()
while L : # tant que la ligne lue n'est pas vide
# suppression de '\n' en fin de chaîne
L.rsplit('\n')
# conversion en liste :
L=L.split()
# conversion en liste d'entiers
L=[int(x) for x in L]
# liste des compléments à 255
L=[255-x for x in L]
#conversion en liste de str
L=[str(x) for x in L]
# écriture des éléments dans le fichier but :
for x in L :
fbut.write(x+'\n')
#lecture de la ligne suivante dans le fichier source
L=fsource.readline()
fsource.close()
fbut.close()
Le zèbre trois fois trop lourd.
Le fichier à charger ici est une photo d'un zèbre au format ppm.
Ouvrez ce fichier avec un éditeur de texte. Expliquez pourquoi on peut dire que ce fichier est
trois fois trop lourd (il s'agit du poids en octets bien sûr) en observant les codes couleurs des pixels.
En cherchant sur le web, la définition du format pgm
(par exemple ici), écrire un programme python qui crée un fichier
de l'image environ trois fois moins lourd.
Résolution de l'exercice "Le zèbre lourd ".
Rappelons que chaque pixel est codé, dans le format ppm, par trois entiers (compris entre 0 et 255 et
correspondant aux intensités respectives de rouge, vert, bleu).
On lit dans le fichier que chaque paquet de trois entiers correspondant à un pixel est constitué de trois entiers égaux. L'information est donc redondante
et on devrait pouvoir la réduire.
Il se trouve que le format pgm (images en niveaux de gris) permet cette économie : dans ce format pgm, chaque pixel est codé
par un seul entier entre 0 et 255, entier correspondant à l'intensité du gris du pixel.
#ouverture en lecture
# du fichier source
fsource=open('zebre.ppm','r')
# ouverture en écriture du fichier
# à créer
fbut=open('zebre.pgm','w')
# la première ligne est modifiée :
L=fsource.readline()
fbut.write('P2\n')
# on recopie les 2 lignes suivantes
# de la source vers le but
for i in range(2) :
L=fsource.readline()
fbut.write(L)
#les lignes suivantes sont des chaînes constituées
# d'entiers entre 0 et 255
# et terminées par '\n'
ListeDesCodes=[]
L=fsource.readline()
while L : # tant que la ligne lue n'est pas vide
# suppression de '\n' en fin de chaîne
L.rsplit('\n')
# conversion en liste :
L=L.split()
# ajout à la liste des codes :
ListeDesCodes.extend(L)
#lecture de la ligne suivante dans le fichier source
L=fsource.readline()
# on ne retient qu'une copie des trois entiers codant un pixel :
ListeCodesReduite=[]
for j in range(0,len(ListeDesCodes),3) :
ListeCodesReduite.append(ListeDesCodes[j])
# écriture des éléments dans le fichier but :
for x in ListeCodesReduite :
fbut.write(x+'\n')
fsource.close()
fbut.close()
Consultez les poids des deux fichiers (pour le ppm initial : 7.9 Mo, pour le pgm obtenu : 2.6 Mo ).
On a bien un rapport de 3 environ.
Griser.
Le fichier à charger ici est une photo de fruits et légumes au format ppm.
L'objectif est de transformer cette photo en photo en niveaux de gris. On cherche
donc à passer de la joyeuse image de gauche à la triste image de droite.
Vous pourrez vous inspirer de l'exercice précédent pour trouver une solution.
Résolution de l'exercice "Griser".
L'exercice précédent peut suggérer que l'on obtiendra une image en divers gris
avec des intensités égales en rouge, vert, bleu pour chaque pixel.
Un moyen simple de rendre les intensités RGB d'un pixel égales en conservant une différence entre pixels
est de calculer la moyenne des intensités RGB.
On trouve sur le web des formules telles que code du gris = 0.2125 R + 07154 G + 0.0721 B qui permettent d'améliorer assez sensiblement
les résultats sur certaines images.
#ouverture en lecture
# du fichier source
fsource=open('fruitslegumes.ppm','r')
# ouverture en écriture du fichier
# à créer
fbut=open('fruitslegumes.pgm','w')
# la première ligne est modifiée :
L=fsource.readline()
fbut.write('P2\n')
# on recopie les 2 lignes suivantes
# de la source vers le but
for i in range(2) :
L=fsource.readline()
fbut.write(L)
#les lignes suivantes sont des chaînes constituées
# d'entiers entre 0 et 255
# et terminées par '\n'
ListeCodesPPM=[]
L=fsource.readline()
while L : # tant que la ligne lue n'est pas vide
# suppression de '\n' en fin de chaîne
L.rsplit('\n')
# conversion en liste :
L=L.split()
# ajout à la liste des codes :
ListeCodesPPM.extend(L)
#lecture de la ligne suivante dans le fichier source
L=fsource.readline()
# un pixel pgm est codé par la moyenne
# des trois entiers codant le pixel
# correspondant du fichier ppm
ListeCodesPGM=[]
for j in range(0,len(ListeCodesPPM),3) :
m=(int(ListeCodesPPM[j])+int(ListeCodesPPM[j+1])+int(ListeCodesPPM[j+2]))//3
ListeCodesPGM.append(str(m))
# écriture des éléments dans le fichier but :
for x in ListeCodesPGM :
fbut.write(x+'\n')
fsource.close()
fbut.close()
Ce module permet de manipuler les images et automatise bien sûr ce genre de traitement.
Exemple avec l'image suivante au format jpg :
from PIL import Image
# ouverture de l'image initiale :
imageSource=Image.open('ptpanda.jpg')
# conversion en niveaux de gris :
imageSource=imageSource.convert('L')
# sauvegarde du résultat sous un nouveau nom :
imageSource.save('pandagris.jpg')
# on lance une visualisation :
imageSource.show()
On obtient :
Le créateur de rose.
Le fichier à charger ici est la photo d'une rose au format ppm.
L'objectif est de créer une catégorie de rose verte.
En d'autres termes, vous devez transformer la rose de gauche en celle de droite.
Résolution de l'exercice "Le créateur de rose".
L'idée consiste à simplement échanger les intensités de rouge et de vert.
#ouverture en lecture
# du fichier source
fsource=open('rose.ppm','r')
# ouverture en écriture du fichier
# à créer
fbut=open('verte.ppm','w')
# on recopie les 3 lignes d'entête
# de la source vers le but
for i in range(3) :
L=fsource.readline()
fbut.write(L)
#les lignes suivantes sont des chaînes constituées
# d'entiers entre 0 et 255
# et terminées par '\n'
ListeCodesRose=[]
L=fsource.readline()
while L : # tant que la ligne lue n'est pas vide
# suppression de '\n' en fin de chaîne
L.rsplit('\n')
# conversion en liste :
L=L.split()
# ajout à la liste des codes :
ListeCodesRose.extend(L)
#lecture de la ligne suivante dans le fichier source
L=fsource.readline()
# on échange les intensités de vert et de rouge
ListeCodesVerte=[]
for j in range(0,len(ListeCodesRose),3) :
a, b, c= ListeCodesRose[j], ListeCodesRose[j+1], ListeCodesRose[j+2]
ListeCodesVerte.append(b+' '+a+' '+c)
# écriture des éléments dans le fichier but :
for x in ListeCodesVerte :
fbut.write(x+'\n')
fsource.close()
fbut.close()