Télédétection et machine
learning avec Python
Souleymane BAH
bsouleymane@[Link]
[Link]
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
• [Link]
• 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
• [Link]
• 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
[Link] 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 [Link] import show
%matplotlib inline
import [Link] as plt
import [Link]
from [Link] import BoundaryNorm, ListedColormap
from [Link] import get_cmap
from [Link] import Axes
from [Link] 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 = [Link]("T31PDP_20240626T101031_B02.jp2")
band3 = [Link]("T31PDP_20240626T101031_B03.jp2")
band4 = [Link]("T31PDP_20240626T101031_B04.jp2")
band8 = [Link]("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 = [Link]
[Link]({"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 [Link](rgb_path, 'w', **meta) as dest:
[Link]([Link](1),1)
[Link]([Link](1),2)
[Link]([Link](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 = [Link]()
nir = [Link]()
ndvi = ([Link](float) - [Link](float)) / (nir+red)
# Construction de l'image NDVI
meta = [Link]
[Link](driver='GTiff')
[Link](dtype=rasterio.float32)
ndvi_path = '2024-06-26_T101031_S2_ndvi.tif'
with [Link](ndvi_path, 'w', **meta) as dest:
[Link]([Link](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
[Link]
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 [Link] 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 = [Link]('South_coast.tif', gdal.GA_ReadOnly)
img = [Link]((
img_ds.RasterYSize,
img_ds.RasterXSize,
img_ds.RasterCount),
gdal_array.GDALTypeCodeToNumericTypeCode(
img_ds.GetRasterBand(1).DataType))
for b in range([Link][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 = ([Link][0] * [Link][1], [Link][2])
# Valeurs d'entrée
X = img[:, :, :13].reshape(new_shape)
# Clustering
k_means = [Link](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
[Link](figsize=(20,20))
[Link](X_cluster, cmap="hsv")
[Link]()
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 [Link], samples.* et temp_y_points.* dans Colab
[Link]
Saisissez puis exécutez le code suivant
! pip install rasterio
import rasterio
from [Link] import show
import numpy as np
import geopandas as gpd
import fiona
import [Link] as plt
import seaborn as sns
import pandas as pd
import sklearn
from [Link] 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 = '[Link]'
points_loc = '[Link]'
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 = [Link](raster_loc)
# bandes
blue = [Link](1, masked=True)
green = [Link](2, masked=True)
red = [Link](3, masked=True)
nir = [Link](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 = [Link](), [Link]()
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 [Link](raster_loc) as img:
bands = ([Link]()).shape[0]
print('Bandes: ', bands)
# Liste des bandes
features = []
for i in range(bands):
[Link]('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 = [Link](id=range(len(points)))
# sauvegarde des points avec ID
points.to_file(temp_point_loc)
# conversion de GeoPandaDataframe en DataFrame
points_df = [Link]([Link](columns='geometry'))
# Série Panda
sampled = [Link]()
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 [Link](temp_point_loc) as shp:
for feature in shp:
siteID = feature['properties']['id']
coords = feature['geometry']['coordinates']
# lecture de la valeur du pixel
with [Link](raster_loc) as stack_src:
value = [v for v in stack_src.sample([coords])]
# Mise à jour de la série
[Link][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 = [Link]([Link](),
index=[Link])
df1['id'] = [Link]
df1
# Exécuter dans une autre cellule
df1 = [Link](df1[0].[Link](),
columns=features)
df1['id'] = [Link]
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 = [Link](df1, points_df, on ='id')
print('Données échantillonnées: \n',data)
x = [Link][:,0:f_len]
X = [Link]
y = [Link][:,-1]
Y = [Link]
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 [Link] import SVC
from [Link] import confusion_matrix
cName = 'SVM'
clf = SVC(kernel='rbf')
[Link](X_train, y_train)
clf_pred = [Link](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/[Link](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
[Link](figsize=(7, 7), facecolor='w', edgecolor='k')
[Link](font_scale=1.5)
[Link](cm_percent,
xticklabels=lulc_name,
yticklabels=lulc_name,
cmap="YlGn",
annot=True,
fmt='.2%',
cbar=False,
linewidths=2,
linecolor='black')
[Link](cName)
[Link]('Prédite')
[Link]('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 = [Link](raster_loc)
img_arr = [Link]()
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 = [Link](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 = [Link]
height = [Link]('height')
width = [Link]('width')
crs = [Link]('crs')
transform = [Link]('transform')
# Prédiction sur toutes les données
pred_full = [Link](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 = [Link](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
[Link]
[Link]
• Sentinel-2 MSI Level 2A - Composite Imagery, Normalized Burn Ratio
and Burn Severity
[Link]
• K-means in Python 3 on Sentinel 2 data
[Link]
• Mastering Machine Learning based Land Use Classification with
Python: A Comprehensive Guide!
[Link]
39