Classification d'objets et inversion de paramètres par télédétection avec apprentissage automatique - Implémentation avec la forêt aléatoire

Vue d'ensemble

Ce guide s'adresse aux utilisateurs souhaitant exploiter Python en local pour la classification d'objets sur des images de télédétection via l'apprentissage automatique, ou pour l'inversion de paramètres (régression). Il couvre la configuration de l'environnement de développement Python, l'installation des bibliothèques tierces, l'acquisition et le prétraitement des données géospatiales, l'entraînement et la prédiction des modèles, ainsi que l'évaluation des résultats. L'approche est illustrée avec la forêt aléatoire pour l'extraction de masses d'eau (classification) et la régression de l'indice NDWI.

Mots-clés : apprentissage automatique, télédétection, classification, régression, Python

  1. Configuration logicielle

Les outils principaux requis sont : un SIG comme ArcGIS ou QGIS, un logiciel de traitement d'images tel que ENVI, ainsi que l'environnement Python Anaconda et l'IDE PyCharm.

Les bibliothèques Python nécessaires incluent GDAL, scikit-learn, et numpy.

1.1 Installation d'Anaconda

Téléchargez le programme d'installation depuis un miroir fiable, par exemple via l'Index d'archives d'Anaconda de l'Université de Tsinghua. Exécutez l'installateur avec des privilèges administrateur. Suivez les étapes en acceptant le contrat de licence, en sélectionnant l'option "All Users" si désiré, et en définissant le répertoire d'installation. Finalisez l'installation et attendez la complétion.

1.2 Installation de PyCharm

Obtenez la version communautaire de PyCharm depuis le site JetBrains. Lancez le fichier d'installation .exe, choisissez un chemin sans espaces ou caractères spéciaux, cochez toutes les options d'intégration, et installez. Une fois terminé, vous pouvez localiser et installer le plugin de langue chinoise simplifiée via File -> Settings -> Plugins pour l'interface en chinois.

1.3 Configuration de l'environnement Python

Dans Anaconda Navigator, créez un nouvel environnement avec une version spécifique de Python, par exemple 3.8. Nommez-le de manière descriptive. Dans cet environnement, installez les paquets GDAL, scikit-learn et numpy via l'onglet "Not Installed" en les cherchant et en appliquant les changements. Pour utiliser cet environnement dans PyCharm, créez un nouveau projet et sélectionnez l'interpréteur Conda correspondant dans les paramètres.

  1. Préparation des données

Les données nécessaires comprennent une image de télédétection (ex. Landsat 8) et des étiquettes de référence, obtenues par interprétation visuelle.

2.1 Acquisition des données

Pour télécharger des images Landsat 8, utilisez des portails comme le Cloud de données géospatiales. Inscrivez-vous, naviguez dans les ressources publiques, et utilisez la recherche avancée pour filtrer par étendue spatiale, période et couverture nuageuse. Par exemple, recherchez des images près du lac Taihu en janvier 2023 avec une couverture nuageuse inférieure à 5%. Téléchargez l'archive, extrayez-la, et combinez les bandes spectrales (1-7) en un seul fichier GeoTIFF à l'aide d'un outil comme ENVI (via Layer Stacking) et exportez le résultat au format TIFF.

2.2 Traitement des données

Pour les étiquettes de classification, créez des polygones dans un SIG, puis convertissez-les en raster aligné sur l'image de télédétection. Pour la régression, les données de terrain (ex. mesures in situ) peuvent être interpolées ou converties en raster de manière similaire.

  1. Classification d'objets (tâche de classification)

3.1 Chargement des données

Ouvrez le dossier du projet dans PyCharm, assurez-vous que l'environnement Python avec les bibliothèques requises est sélectionné. Créez un script Python, par exemple "classification_rf.py".

3.2 Prétraitement des données

Chargez l'image raster et les étiquettes, puis structurez-les en une matrice tabulaire où les colonnes représentent les bandes spectrales et la classe. Éliminez les pixels sans étiquette.

from osgeo import gdal
import numpy as np
from sklearn.model_selection import train_test_split

def load_raster(file_path):
    dataset = gdal.Open(file_path)
    proj = dataset.GetProjection()
    geotrans = dataset.GetGeoTransform()
    width = dataset.RasterXSize
    height = dataset.RasterYSize
    bands = dataset.RasterCount
    data = dataset.ReadAsArray()
    return proj, geotrans, width, height, data

# Charger l'image et les étiquettes
img_proj, img_geotrans, img_width, img_height, band_data = load_raster('path/to/image.tif')
label_proj, label_geotrans, label_width, label_height, label_array = load_raster('path/to/labels.tif')

# Aplatir et combiner les données
num_bands = band_data.shape[0]
flat_bands = band_data.reshape(num_bands, -1).T
flat_labels = label_array.reshape(-1, 1)
combined = np.hstack([flat_bands, flat_labels])
valid_mask = ~np.any(np.isnan(combined), axis=1)
clean_data = combined[valid_mask]

Divisez le jeu de données nettoyé en sous-ensembles d'entraînement et de test.

