TD Informatique PSI
Traitement d’images
1. Notions de bases & vocabulaire
Une image numérique est une fonction à support discret et borné, et à valeurs discrètes. Le support est multidimensionnel, en
général 2d ou 3d. Les valeurs peuvent être scalaires (images en niveaux de gris), ou bien vectorielles (imagerie multi-composante,
imagerie couleur).
La gamme de valeurs possibles varie en fonction du type d'images considéré ; le Tableau 1 présente les types les plus courants, les
grandeurs physiques associées et les capteurs utilisés.
Phénomène physique
Grandeur mesurée
Capteur
Lumière visible
Flux photonique émis ou réfléchi
CCD, CMOS, Scanner
Rayonnement Infra-rouge
Luminance Infra-rouge (Chaleur)
Bolomètres
Echo ultrasonore
Distance, densité de tissus,. . .
Echographie, sonar
Résonance magnétique
Présence d'un corps chimique….
IRM, RMN,…
Echo électromagnétique
Distance, spécularité de surfaces…
Radar, SAR…
Absorption des rayons X
Densité de tissus….
Radiographie…
Tableau 1 : Quelques types dimages
Une image numérique est associée à un
pavage de l'espace, en général rectangulaire.
Chaque élément du pavage, appelé pixel, est
désigné par ses coordonnées entières : Figure
1 gauche. L'échantillonnage est le procédé
de discrétisation spatiale d'une image
consistant à associer à chaque pixel une
unique valeur : Figure 1 droite. On parle de
sous-échantillonnage lorsque l'image est déjà
discrétisée et que l’on diminue le nombre de
pixels.
La quantification désigne la discrétisation tonale correspondant
à la limitation du nombre de valeurs différentes que peut
prendre chaque pixel. Une image numérique est donc une image
échantillonnée et quantifiée.
Une image numérique 2D est représentée par un tableau T de h
lignes et w colonnes. Le pixel est désigné par un couple (i,j) j
est l'indice de colonne j {0,w1}, et i l'indice de ligne i
{0,h1}. w est la largeur, h la hauteur de l'image T. Par
convention, le pixel origine (0,0) est en général en haut à gauche
(voir Figure 2). Le nombre T(i,j) est la valeur (ou le niveau de gris)
du pixel (i,j), T(i,j) {0,Nmax1}. Nmax est le nombre de niveaux
de gris. On appelle dynamique de l'image le logarithme en base
2 de Nmax, soit encore le nombre de bits utilisés pour coder
l'ensemble des valeurs possibles.
Figure 1 Pavage (à gauche) ; Echantillonnage (à droite)
Figure 2 Conventions de notations
TD Informatique PSI
Une image numérique
ne constitue donc
qu'une version
approchée de « l’image
réelle » formée par
l'image (au sens
mathématique) de la
projection de la scène 3D
sur la portion de plan
correspondant à la
surface photosensible du
capteur. La qualité de
l'approximation dépend
de la quantité
d'information portée par
l'image numérique, en
particulier du nombre de
pixels utilisés : la
résolution spatiale. La
Figure 3 montre un
exemple d'une même
image acquise à des
résolutions différentes.
Le changement de résolution tonale, correspondant à la quantification, fait aussi apparaître une perte d'information dans les
images : voir Figure
4, pour la
représentation
d'une même image
avec différentes
dynamiques. La
bonne dynamique
dépend de la
qualité des
éléments
photosensibles du
capteur, mais aussi
de la richesse du
contenu
informationnel de
l'image, qui est lié
à la distribution
statistique de ses
valeurs.
Figure 3 Résolution spatiale : échantillonnage
Figure 4 Résolution tonale : Quantification
TD Informatique PSI
2. Manipulations de base sur les images en noir et blanc
Nous allons nous intéresser dans cette première partie à l’image « damier-ng.jpeg » qui se trouve dans un dossier nommé « Image
» disponible sur le réseau. Copier-coller ce dossier dans le répertoire de travail courant libre d’accès en écriture.
Nous aurons besoin dans toute la suite des bibliothèques « numpy », « image » et « pyplot » de matplotlib. Les importer de la
façon suivante :
import matplotlib.image as im
import matplotlib.pyplot as plt
import numpy as np
Commencer par ouvrir l’image en lecture :
pixels = im.imread("damier-ng.jpeg")
Pour afficher l’image:
plt.figure(1)
plt.imshow(pixels, cmap='gray')
plt.show()
L'image du fichier « damier-ng.jpeg » étant en noir et blanc l'argument cmap='gray' est nécessaire pour afficher l'image
correctement.
Q1. Que représente pixels ? Que représente uint8 ? Que se passe-t-il si on calcule la somme suivante :
np.uint8(10)+np.uint8(250)
Toutes les valeurs du tableau n'ont pas été affichées ci-dessus (elles ne sont pas toutes à 255). La taille du tableau est accessible
par pixels.shape qui fournit dans l'ordre le nombre de lignes et le nombre de colonnes, ou par np.size(pixels,0) et
np.size(pixels,1).
Comme on travaille dans « numpy », il est facile grâce au concept de diffusion que propose cette librairie de modifier un ensemble
de valeurs d’un tableau par une valeur unique. Par exemple : l’instruction pixels[50:250, 150:250] = 128 est
équivalente à pixels[50:250, 150:250] = table table est un tableau de la même taille que pixels[50:250,
150:250] avec toutes ses valeurs à 128.
Q2. Mettre en œuvre une méthode permettant de créer une nouvelle image avec un bord gris de 50 pixels d’épaisseur tout
autour de l’image de départ.
Nous allons maintenant modifier l'image en inversant l'intensité des pixels. En particulier le blanc et le noir seront inversés.
Q3. Réaliser cette modification et afficher l’image obtenue. Proposer une méthode alternative permettant cette inversion
d’intensité de pixels, sans utiliser de boucles.
3. Matrices de convolutions
Une opération courante en traitement d’image consiste à recalculer la valeur d’un pixel en fonction des valeurs des pixels
environnants. Ceci s'applique par exemple lorsque l'on souhaite flouter une image. Souvent, la nouvelle valeur du pixel est une
combinaison linéaire des valeurs environnantes. On peut alors décrire la transformation par une matrice.
Considérons la matrice suivante :

 
 
   
 
 
  
   
 
