TD : Lire une composition colorée.¶

Vincent GODARD - V6 - 06/04/2023

Cours SIG et télédétection¶

Département de géographie - L3 - Université de Paris 8¶

Inspiré de :

  • MOOC FUN MinesTelecom Introduction au traitement des images https://www.fun-mooc.fr/courses/course-v1:MinesTelecom+04044+session01/info

Sources :

  • données Landsat Thematic Mapper (TM) du 10 septembre 1987, ouest de Worcester, Massachusetts (issues du https://clarklabs.org/download/)

  • scikit-image https://scikit-image.org/

  • matplotlib https://matplotlib.org/

Téléchargement des documents nécessaires :

Dossier compressé à télécharger => ici.

1. Chargement des données et des bibliothèques¶

1.1 Chargement des données¶

Créez dans le répertoire TD13 un sous répertoire "data" où vous déposerez (bouton Upload Files), depuis votre zone de stockage, les fichiers :

○ "how87tm432.jpg" ;

○ "how87tm321_PS.jpg"

Ce noteboock et le répertoire "data" seront au même niveau dans l'arborescence, tous les deux sous TD13.

1.2 Chargement des bibliothèques (library)¶

Dans le JupyterLab la bibliothèque Matplotlib est déjà installée. Si la bibliothèque skimage ne l'est pas, il faut l'installer.

Il faut ensuite les charger (fonction import).

In [ ]:
## Si vous n'avez jamais installé skimage sur votre ordinateur, il est probablement absent des bibliothèques par défaut. 
## Pour l'installer, effacez le # (avant le "!").

#!pip install scikit-image
In [ ]:
## Import des bibliothèques
 
import skimage # Bibliothèque de traitement d'images
import skimage.io as io # Utilitaire permettant de lire et d'écrire des images dans différents formats (raccourci en io).
import skimage.metrics # Utilitaire permettant des mesures entre images.
import matplotlib.pyplot as plt # Bibliothèque destinée à tracer et visualiser des données sous forme de graphiques.

## Pour en connaître la version de skimage
skimage.__version__ # attention au "." après skimage

Il se peut que l'import de la version de skimage génère un message d'erreur, comme une incompatibilité avec NumPy, par exemple. Une des bibliothèques est trop ancienne par rapport à l'autre. Il faut donc faire une mise à jour.

In [ ]:
## SciPy est un projet qui fédère des bibliothèques Python à usage scientifique.
## Scipy utilise les tableaux et matrices du module NumPy (https://fr.wikipedia.org/wiki/SciPy).

## Mise à jour de scipy, effacez le # (avant le "!") si nécessaire.
#!pip install --upgrade scipy

## Ensuite, il faut l'importer
#import scipy

## Puis vérifier que cette nouvelle version est compatible
#scipy.__version__

On pourra avantageusement regarder à quoi servent les bibliothèques https://scikit-learn.org/stable/ ou https://scikit-image.org/ dont il existe parfois des Wiki en français https://fr.wikipedia.org/wiki/Scikit-learn ou https://fr.wikipedia.org/wiki/Scikit-image.

2. Chargement et affichage des données¶

2.1 Chargement des données¶

Lecture d'un fichier image centré sur le secteur des Howe Hill, à l'ouest de Worcester dans le Massachusetts (USA). C'est une composition colorée en couleurs naturelles issue des bandes TM3 (bande du rouge), TM2 (bande du vert) et TM1 (bande du bleu) du Landsat Thematic Mapper (TM) du 10 septembre 1987.

TM3 (bande du rouge) sera codée en rouge, TM2 (bande du vert) sera codée en vert et TM1 (bande du bleu) sera codée en bleu.

In [ ]:
## Lecture avec la fonction imread() avant affichage

HOW87TM321 = io.imread('data/how87tm321_PS.jpg')

La dynamique de l'image a été préalablement améliorée pour qu'elle ne soit pas trop terne lors de ce premier affichage, ici avec Photoshop (d'où le _PS). On verra par la suite comment le faire en Python.

2.2 Affichage du contenu de l'image¶

In [ ]:
## Affichage du nb de lignes, de colonnes et du nb de canaux (le cas échéant)
## Utilisation de la fonction .shape du module .io

print(HOW87TM321.shape)

# Si on souhaite habiller la sortie (texte entre '', puis "," avant la fonction .shape sur la variable HOW87TM123)

print('(nb lignes, nb colonnes, nb de canaux) :', HOW87TM321.shape)

On peut aussi vouloir connaître la classe de notre variable et son type.

○ Les classes sont un moyen de réunir des données et des fonctionnalités : https://docs.python.org/fr/3/tutorial/classes.html

○ Le type d'un objet Python détermine quel genre d'objet c'est : https://docs.python.org/fr/3/glossary.html#term-type
In [ ]:
## Affichage des informations

print( 'classe :', type(HOW87TM321) )
print( 'type :', HOW87TM321.dtype )

La classe est un vecteur numpy.ndarray placée dans la variable image HOW87TM321.

Comme il comporte 3 canaux (cf .shape), c'est un tableau à 3 dimensions, c'est donc un 3D array de type NumPy.

Le type est un entier (unsigned integer 8bits) codé sur un octet (256 niveaux de gris par exemple).

Donc, notre image HOW87TM321 est un vecteur de classe numpy.ndarray contenant des valeurs de type uint8 (entier sur un octet) de 3 dimensions dont la forme est : nb lignes, nb colonnes, nb de canaux codés en Rouge, Vert, Bleu.

2.3 Affichage de la composition colorée (CC) HOW87TM321¶

In [ ]:
## Affichage de l’image en composition colorée HOW87TM321, en utilisant la fonction imshow() du module io :

io.imshow(HOW87TM321)

On constate que la fonction imshow() du module io fait appel à matplotlib !

3. Décomposition de la CC HOW87TM321 en 3 canaux RVB¶

3.1 Décomposition en 3 canaux RVB affichés en couleurs par défaut¶

Affichage par itérations (Loop) en utilisant le nb de canaux (cf. Contenu en 2.2).

In [ ]:
## Décomposition en 3 canaux RVB affichés en couleurs standards
## Avec une boucle qui parcourt un nombre spécifié de fois (3) l'étendue (range) des canaux "c" en partant du premier
## Attention aux ":" à la fin de la boucle for.

for c in range(3): 
    plt.imshow(HOW87TM321[:,:,c]) # [:,:,c] permettrait de découper des sous fenêtre (cf. TELED/TD12)
    plt.show() # affiche les images mises en file d'attente par imshow() la ligne d'avant.

## Pour voir des exemples de boucles 'for' => https://waytolearnx.com/2019/05/boucle-for-en-python.html?utm_content=cmp-true

À l'œil, la différence n'est pas flagrante ! Cela s'améliorera avec l'image en fausses couleurs (cf. infra chap. 4.) !

3.2 Décomposition en 3 canaux RVB affichés en niveaux de gris¶

In [ ]:
## Décomposition en 3 canaux RVB affichés en gris et centrés sur une sous zone

for c in range(3):
    plt.imshow(HOW87TM321[400:480,200:300,c], 'gray') # imagettes centrées sur l'aéroport (coord. approx. lues en 3.1)
    plt.show()
    

À l'œil, la différence en niveaux de gris n'est toujours pas flagrante !

Enregistrons ces 3 canaux et comparons-les.

3.3 Enregistrement des 3 canaux en 3 fichiers PNG séparés¶

Si un seul canal vous intéresse, pas la peine de faire une boucle.

Rappel : les canaux sont comptés à partir de 0 !

0 = canal 3 (bande du rouge), 1 = canal 2 (bande du vert) et 2 = canal 1 (bande du bleu)

In [ ]:
## Sélection du canal à enregistrer, ici le 3.

io.imsave('data/HOW87TM3.png', HOW87TM321[:,:,0])

Si vous souhaitez enregistrer les trois canaux, il vaut mieux recourir à une boucle.

In [ ]:
## Création d'un n° de bande équivalent à l'incrément des 'range'
## On crée un tuple, une liste, où deux informations sont liées et non permutables.

img_index_tuple_list = [(0,'TM3'),(1,'TM2'),(2,'TM1')] 


## Sélection successive des canaux à enregistrer avec affectation du n° de bande

for c in img_index_tuple_list: 
    out_img_name = f'data/HOW87{c[1]}.png' # On lui précise où démarrer [1], dans le tuple
    io.imsave(out_img_name, HOW87TM321[:,:,c[0]]) # étape d'enregistrement par incrément successif
    print(out_img_name) # pour voir ci-dessous quels seront les noms des fichiers dans /data

Il semblerait qu'il n'y ait pas une grosse différence "visuelle" entre les trois fichiers .png créés. Il serait préférable de contrôler leurs différences en comparant leurs histogrammes, par exemple. Ce sera l'objet du prochain TD. En attendant, vous pouvez tester ce que vous venez de faire sur une nouvelle composition colorée, plus contrastée. Une composition colorée dite "fausses couleurs".

3.4. Comparaison statistique des 3 canaux¶

Comme nous l'avons vu au TD 12, nous pouvons comparer les canaux deux à deux en utilisant le module de l'erreur quadratique moyenne (MSE).

3.4.1 Lecture des 3 canaux¶

Chargement des images en mémoire.

In [ ]:
## Lecture des images avec la fonction imread() avant affichage

HOW87TM3 = io.imread('data/how87tm3.png')
HOW87TM2 = io.imread('data/how87tm2.png')
HOW87TM1 = io.imread('data/how87tm1.png')

On peut s'assurer que les images font la même taille. C'est une condition pour les comparaisons deux à deux du paragraphe suivant (calcul de la MSE).

In [ ]:
## Affichage du nb de lignes, de colonnes et du nb de canaux (le cas échéant)
## Utilisation de la fonction .shape du module .io

print(HOW87TM3.shape)
print(HOW87TM2.shape)
print(HOW87TM1.shape)

3.4.2 Comparaison des canaux TM3 et TM2¶

In [ ]:
## Calcul de l'erreur quadratique moyenne (MSE) entre les deux canaux TM3 et TM2

mse = skimage.metrics.mean_squared_error(HOW87TM3, HOW87TM2) # calcul de l'écart entre les deux canaux avec skimage.metrics via MSE

MSE = f'{mse:.2f}' # Valeur de la MSE avec deux décimales, grandeur sans unité (luminances apparentes ou comptes numériques)

## Affichage de la MSE

print('Valeur de la MSE (erreur quadratique moyenne) entre les canaux TM3 et TM2 :', MSE)

Bien que la différence de radiométries ne soit pas nette à l'œil, la valeur de MSE est sans appel. Les canaux sont différents.

On peut encore le tester entre TM3 et TM1.

3.4.3 Comparaison des canaux TM3 et TM1¶

In [ ]:
## Calcul de l'erreur quadratique moyenne (MSE) entre les deux canaux TM3 et TM1

mse = skimage.metrics.mean_squared_error(HOW87TM3, HOW87TM1) # calcul de l'écart entre les deux canaux avec skimage.metrics via MSE

MSE = f'{mse:.2f}' # Valeur de la MSE avec deux décimales, grandeur sans unité (luminances apparentes ou comptes numériques)

## Affichage de la MSE

print('Valeur de la MSE (erreur quadratique moyenne) entre les canaux TM3 et TM1 :', MSE)

Les canaux TM3 et TM1 sont plus proches que les canaux TM3 et TM2 car leur MSE est plus faible.

3.4.4 Comparaison des canaux TM1 et TM2¶

Sauriez-vous calculer la MSE entre les canaux TM1 et TM2 ?

In [ ]:
 

4. Affichage de la composition colorée (CC) HOW87TM432¶

Sauriez-vous afficher une autre CC, la HOW87TM432 ? La décomposer en trois bandes ?

Les différences seront plus visibles sur cette composition colorée "fausses couleurs" !

In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
    
In [ ]: