Académique Documents
Professionnel Documents
Culture Documents
On travaillera sur l’une des images fournies sur le site de votre enseignant de mathématiques.
Télécharger l’image choisie sur votre répertoire. Ensuite, on l’ouvre dans le logiciel Python avec la commande
photo=img.imread('chemin/nom_image.png')
Cette commande permet d’enregistrer dans photo un tableau de nombres phot o [i ][ j ][k ] de taille n × p × 3 où n
est le nombre de pixels par ligne, p le nombre de pixel par colonne.
phot o [i ][ j ][k ] est un nombre compris entre 0 et 1 qui indique le pourcentage de couleur rouge si k = 0, de cou-
leur verte si k = 1, et de couleur bleue si k = 2.
Si l’image est en niveau de gris, toutes les composantes k auront la même valeur indiquant le niveau de gris.
qui crée n ∗ p images réparties selon n lignes et p colonnes et qui sélectionne la k-ième image parmi ces np
images. Pour afficher une image, on utilise la commande :
plt .imshow(image)
Exercice 2. négatif
Écrire un programme permettant d’obtenir le négatif de la photo de départ, et de l’afficher dans une même figure
que la photo de départ. Pour effectuer cette opération, il suffit d’inverser le niveau de chaque couleur et donc de
transformer la valeur x de chaque couleur de chaque pixel en 1 − x.
Attention, pour chaque transformation que l’on effectue, il faut s’assurer que la valeur obtenue reste dans [0; 1].
En fait chaque couleur rouge, verte et bleue n’ayant pas la même luminosité, plutôt qu’une moyenne des trois
composantes, il est préférable de calculer une moyenne pondérée des trois composantes selon la formule : 0, 2126×
Roug e + 0, 7152 × V er t + 0, 0722 × Bl eu.
Écrire un programme qui permet d’afficher sur une même figure l’image de départ, l’image noir et blanc obtenue
par une moyenne simple et l’image obtenue par moyenne pondérée selon la dernière formule.
Exercice 4. contraste
À partir d’une image noir et blanc, on souhaite augmenter le contraste. Pour obtenir plus de contraste, une idée
TD Info
1 TD Traitement d’image PSI
simple est d’étirer la valeur des niveaux de gris dans le domaine de valeurs où l’on souhaite obtenir plus de
contraste. Pour cela, pour chaque pixel de l’image, on remplace chaque valeur x de niveau de gris par son image
par une fonction f de [0; 1] dans [0; 1] qui a une pente plus importante dans les valeurs de x que l’on veut plus
contraster.
Exercice 5. Floutage
À partir d’une image noir et blanc, ou couleur, on veut créer un floutage sur tout ou une partie d’une photo. Pour
cela, une idée simple est de remplacer chaque composante couleur de chaque pixel par la moyenne de cette com-
posante sur tous les pixels voisins ou proche à une certaine distance.
Pour simplifier, on calcule la moyenne de chaque composante sur des carrés de côté 2a + 1 sur les pixels qui ont
un indice de ligne et un indice de colonne distant d’au plus a de l’indice du pixel courant.
Programmer une fonction floutage sur une partie centrale de la photo et afficher le résultat pour différentes va-
leurs de a.
Programmer une fonction floutage sur toute la photo en tenant compte de la particularité des bords de photo, et
afficher le résultat.
import numpy as np
from math import *
import matplotlib.image as img
import matplotlib. pyplot as plt
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
Exercice 2. négatif
TD Info
1 TD Traitement d’image PSI
Ici on n’a plus besoin de charger à nouveau la photo, on suppose qu’elle a été chargée dans un tableau à trois
dimensions photo et on va définir
● une fonction négatif qui prend en entrée une valeur entre 0 et 1 et retourne une valeur entre 0 et 1. Cela
permet de modifier la valeur x d’une couleur d’un pixel en 1 − x.
● une fonction traitement qui prend en entrée un tableau de nombre à 3 dimensions représentant une photo
et trois fonctions f, g et h. Cette fonction parcourt chaque pixel de l’image par deux boucles sur les lignes
et les colonnes, et applique la fonction f à la valeur rouge du pixel, g à la valeur vert du pixel et h à la valeur
bleue du pixel. Cette fonction retourne un tableau de nombre représentant une photo avec les modifica-
tions demandées par les trois fonctions.
● Pour obtenir le négatif d’une photo et l’affichée il ne reste plus qu’à appeler cette fonction traitement avec
les 3 fonctions négatifs sur la photo de départ et d’afficher la photo originale et le négatif avec la fonction
subplot
def negatif (k ):
return 1−k
return image2
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
0
100
200
300
400
500
600
0 100200300400500600700800
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
Exercice 4. contraste
On part ici de la photo lena_gray que l’on charge en noir et blanc dans un tableau à deux dimensions. et on définit
● Une fonction contraste qui à partir d’un nombre entre 0 et 1 retourne un nombre entre 0 et 1. Cela permet
de modifier la valeur du niveau de gris d’un pixel à partir de la fonction affine par morceaux que l’on a
définie dans l’énoncé.
● Une fonction traitement_nb qui prend en entrée un tableau de nombre à deux dimensions, et une fonction
f. On parcourt via une double boucle tous les pixels et on applique la fonction f à la valeur de niveau de gris
de chaque pixel et on enregistre la nouvelle valeur dans un nouveau tableau à deux dimension que l’on
renvoie en fin de fonction.
● on définit une fonction contraste2 avec la fonction sinus comme demandé ;
● Il ne reste plus qu’à appeler cette fonction traitement_nb avec comme paramètre la photo enregistrée
et la fonction contraste et une seconde fois avec comme paramètre la photo enregistrée et la fonction
TD Info
1 TD Traitement d’image PSI
contraste2 et afficher la photo de départ et celles obtenues dans les deux cas.
Par exemple, on peut faire le programme suivant :
import numpy as np
from math import *
import matplotlib.image as img
import matplotlib. pyplot as plt
photo=img.imread('/Users/fzwolska/.../lena_gray.png') #charge l'image
def contraste3(k ):
return (1/2+sin(pi *(k−1/2))/2)
plt .subplot(2,2,1)
plt .imshow(photo,plt.cm.gray) # on affiche la photo de départ
photo2=traitement_nb(photo,contraste)
plt .subplot(2,2,3)
plt .imshow(photo2,plt.cm.gray)
photo2=traitement_nb(photo,contraste2)
plt .subplot(2,2,4)
plt .imshow(photo2,plt.cm.gray)
plt .show()
0
100
200
300
400
500
600
0 100200300400500600700800
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
TD Info
1 TD Traitement d’image PSI
Exercice 5. Floutage
Si la photo de départ a n × p pixels, pour créer du floutage sur toute la photo, on parcourt tous les pixels de la photo
avec une double boucle, et en chaque pixel (i , j ) on fait la moyenne pour chaque composante couleur de toutes
les valeurs des pixels situés entre les lignes i − k et i + k et entre les colonnes j − k et j + k, en ne gardant bien sûr
que les valeurs de lignes entres 0 et n − 1 et de colonnes entre 0 et p − 1. Un programme tenant compte ainsi des
bords est donné ci-après.
Par contre, la valeur de k étant souvent petite devant la taille de la photo, on pourrait s’abstenir de tenir compte
de ces effets de bords en ne calculant les valeurs moyennes des composantes couleurs que pour les pixels de la
photo situés entre les lignes k et n − 1 − k et entre les colonnes k et p − 1 − k, et laisser en noir (valeur 0) les pixels
de la bande entourant la photo. Le bord n’étant en général pas le plus important dans la photo.
import numpy as np
from math import *
import matplotlib.image as img
import matplotlib. pyplot as plt
photo=img.imread('/Users/fzwolska/Documents/enseignement/classes/PSI/Informatique/traitement_image/lena.png') #charge l'image
n=len(photo)
p=len(photo[0])
q=len(photo[0][0])
plt .show()
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
0 0
100 100
200 200
300 300
400 400
500 500
600 600
0 100200300400500600700800 0 100200300400500600700800
Comme pour chaque octet désignant chaque couleur de chaque pixel de l’image donnée,
TD Info
1 TD Traitement d’image PSI
● les 4 premiers bits sont les quatre premiers bits du nombre correspondant de la photo originale
● les 4 derniers bits sont les quatre premiers bits du nombre correspondant de la photo cachée
il suffit d’extraire de chaque octet les 4 derniers bits (bits de poids faible), cela s’obtient en calculant le reste d’un
octet par la division euclidienne par 16.
Et pour obtenir un octet normal d’une image il suffit ensuite de le multiplier par 16 pour obtenir à nouveau les 4
bits de poids forts de l’image cachée.
Toutefois comme le format de l’image de départ est un nombre entre 0 et 1, il faut déjà le multiplier par 255 et
prendre sa partie entière et obtenir de véritables octets pour chaque couleur de chaque pixel.
Pour cela, soit on le fait sur une triple boucle parcourant tous les octets de chaque pixel de la photo de départ, soit
on le fait directement sur la photo en multipliant tout le tableau nd.array par 255 et en lui adjoignant l’extension
.astype(np.uint8) :
photo=img.imread('/Users/fzwolska/Documents/enseignement/classes/PSI/Informatique/TDs/2020/TD1TraitementImage/sirenedansgaronne.png')
if photo.dtype == np.float32: # Si le résultat n'est pas un tableau d' entiers
photo = (photo * 255).astype(np.uint8) #on transforme le codage des couleurs en octet
plt .imshow(photo)
plt . figure ()
image=(photo%16)*16 #on prend le reste de chaque octet modulo 16 et on le multiplie par 16
#pour obtenir les 4 bits de poids fort de l ' image de départ.
#image=(photo−(photo//16)*16)*16
plt .imshow(image)
plt .show()
Ce programme permet de révéler l’image suivante de la sirène qui était cachée dans la photo de la garonne :
100
200
300
400
500
0 100 200 300 400 500 600 700 800
Pour cacher une photo dans une autre, on crée une nouvelle photo de la taille la plus grande des photos, et
pour chaque octet de chaque pixel :
● on lui met la valeur des 4 bits forts de la plus grande photo en prenant le quotient de ces octets dans la
divisions euclidienne par 16, que l’on multiplie par 16 pour que ce soit les 4 bits forts du nouvel octet.
● Et tant que le numéro de ligne et de la colonne du pixel que l’on traite reste dans les dimensions de la petite
image, on ajoute le quotient des octets de la petite image dans la divisions euclidienne par 16. Cela crée les
4 bits faibles de chaque octet des pixels de la nouvelle image. Le programme suivant a notamment permis
de créer l’image "sirenedansgaronne"
import numpy as np
TD Info
1 TD Traitement d’image PSI
def cacheimage(image1,image2):
# on suppose que les deux dimensions de l'image 2 sont plus petites que celle de l ' image 1, et l ' image 2 sera cachée dans l'image 1
# chaque couleur étant codée par un nombre p/255, p étant un entier entre 0 et 255.
n=len(image1)
p=len(image1[0])
n2=len(image2)
p2=len(image2[0])
image3=np.zeros((n,p,3))
image3=(image1//16)*16
for i in range(n2):
for j in range(p2):
for k in range(3):
image3[i][ j ][ k]+=image2[i][ j ][ k ]// 16
plt . figure ()
plt .subplot(2,2,1)
plt .imshow(image1)
plt .subplot(2,2,2)
plt .imshow(image2)
plt .subplot(2,2,3)
plt .imshow(image3)
return image3
cacheimage(photo2,photo1)
0
0
100 100
200 200
300 300
400
400
500
0 100 200 300 400 500 600 700 800 500
0 100 200 300 400 500
0
100
200
300
400
500
0 100 200 300 400 500 600 700 800