Hormis les pixels trop près du bord de l'image, chaque pixel est le centre d'un carré de 5 pixels de côté. Nous nous proposons de
remplacer la valeur de ce pixel par la moyenne des 25 pixels du carré, en utilisant la matrice K comme coefficients de pondération.
Les pixels proches du centre auront ainsi plus d'influence sur la valeur moyenne.
TD Informatique PSI
Pour cela nous allons écrire la fonction filtrer(T,K) qui prend en entrée deux tableaux Numpy : T : l’image à modifier et K :
une matrice carrée de taille impaire 2n+1.
La fonction filtrer(pixels,K) effectue un moyennage des pixels de pixels avec les coefficients de la matrice K. Les pixels
situés sur le cadre extérieur de largeur n ne sont pas modifiés.
Q4. Programmer une cette fonction filtrer(T,K) qui retournera une matrice filtrée de même taille que T, en n’oubliant
pas que T est un objet mutable (il faudra donc faire une copie superficielle de la matrice T dans cette fonction…).
Q5. L'image « ecole-ng.jpeg » contient une scène apparaît le visage d'une petite fille. Modifier cette image de manière à
flouter le visage. On pourra appliquer plusieurs fois de suite la fonction filtrer afin d'obtenir un flou suffisant pour
masquer l'identité de la fillette.
Les matrices de convolution peuvent aussi être utilisées pour repérer des contours d'objets dans une image. On peut par exemple
utiliser l'une des deux matrices.   
  
   OU   
  
  