features = clean_data[:, :num_bands]
targets = clean_data[:, num_bands]
X_train, X_test, y_train, y_test = train_test_split(features, targets, test_size=0.3, random_state=42)

3.3 Entraînement du modèle

Initialisez et entraînez un classificateur de forêt aléatoire, puis sauvegardez le modèle.

from sklearn.ensemble import RandomForestClassifier
import joblib

forest_clf = RandomForestClassifier(n_estimators=50, max_depth=10, n_jobs=-1, random_state=42)
forest_clf.fit(X_train, y_train)
joblib.dump(forest_clf, 'random_forest_classifier.pkl')

3.4 Évaluation de la précision

Chargez le modèle sauvegardé, effectuez des prédictions sur l'ensemble de test, et calculez les métriques de performance.

from sklearn.metrics import confusion_matrix, accuracy_score

loaded_model = joblib.load('random_forest_classifier.pkl')
y_pred = loaded_model.predict(X_test)
conf_mat = confusion_matrix(y_test, y_pred)
accuracy = accuracy_score(y_test, y_pred)
print(f"Matrice de confusion: {conf_mat}")
print(f"Précision: {accuracy}")

3.5 Prédiction sur l'image complète

Appliquez le modèle à tous les pixels de l'image pour générer une carte de classification, et sauvegardez-la en tant que GeoTIFF.

def save_raster(output_path, proj, geotrans, data_array):
    driver = gdal.GetDriverByName('GTiff')
    rows, cols = data_array.shape
    dataset = driver.Create(output_path, cols, rows, 1, gdal.GDT_Float32)
    dataset.SetProjection(proj)
    dataset.SetGeoTransform(geotrans)
    band = dataset.GetRasterBand(1)
    band.WriteArray(data_array)
    dataset.FlushCache()

# Prédiction sur toutes les données
full_features = combined[:, :num_bands]
full_pred = loaded_model.predict(full_features)
pred_image = full_pred.reshape(img_height, img_width)
save_raster('classification_result.tif', img_proj, img_geotrans, pred_image)

  1. Inversion de paramètres (tâche de régression)

Pour illustrer la régression, nous utilisons l'Indice d'Eau Normalisé (NDWI) comme variable cible simulée, calculé à partir des bandes spectrales.

4.1 Chargement des données et calcul du NDWI

Chargez l'image et dérivez le NDWI, puis préparez les données pour la régression.

img_proj, img_geotrans, img_width, img_height, band_data = load_raster('path/to/image.tif')
# Simuler le NDWI : (Bande3 - Bande5) / (Bande3 + Bande5)
band3 = band_data[2].astype(np.float64)
band5 = band_data[4].astype(np.float64)
ndwi_values = (band3 - band5) / (band3 + band5)

# Combiner et nettoyer
num_bands = band_data.shape[0]
flat_bands = band_data.reshape(num_bands, -1).T
flat_ndwi = ndwi_values.reshape(-1, 1)
regression_data = np.hstack([flat_bands, flat_ndwi])
valid_mask = ~np.any(np.isnan(regression_data), axis=1)
clean_reg_data = regression_data[valid_mask]

4.2 Prétraitement

Divisez les données nettoyées pour l'entraînement et le test.

features_reg = clean_reg_data[:, :num_bands]
targets_reg = clean_reg_data[:, num_bands]
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(features_reg, targets_reg, test_size=0.5, random_state=123)

4.3 Entraînement du modèle

Entraînez un modèle de forêt aléatoire pour la régression.

from sklearn.ensemble import RandomForestRegressor

forest_reg = RandomForestRegressor(n_estimators=50, max_depth=8, n_jobs=-1, random_state=123)
forest_reg.fit(X_train_reg, y_train_reg)
joblib.dump(forest_reg, 'random_forest_regressor.pkl')

4.4 Évaluation

Évaluez les performances sur l'ensemble de test avec des métriques adaptées à la régression.

from sklearn.metrics import mean_squared_error, r2_score

loaded_reg_model = joblib.load('random_forest_regressor.pkl')
y_pred_reg = loaded_reg_model.predict(X_test_reg)
mse = mean_squared_error(y_test_reg, y_pred_reg)
r2 = r2_score(y_test_reg, y_pred_reg)
print(f"Erreur quadratique moyenne: {mse}")
print(f"Score R2: {r2}")

4.5 Prédiction et exportation

Générez une carte prédite du NDWI pour l'image entière et sauvegardez-la.

full_features_reg = combined_reg[:, :num_bands]
ndwi_pred = loaded_reg_model.predict(full_features_reg)
ndwi_map = ndwi_pred.reshape(img_height, img_width)
save_raster('ndwi_prediction.tif', img_proj, img_geotrans, ndwi_map)

Note : Les valeurs absolues du NDWI prédit peuvent varier en fonction de la calibration radiométrique des données d'origine, mais la distribution spatiale relative devrait être préservée, avec des valeurs plus élevées pour l'eau et plus basses pour les terres émergées.

Étiquettes: forêt aléatoire télédétection apprentissage automatique Classification Régression

Publié le 20 juin à 05h36