Télédétection et machine
learning avec Python
Souleymane BAH
[email protected] https://souleymanebah.wordpress.com
08 juillet 2024
PLAN
1. Rappels sur la télédétection
2. Plateformes d'accès à l'imagerie satellitaire : Copernicus et USGS
3. Télédétection et Python
4. Télédétection et Machine Learning
5. Ressources
2
1. Rappels sur la télédétection
• Télédétection :
• « the science and technology by which the characteristics of objects of interest can be identified, measured or
analyzed the characteristics without direct contact » Japan Association on Remote Sensing
• Le plus souvent mesure de l’énergie émanant de la surface terrestre
• Capteurs et résolutions
• Capteurs passifs : soleil comme source énergie mesurée
• Capteurs actifs : capteur comme source énergie mesurée
• Résolutions
• Résolution spatiale : surface couverte par un pixel Processus de télédétection
Crédit : Centre canadien de télédétection
• Résolution spectrale : plus petite largeur de la bande spectrale enregistrée par le capteur
• Résolution radiométrique : sensibilité à l’intensité de l’énergie électromagnétique, mesurée en bit
• Résolution temporelle : temps pour observer exactement la même scène à partir du même point dans l'espace
3
1. Rappels sur la télédétection
• Radiance, réflectance et signature spectrale
• Les capteurs mesurent la radiance
• La réflectance est le rapport énergie réfléchie/énergie totale
• La signature spectrale est la courbe de la réflectance par rapport à la longueur d’onde
Courbe de réflectance d’un végétal chlorophyllien
4
Crédit : Hountondji
1. Rappels sur la télédétection
• Type de satellites
• Multispectral : 3 à 8 canaux d’observation.
• Ex : Sentinel-2, GeoEye-1
• Hyperspectral : 15 à 250 canaux et même jusqu’à 900.
• Ex : PRISMA, Pixxel
• Thermal infrarouge : température précise de la surface du sol.
• Ex : Landsat 8/9, OroraTech
• SAR : Radar à synthèse d'ouverture.
• Ex : Sentinel-1, Capella
• LiDAR : capteur actif laser.
• Ex : ICESat-2, NUVIEW
Couverture des bandes multispectrales et hyperspectrales
5
Crédits : Pettorelli et al., 2014 ; EOS DATA ANALYTICS
2. Plateformes d'accès à l'imagerie satellitaire : Copernicus
• CDSE : Copernicus Data Space Ecosystem
• Copernicus : programme de l’Union Européenne d’observation de la Terre
• CDSE : portail officiel d’accès à l’imagerie satellitaire du programme Copernicus
• https://dataspace.copernicus.eu/
• Pratique
• Créer un compte et se connecter
• Explore data Copernicus browser
• Go to place + Create an Area Of Interest OU Upload file to create an AOI (Google Earth)
• Search Data sources (satellite & couverture nuageuse) Time range
• Aperçu & Télécharger
6
2. Plateformes d'accès à l'imagerie satellitaire : USGS
• USGS : United States Geological Survey
• USGS : organisme américain dédié aux sciences de la Terre
• USGS EarthExplorer : portail officiel d’accès à l’imagerie satellitaire et aérienne d’USGS
• https://earthexplorer.usgs.gov/
• Pratique
• Créer un compte et se connecter
• KML/Shapefile Upload (Google Earth) OU Add Coordinate
• Date Range : intervalle de dates
• Cloud Cover : couverture nuageuse
• Data Sets
• Results
• Aperçu & Télécharger (certains fichier : select files ou tous les fichies : All Files)
7
3. Télédétection et Python
Chargement d'une image satellite 1/5
• Télécharger l’image Sentinel-2A correspondant au fichier KML "Parc W"
• ID : S2A_MSIL1C_20240626T101031_N0510_R022_T31PDP_20240626T160811
• Sensing time: 2024-06-26T10:10:31.024Z
• Size: 790MB
• Décompresser le fichier
• Sélectionner les fichiers correspondant aux :
• bandes : Red, Green, Blue, NIR
• résolution spatiale : 10 m
• Créez un notebook sur Google Colab Bandes Sentinel-2
https://colab.research.google.com Crédit : Kaplan & Avdan, 2016
• Importer les fichiers sélectionnés 8
3. Télédétection et Python
Chargement d'une image satellite 2/5
Saisissez puis exécutez le code suivant
# Prérequis
import os
import glob as glob
import numpy as np
!pip install rasterio
import rasterio
from rasterio import plot
from rasterio.plot import show
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.colors
from matplotlib.colors import BoundaryNorm, ListedColormap
from matplotlib.cm import get_cmap
from matplotlib.axes import Axes
from IPython.display import HTML
from skimage import exposure
9
3. Télédétection et Python
Chargement d'une image satellite 3/5
Saisissez puis exécutez le code suivant
# Ouverture des fichiers pour chaque bande
band2 = rasterio.open("T31PDP_20240626T101031_B02.jp2")
band3 = rasterio.open("T31PDP_20240626T101031_B03.jp2")
band4 = rasterio.open("T31PDP_20240626T101031_B04.jp2")
band8 = rasterio.open("T31PDP_20240626T101031_B08.jp2")
10
3. Télédétection et Python
Chargement d'une image satellite 4/5
Saisissez puis exécutez le code suivant
# Metadonnées
meta = band2.meta
meta.update({"count": 3})
rgb_path = '2024-06-26_T101031_S2_RGB.tif'
# Composite de couleur naturelle
# prend du temps
# la bande 8 sera utilisée plus tard
with rasterio.open(rgb_path, 'w', **meta) as dest:
dest.write(band2.read(1),1)
dest.write(band3.read(1),2)
dest.write(band4.read(1),3)
# Télécharger l’image et l’ouvrir sous QGIS (l’ouverture plante dans Colab)
11
3. Télédétection et Python
Chargement d'une image satellite 5/5
12
3. Télédétection et Python
Calcul d'indices de végétation
Saisissez puis exécutez le code suivant
# NDVI : (nir - red)/(nir + red)
red = band4.read()
nir = band8.read()
ndvi = (nir.astype(float) - red.astype(float)) / (nir+red)
# Construction de l'image NDVI
meta = band4.meta
meta.update(driver='GTiff')
meta.update(dtype=rasterio.float32)
ndvi_path = '2024-06-26_T101031_S2_ndvi.tif'
with rasterio.open(ndvi_path, 'w', **meta) as dest:
dest.write(ndvi.astype(rasterio.float32))
# Télécharger l’image puis l’ouvrir dans QGIS
13
3. Télédétection et Python
Calcul d'indices de végétation
14
4. Télédétection et Machine Learning
Couverture du sol par apprentissage non supervisé 1/5
Importer le fichier "South_coast.tif" dans Colab
https://github.com/acgeospatial/Satellite_Imagery_Python/raw/maste
r/Training_data/South_coast.tif
Saisissez puis exécutez le code suivant
# Prérequis
from sklearn import cluster
from osgeo import gdal, gdal_array
import matplotlib.pyplot as plt
15
4. Télédétection et Machine Learning
Couverture du sol par apprentissage non supervisé 2/5
Saisissez puis exécutez le code suivant
# Chargement de l'image
img_ds = gdal.Open('South_coast.tif', gdal.GA_ReadOnly)
img = np.zeros((
img_ds.RasterYSize,
img_ds.RasterXSize,
img_ds.RasterCount),
gdal_array.GDALTypeCodeToNumericTypeCode(
img_ds.GetRasterBand(1).DataType))
for b in range(img.shape[2]):
img[:, :, b] = img_ds.GetRasterBand(b + 1).ReadAsArray()
16
4. Télédétection et Machine Learning
Couverture du sol par apprentissage non supervisé 3/5
Saisissez puis exécutez le code suivant
# Shape
new_shape = (img.shape[0] * img.shape[1], img.shape[2])
# Valeurs d'entrée
X = img[:, :, :13].reshape(new_shape)
# Clustering
k_means = cluster.KMeans(n_clusters=8)
k_means.fit(X)
X_cluster = k_means.labels_
X_cluster = X_cluster.reshape(img[:, :, 0].shape)
17
4. Télédétection et Machine Learning
Couverture du sol par apprentissage non supervisé 4/5
Saisissez puis exécutez le code suivant
# Affichage du clustering
plt.figure(figsize=(20,20))
plt.imshow(X_cluster, cmap="hsv")
plt.show()
18
4. Télédétection et Machine Learning
Couverture du sol par apprentissage non supervisé 5/5
19
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 1/1`9
Importer les fichiers s2image.tif, samples.* et temp_y_points.* dans Colab
https://github.com/waleedgeo/lulc_py/tree/main/materials
Saisissez puis exécutez le code suivant
! pip install rasterio
import rasterio
from rasterio.plot import show
import numpy as np
import geopandas as gpd
import fiona
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import sklearn
from sklearn.metrics import classification_report, accuracy_score
20
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 2/19
Saisissez puis exécutez le code suivant
# nom des fichiers
raster_loc = 's2image.tif'
points_loc = 'samples.shp'
temp_point_loc = 'temp_y_points.shp'
# Labels
lulc_name = ['Water', 'Dense Veg', 'Veg', 'Impervious']
21
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 3/19
Image du site et des points d’échantillonnage (en jaune) sous QGIS 22
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 4/19
Saisissez puis exécutez le code suivant
# Ouverture du fichier raster
src = rasterio.open(raster_loc)
# bandes
blue = src.read(1, masked=True)
green = src.read(2, masked=True)
red = src.read(3, masked=True)
nir = src.read(4, masked=True)
23
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 5/19
Saisissez puis exécutez le code suivant
# Fonction de normalisation des bandes (à l'échelle entre
0 et 1)
def normalize(array):
array_min, array_max = array.min(), array.max()
return ((array - array_min)/(array_max - array_min))
# Normalisation
redn = normalize(red)
greenn = normalize(green)
bluen = normalize(blue)
nirn = normalize(nir)
24
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 6/19
Saisissez puis exécutez le code suivant
# lecture de bandes
with rasterio.open(raster_loc) as img:
bands = (img.read()).shape[0]
print('Bandes: ', bands)
# Liste des bandes
features = []
for i in range(bands):
features.append('band'+str(i+1))
print(Nom des bandes: ', features)
f_len = len(features)
25
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 7/19
Saisissez puis exécutez le code suivant
points = gpd.read_file(points_loc)
# Ajout colonne ID
points = points.assign(id=range(len(points)))
# sauvegarde des points avec ID
points.to_file(temp_point_loc)
# conversion de GeoPandaDataframe en DataFrame
points_df = pd.DataFrame(points.drop(columns='geometry'))
# Série Panda
sampled = pd.Series()
26
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 8/19
Saisissez puis exécutez le code suivant
# Lecture du fichier shape et itération pour chaque caractéristique
with fiona.open(temp_point_loc) as shp:
for feature in shp:
siteID = feature['properties']['id']
coords = feature['geometry']['coordinates']
# lecture de la valeur du pixel
with rasterio.open(raster_loc) as stack_src:
value = [v for v in stack_src.sample([coords])]
# Mise à jour de la série
sampled.loc[siteID] = value
27
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 9/19
Saisissez puis exécutez le code suivant
# Ajout des bandes en tant que colonnes
df1 = pd.DataFrame(sampled.values.tolist(),
index=sampled.index)
df1['id'] = df1.index
df1
# Exécuter dans une autre cellule
df1 = pd.DataFrame(df1[0].values.tolist(),
columns=features)
df1['id'] = df1.index
df1 28
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 10/19
Saisissez puis exécutez le code suivant
# Fusion des valeurs des pixels pour chaque bande
# avec les étiquettes
data = pd.merge(df1, points_df, on ='id')
print('Données échantillonnées: \n',data)
x = data.iloc[:,0:f_len]
X = x.values
y = data.iloc[:,-1]
Y = y.values
29
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 11/19
Saisissez puis exécutez le code suivant
# Fractionnement des valeurs d'entraînement et de test
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,
Y, test_size=0.30, stratify = Y)
print(f'X_train Shape: {X_train.shape}\
\nX_test Shape: {X_test.shape}\
\ny_train Shape: {y_train.shape}\
\ny_test Shape:{y_test.shape}')
30
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 12/19
Saisissez puis exécutez le code suivant
# Apprentissage SVM
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix
cName = 'SVM'
clf = SVC(kernel='rbf')
clf.fit(X_train, y_train)
clf_pred = clf.predict(X_test)
print(f"Accuracy {cName}: {accuracy_score(y_test, clf_pred)*100}")
print(classification_report(y_test, clf_pred))
31
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 13/19
Saisissez puis exécutez le code suivant
# Matrice de confusion
cm = confusion_matrix(y_test, clf_pred)
print('Confusion Matrix \n',cm)
cm_percent = cm/np.sum(cm)
32
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 14/19
Saisissez puis exécutez le code suivant
plt.figure(figsize=(7, 7), facecolor='w', edgecolor='k')
sns.set(font_scale=1.5)
sns.heatmap(cm_percent,
xticklabels=lulc_name,
yticklabels=lulc_name,
cmap="YlGn",
annot=True,
fmt='.2%',
cbar=False,
linewidths=2,
linecolor='black')
plt.title(cName)
plt.xlabel('Prédite')
plt.ylabel('Actuelle') 33
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 15/19
Saisissez puis exécutez le code suivant
%%time
exp_name = 'lulc_SVM.tif'
img = rasterio.open(raster_loc)
img_arr = img.read()
bands = img_arr.shape[0]
print(f'Hauteur: {img_arr.shape[1]}\
\nLargeur: {img_arr.shape[2]}\
\nBandes: {img_arr.shape[0]}\n')
34
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 16/19
Saisissez puis exécutez le code suivant
img_n = np.moveaxis(img_arr, 0, -1)
img_n = img_n.reshape(-1, f_len)
print('Shape des prédictions pour toutes les données: ',img_n.shape)
metadata = img.meta
height = metadata.get('height')
width = metadata.get('width')
crs = metadata.get('crs')
transform = metadata.get('transform')
# Prédiction sur toutes les données
pred_full = clf.predict(img_n)
35
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 17/19
Saisissez puis exécutez le code suivant
# Export du raster
img_reshape = pred_full.reshape(height, width)
out_raster = rasterio.open(exp_name,
'w',
driver='GTiff',
height=height,
width=width,
count=1,
dtype='uint8',
crs=crs,
transform = transform,
nodata = 255 #nodata
)
out_raster.write(img_reshape, 1)
out_raster.close()
# Télécharger et ouvrir le raster sous QGIS et y ajouter la légende 36
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 18/19
37
4. Télédétection et Machine Learning
Couverture du sol par apprentissage supervisé 19/19
38
5. Ressources
• Brief Introduction to Remote Sensing
https://semiautomaticclassificationmanual.readthedocs.io/it/latest/remote_se
nsing.html
• Sentinel-2 MSI Level 2A - Composite Imagery, Normalized Burn Ratio
and Burn Severity
https://fire.trainhub.eumetsat.int/docs/figure5678_Sentinel-2.html
• K-means in Python 3 on Sentinel 2 data
http://www.acgeospatial.co.uk/k-means-sentinel-2-python/
• Mastering Machine Learning based Land Use Classification with
Python: A Comprehensive Guide!
https://waleedgeo.medium.com/lulc-py-78cb954673d
39