TP Images
TP Images
TP Images
L1 = [1,2,3]
L2 = [4,5,6]
v1 = np.array(L1)
v2 = np.array(L2)
Exécuter puis commenter ce qui est renvoyé par les commandes suivantes :
1
print(L1 + L2)
print(v1 + v2)
print(2 * L1)
print(2 * v1)
print(1.5 * L1)
print(1.5 * v1)
print(L1 ** 2)
print(v1 ** 2)
L1.append(7)
v1.append(7)
print(np.sin(v1))
Exercice 2 : Le type np.uint8 Pour : entier non signé codé sur 8 bits.
On représentera les niveaux de gris par un entier codé sur 8 bits entre 0 et 28 − 1 = 255
(voir cours du second semestre), à l'aide du type np.uint8 de Python. Pour comprendre
son incidence sur les opérations élémentaires, exécuter et commenter le code suivant :
a = np.uint8(280)
b = np.uint8(240)
print(a)
print(a+b)
print(a-b)
print(a//b)
print(a/b)
Les fonctions numpy qui eectuent de manière répétitive des opérations élémentaires
prennent la précaution d'utiliser pour leurs calculs intermédiaires et leur résultat un
type compatible avec le type de base de la plus grande capacité possible. Par exemple
le résultat de np.sum(np.array([100, 200], dtype=np.uint8)) est de type np.uint32
(entier non signé codé sur 32 bits) et vaut bien 300. On les utilisera donc si besoin.
Les images sont représentées par des matrices de pixels. On distingue deux catégories :
1. Les images en couleur : chaque pixel code une couleur sous forme d'un vecteur
de taille 3 contenant 3 entiers associés à la décomposition de la couleur dans le
système RVB (rouge-vert-bleu), codés en général sur 8 bis (donc de type np.uint8,
voir exercice 2). Ainsi une image en couleur est une "matrice de vecteurs" donc un
tableau à 3 dimensions. Si img est une telle image, img[i,j] renvoie le pixel de
coordonnées (i, j), c'est donc un vecteur de taille 3.
2. Les images en niveaux de gris : chaque pixel n'est cette fois représenté que par un
seul entier, codant la nuance de gris entre le noir (0) et le blanc (255). Une image
en niveaux de gris est une matrice (donc un tableau à 2 dimensions).
2
Pour manipuler des images avec Python, on importe les modules :
import numpy as np
import matplotlib.pyplot as plt
Pour des manipulations plus complexes, on peut aussi utiliser from scipy import
ndimage mais ce n'est pas le cas dans ce TP.
Une image au format JPEG peut être convertie en matrice de pixels à l'aide de la
commande :
img = plt.imread("image.jpg")
Téléchargez sur Cahier de prépa l'image "plage.jpg", l'enregistrer dans le répertoire de
travail (c'est celui où sont enregistrés les chiers créés sur Python, voir le TP "Lecture
et écriture de chiers"), puis l'ouvrir à l'aide de cette commande, observez la nature et
les dimensions de l'objet img. Les fonctions des exercices suivants pourront être testées
sur cette image.
Pour acher une image associée à une matrice de pixels, on utilisera :
plt.imshow(img)
plt.show()
Si l'image est en niveaux de gris :
plt.imshow(img, cmap = plt.cm.gray)
plt.show()
Remarque :La commande plt.imsave permet de d'enregistrer une matrice de pixels
dans un chier.
1. Écrire une fonction gris(p) prenant en entrée un pixel de couleur (donc un vecteur
de taille 3) et renvoyant le niveau de gris correspondant à la moyenne de ses 3
composantes RVB, arrondie à l'entier le plus proche. On utilisera les commandes :
- np.mean(v) : renvoie la moyenne des éléments du vecteur v (sous forme d'un
ottant), compatible avec le type np.uint8 (voir exercice 2)
- round pour arrondir un ottant en entier
- on convertira le résultat en entier codé sur 8 bits à l'aide du type np.uint8
2. Écrire une fonction conversion(img) prenant en entrée une image en couleurs
(donc un tableau à 3 dimensions) et renvoyant une image en niveaux de gris (donc
un tableau à 2 dimensions) construite à partir de celle-ci en prenant pour chaque
pixel la moyenne (arrondie) de ses 3 composantes RVB.
Remarque : Si vous voulez enregistrer votre image en niveau de gris dans un -
chier, il faudra utiliser : plt.imsave(<fichier>,<matrice>,cmap = plt.cm.gray).
Dans toute la suite, on ne manipulera que des images en niveaux de gris, donc des
tableaux à 2 dimensions.
3
3. Écrire une fonction inverser(A) renvoyant l'image inverse de A, c'est-à-dire que
chaque pixel de niveau de gris p est remplacé par celui de niveau 255-p.
4. Écrire une fonction flip(A) renvoyant l'image obtenue à partir de A en appliquant
une symétrie d'axe vertical passant par le milieu de l'image.
5. Écrire une fonction tourner(A) renvoyant l'image obtenue à partir de A en appli-
quant une rotation de 90°.
6. On souhaite maintenant redimensionner une image. On dispose d'une image A de
taille (N, M ) que l'on veut redimensionner en appliquant un facteur f .
On obtient alors une image R de taille (n = bf · N c, m = bf · M
h
c).
i
On devrait alors avoir pour (i, j) ∈ [[0, n[[×[[0, m[[ : R[i, j] = A i j
f, f .
Malheureusement, sauf si f est l'inverse d'un entier, i
f et j
f ne sont en général pas
des entiers.
a) Méthode du plus proche voisin :
Dans cette méthode, on remplace fi et fj par leurs arrondis entiers ou leurs
parties entières.
Si on veut prendre les arrondis, il faut faire attention à ne pas sortir de l'image
d'origine.
Écrire une fonction ppvoisin(A,f) prenant en entrée une image A en niveaux
de gris et facteur f et qui renvoie une nouvelle image en ayant appliqué à A le
facteur f de l'interpolation au plus proche voisin.
Dans un premier temps, vous utiliserez les parties entières et si vous avez du
temps, les arrondis.
b) Par interpolation bilinéaire
Étant donné deux entiers a et b et une fonction f à deux variables, on interpole
f en ((a, b), (a + 1, b), (a, b + 1), (a + 1, b + 1)) par une fonction du type :
g(x, y) = α + β(x − a) + γ(y − b) + δ(x − a)(y − b).
En remplaçant x et y par a, a + 1 , b et b + 1 on obtient :
α = f (a, b), β = f (a + 1, b), γ = f (a, b + 1) − f (a, b) et δ = f (a + 1, b + 1) +
f (a, b) − f (a + 1, b) − f (a, b + 1).
Écrire une fonction qui modie la taille d'une image par interpolation bilinéaire.
Attention : il peut y avoir des problèmes au bord de l'image.
7. On souhaite maintenant détecter les contours d'une image. Pour cela on remplace
chaque pixel A(i, j) par la norme de son gradient discret :
(A(i, j) − A(i, j − 1))2 + (A(i, j) − A(i − 1, j))2 (sauf pour la première ligne et
p
la colonne où on mettra des 0). Écrire une fonction contour(A) réalisation cette
opération à l'image A (pour plus de lisibilité, on pourra renvoyer une image inver-
sée). Pour réaliser la soustraction de deux entiers x et y codés sur 8 bits, on pourra
écrire x + (-1)*y (le résultat sera codé sur 32 bits), et on pourra utiliser np.sqrt
pour la racine carrée.