On remarquera que les sommes des coefficients de ces matrices sont nulles. Si on applique la fonction filtrer avec elles, on ne
calcule donc pas vraiment une moyenne. D'ailleurs, le tableau qui en résulte peut contenir des valeurs négatives. Il ne peut donc
pas être interprété comme étant une image, du moins pas directement.
Soient les lignes de programmes suivantes, saisies directement dans la console :
>>> T = imread("ecole-ng.jpeg")
>>> T [94:97,149:152]
array([[117, 174, 251],
[116, 184, 250],
[119, 207, 249]], dtype=uint8)
>>> T[470:473,600:603]
array([[214, 212, 210],
[214, 213, 212],
[213, 213, 211]], dtype=uint8)
>>> Gx = array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]], dtype=int32)
>>> Px = filtrer(T, Gx)
Q6. Calculer à la main Px[95,150] et Px[471,601]. Que mesurent les valeurs du tableau Px ? Dans quel cas obtient-on
de grandes valeurs ?
Les valeurs calculées par filtrer(T,Gx) n'ont pas de raison de rester comprises entre 0 et 255. Le tableau retourné doit être
du type « float64 ».
Q7. Modifier en conséquence la fonction filtrer en remplaçant la ligne faisant la copie superficielle de la matrice initiale
par la création d’une matrice remplie de zeros, de type « float64 ».
Nous allons maintenant analyser le contenu du tableau Px. On exécutera pour cela les lignes de code suivantes :
Px = filtrer2(pixels, Gx)
plt.figure()
plt.hist(Px.flat, bins=200, range=(-100, 100))
plt.figure()
plt.imshow(pixels, cmap='gray')
plt.figure()
plt.imshow(Px, cmap='gray')
plt.show()
Q8. Que représentent chacune des figures obtenues ? Existe-t-il une corrélation entre elles ?
L’opération de filtrage précédente a mis en évidence les régions l’intensité varie fortement dans la direction horizontale. Nous
allons maintenant procéder de même, en effectuant le calcul dans la direction verticale
TD Informatique PSI
Q9. Créer de même le tableau Py et le représenter par une image en niveau de gris.
L’association des deux tableaux (Px, Py) peut être interprétée comme un vecteur qui indique la direction dans laquelle la variation
d'intensité est maximale pour chaque pixel. La norme de ce vecteur correspond à cette intensité maximale.
Q10. Créer alors un tableau P de même taille de Px (ou Py) dont les composantes seront les normes des vecteurs définis ci-
dessus. Dans quel cas obtient-on de grandes valeurs dans les cellules de ce tableau et le représenter par une image en
niveau de gris.
Nous avons au final trouvé une méthode qui permet de détecter les contours dans une image.
4. Images en couleur
Le codage informatique des couleurs est l'ensemble des conventions
permettant l'affichage ou l'impression par un périphérique
informatique d'une image en couleurs, plutôt qu'en noir et blanc. Le
codage se base sur la synthèse additive trichrome des couleurs. On
s’intéresse alors à une image codée au format RGB (Red-Green-Blue).
Pour cela, on a trois images nommées « canal0.jpeg », « canal1.jpeg »
et « canal2.jpeg » qui sont les trois canaux RGB d’une même image. Les
canaux 0, 1 et 2 représentent respectivement les intensités de rouge,
de vert et de bleu. Chaque combinaison d'intensités correspond à une
couleur particulière.
Q11. Observer la structure de chacune de ces images, après les
avoirs ouvertes et les avoir affichées. En déduire de combien de couleurs différentes on peut coder dans le format RGB. De
quelle couleur sont les manches des pinceaux ?
Une image RGB complète est représentée par un tableau Numpy à trois dimensions (une dimension par canal) :
>>> pixels[2, 5, 0] # Canal 0 du pixel (2, 5)
165
>>> pixels[2, 5] # Les trois canaux du pixel (2, 5)
array([165, 168, 180], dtype=uint8)
>>> pixels[:, :, 2] # Canal 2 complet
array([[180, 179, 178, ..., 161, 160, 159],
[180, 180, 180, ..., 162, 161, 160],
[180, 180, 181, ..., 162, 161, 160],
...,
[162, 163, 164, ..., 100, 100, 101],
[165, 165, 166, ..., 96, 98, 101],
[167, 167, 167, ..., 88, 94, 101]], dtype=uint8)
L’objectif va être de reconstruire l’image à partir des 3 canaux. Pour cela, on va créer un tableau Numpy de taille (h,w,3), (h,w)
est la taille d’un tableau correspondant à un canal.
Q12. Créer alors un tel tableau, que l’on pourra nommer pixels et l’afficher sur une nouvelle figure. (Quand on utilisera imshow,
il ne faudra bien entendu ne plus spécifier cmap).
Q13. Assembler de manière différente les canaux pour obtenir une image avec des manches de pinceaux jaunes.
5. Photomaton
Soit l’image « mona-lisa.jpeg » contenue dans le dossier Images. L’afficher. Nous allons trouver une méthode pour réaliser la
transformation suivante :
1 / 6 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !