Vincent GODARD - V4- 30/03/2023
Inspiré de :
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/
numpy https://numpy.org/
Dossier compressé à télécharger => ici.
Créez dans le répertoire TD11 un sous répertoire "data" où vous déposerez (bouton Upload Files), depuis votre zone de stockage, les fichiers :
- how87tm3.tif
- how87tm4.tif
Ce noteboock et le répertoire "data" seront au même niveau dans l'arborescence, tous les deux sous TD12.
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. Idem pour numpy.
Il faut ensuite les charger (fonction import).
## 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
## 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.
import numpy as np # Bibliothèque destinée à manipuler des matrices ou tableaux multidimensionnels.
## Pour en connaître la version de skimage
skimage.__version__ # attention au "." après skimage
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 ou bien encore https://fr.wikipedia.org/wiki/NumPy.
Lecture d'un fichier image centré sur le secteur des Howe Hill, à l'ouest de Worcester dans le Massachusetts (USA). C'est la bande TM4 (PIR, proche infra-rouge) du Landsat Thematic Mapper (TM) du 10 septembre 1987.
Contrairement au TD11, le fichier n'est plus dans un format .jpg (format compressé JPEG, https://fr.wikipedia.org/wiki/JPEG) mais .tif (format compressé ou non TIFF, https://fr.wikipedia.org/wiki/Tagged_Image_File_Format).
## Lecture avec la fonction imread() avant affichage
HOW87TM4 = io.imread('data/how87tm4.tif')
## 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(HOW87TM4.shape)
## Si on souhaite habiller la sortie (texte entre '', puis "," avant la fonction .shape sur la variable HOW87TM123)
print('(nb lignes, nb colonnes) :', HOW87TM4.shape)
On peut aussi vouloir connaître la profondeur de notre variable (son codage) par son type.
○ La fonction type() renvoie le type de objet (entier, texte, tuple...) : https://docs.python.org/fr/3/glossary.html#term-type
## Affichage des informations
print( 'type :', HOW87TM4.dtype )
Le type est un entier (unsigned integer 8bits) codé sur un octet (256 niveaux de gris par exemple).
## Affichage de l’image en niveau de gris, en utilisant la fonction imshow() du module plt :
plt.imshow(HOW87TM4, 'gray')
## Pour choisir une autre couleur : https://matplotlib.org/stable/tutorials/colors/colormaps.html
## Écrire n'importe quoi à la place de 'gray', cela génère un message d'erreur !
## À ValueError, dans la liste des couleurs, en essayer d'autres comme :
## 'viridis' (couleur par défaut) ou 'tab20c_r' pour voir l'effet.
## Attention à la casse (MAJ/min) !
Compression dans un des formats les plus courants, le JPEG (https://fr.wikipedia.org/wiki/JPEG).
Compression de l'image HOW87TM4 en jpeg avec un niveau de compression compris entre 1 et 100
## Sauvegarde de l'image compressée en format .jpg
io.imsave('data/HOW87TM4.jpg', HOW87TM4, quality=50) # compression à 50%
Après la compression, il faut comparer les deux fichiers. La première étape peut être visuelle.
À l’œil, celles-ci doivent être encore très ressemblantes. Sinon, les indicateurs statistiques de similitude risquent d'être très défavorables !
## Lecture de l'image en format .jpg
JPEG4 = io.imread('data/HOW87TM4.jpg') # lecture de l'image affectée à la variable JPEG
plt.imshow(JPEG4, 'gray')
À l'œil, la différence n'est pas flagrante !
Comparaisons visuelles et statistiques.
Utilisation de la fonction subplot() de "matplotlib.pyplot" qui permet d’organiser différents tracés à l’intérieur d’une grille d’affichage (https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplot.html ou en français https://courspython.com/tracer-plusieurs-courbes.html#affichage-de-plusieurs-traces-dans-la-meme-figure).
## Affichage de l'image compressée et de l'image des différences
plt.figure(figsize=(15, 5)) # affichage des images dans deux sous figures (faire varier la taille (size) si besoin
plt.subplot(121) # affichage de plusieurs tracés dans la même figure (121/122 disposition sur une ligne)
plt.title('JPEG4 (luminances apparentes, 256 niveaux de gris') # titrage pour identifier l'image
plt.imshow(JPEG4, 'gray') # fonction d'affichage dans matplotlib.pyplot
## Ajout de la légende
plt.colorbar()
diff1 = np.absolute(HOW87TM4-JPEG4) # calcul (avec numpy) la valeur absolue de la différence entre les deux images (origine - compressée)
plt.subplot(122) # affichage de plusieurs tracés dans la même figure (121/122 = disposition sur une ligne)
plt.imshow(diff1) # affiche l'image des différences entre HOW87TM4 et JPEG4
## Ajout de la légende
plt.colorbar()
plt.title('TIFF - JPEG4 (écart en val. absol. de luminances appar.)') # ajout d'un titre à la sous figure avec la valeur de MSE associée à l'image des différences
plt.show() # Pas nécessaire ici pour afficher les résultats successifs stockés en mémoire, mais évite texte inutile au dessus des images (comme : Text(0.5, 1.0, 'Différence TIFF - JPEG4'))
La répartition spatiale des différentes valeurs d'écarts (du bleu au jaune) semble assez homogène.
Utilisation de la MSE (Mean-squared error, erreur quadratique moyenne) comme indicateur statistique de la perte due à la compression.
Qu'est-ce que la MSE [mean-squared error ou erreur quadratique moyenne (EQM) https://fr.wikipedia.org/wiki/Erreur_quadratique_moyenne] ? Allez voir le paramétrage et les explications en suivant ce lien : https://scikit-image.org/docs/stable/api/skimage.metrics.html#skimage.metrics.mean_squared_error.
## Calcul de l'erreur quadratique moyenne (MSE) entre les deux images
mse = skimage.metrics.mean_squared_error(HOW87TM4, JPEG4) # calcul de l'écart entre les deux images avec skimage.metrics via MSE
MSE = f'{mse:.2f}' # Valeur de la MSE avec deux décimales
#print(f" Valeur de la MSE (erreur quadratique moyenne) entre les deux images : {mse:.2f}")
print('Valeur de la MSE (erreur quadratique moyenne) entre les deux images :', MSE)
Comme c'est une valeur brute, il est difficile de savoir si cette perte d'information (écart à l'image d'origine) est importante !
Nous allons comparer cette valeur de MSE avec celle obtenue, au prochain chapitre, sur une autre compression, la PNG.
Sauvegarde de l'image HOW87TM4 avec un niveau de compression par défaut, quand c'est en .png .
## Sauvegarde de l'image compressée en format .png
io.imsave('data/HOW87TM4.png', HOW87TM4) # on ne définit pas de niveau de compression ici
Après la compression, il faut comparer les deux fichiers. Déjà visuellement.
À la lecture, celles-ci doivent être très ressemblantes !
## Lecture de l'image en format .png
PNG4 = io.imread('data/HOW87TM4.png') # lecture de l'image affectée à la variable PNG
plt.imshow(PNG4, 'gray')
## Ajout de la légende
plt.colorbar()
À l’œil, la différence n'est toujours pas flagrante !
Comparaisons visuelles et statistiques.
Utilisation de la fonction subplot() de "matplotlib.pyplot" qui permet d’organiser différents tracés à l’intérieur d’une grille d’affichage (https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.subplot.html ou en français https://courspython.com/tracer-plusieurs-courbes.html#affichage-de-plusieurs-traces-dans-la-meme-figure).
## Affichage de l'image compressée et de l'image des différences
plt.figure(figsize=(15, 5)) # affiche les images dans deux sous figures (faire varier la taille (size) si besoin
plt.subplot(121) # affichage de plusieurs tracés dans la même figure (121/122 disposition sur une ligne)
plt.title('PNG4 (luminances apparentes, 256 niveaux de gris') # titrage pour identifier l'image
plt.imshow(PNG4, 'gray') # fonction d'affichage dans matplotlib.pyplot
## Ajout de la légende
plt.colorbar()
diff2 = np.absolute(HOW87TM4-PNG4) # calcul (avec numpy) la valeur absolue de la différence entre les deux images (origine - compressée)
plt.subplot(122) # affichage de plusieurs tracés dans la même figure (121/122 = disposition sur une ligne)
plt.imshow(diff2) # affiche l'image des différences entre HOW87TM4 et PNG4
## Ajout de la légende
plt.colorbar()
plt.title('TIFF - PNG4 (écart en val. absol. de luminances appar.)') # ajout d'un titre à la sous figure avec la valeur de MSE associée à l'image des différences
plt.show() # Pas nécessaire ici pour afficher les résultats successifs stockés en mémoire, mais évite texte inutile au dessus des images (comme : Text(0.5, 1.0, 'Différence TIFF - PNG4'))
La répartition spatiale des différentes valeurs d'écarts (du bleu au jaune) semble assez homogène.
Utilisation de la MSE (Mean-squared error, erreur quadratique moyenne) comme indicateur statistique de la perte due à la compression.
Qu'est-ce que la MSE [mean-squared error ou erreur quadratique moyenne (EQM) https://fr.wikipedia.org/wiki/Erreur_quadratique_moyenne] ? Allez voir le paramétrage et les explications en suivant ce lien : https://scikit-image.org/docs/stable/api/skimage.metrics.html#skimage.metrics.mean_squared_error.
## Calcul de l'erreur quadratique moyenne (MSE) entre les deux images
mse = skimage.metrics.mean_squared_error(HOW87TM4, PNG4) # calcul de l'écart entre les deux images avec skimage.metrics via MSE
MSE = f'{mse:.2f}' # Valeur de la MSE avec deux décimales
#print(f" Valeur de la MSE (erreur quadratique moyenne) entre les deux images : {mse:.2f}")
print('Valeur de la MSE (erreur quadratique moyenne) entre les deux images :', MSE)
Donc, pas de perte (MSE = 0) avec une compression en PNG !
Cependant, comparez la taille des fichiers TIFF, JPEG et PNG dans votre répertoire des données (data) !
Ne soyez pas surpris si l'image HOW87TM3 est très sombre. Sa dynamique est faible. Nous verrons au TD 14 comment l'analyser et l'améliorer.