3 Base de Google Earth Engine – La manipulation d’image
Après avoir acquis les savoir-faire de base en JavaScript dans le chapitre 2, nous passons maintenant aux manipulations directes de l’API de Google Earth Engine.
Chargement d’une image dans GEE
Pour commencer, nous allons importer une image du satellite Sentinel-2 en utilisant son identifiant d’image et la placer dans une variable appelée image.
Dans le cas où vous voulez récupérer les métadonnées de l’image, vous devez utiliser la fonction print et cela imprimera les métadonnées dans la « Console » (Figure 21).
Pour chaque ligne avec une flèche d’expansion à côté, vous pouvez cliquer, et plus d’informations apparaitront. Par exemple, dans le cas ci-dessus, nous avons développé les métadonnées de la section des bandes. Comme vous pouvez le voir, cela nous montre le nom des bandes ainsi que leur type de données, leur système de projection cartographique et la dimension de l’image dans cette bande spécifique (car la résolution spatiale diffère d’une bande à l’autre). Si vous avez eu des difficultés à comprendre les métadonnées, vous pouvez consulter les informations fournies par GEE dans le champ de recherche situé au-dessus du panneau « Code Editor » (Figure 22).
Il y a deux façons d’accéder à la description des métadonnées :
- en cliquant sur « Browse data catalog » et en sélectionnant le jeu de données que vous utilisez;
- en tapant le nom du jeu de données dans la « Search Box » (dans cet exemple, il s’agit de Sentinel-2) (Figure 23).
Le résultat sera le suivant :
Après avoir cliqué sur le nom de votre jeu de données (dans ce cas, Sentinel-2, Level-1C), vous devriez voir cette boîte de dialogue (Figure 24) :
Visualisation de l’image
L’étape suivante consiste à visualiser notre image. Pour ce faire, nous devons utiliser une simple ligne de code comme ci-dessous :
Le résultat sera le suivant (Figure 25) :
Comme vous l’avez remarqué, la visualisation n’est pas adéquate car nous n’avons pas utilisé d’arguments de visualisation d’image pour améliorer le rendu de l’image. Afin d’obtenir de meilleurs résultats dans notre visualisation, nous ajoutons quelques paramètres supplémentaires en marge de l’affichage de l’image (Figure 26).
Voici les quatre arguments de la commande Map.addLayer ci-dessus :
- image : l’imagerie que nous voulons afficher sur la carte;
- bands : les bandes sélectionnées dans l’imagerie à afficher sur la carte. Dans ce cas, nous avons choisi les bandes avec le nom de ‘B4’, ‘B3’ et ‘B2’ comme bandes RVB selon la description de l’ensemble de données que nous avons utilisé. Vous pouvez utiliser une combinaison différente de bandes et l’afficher comme une image composite en fausses couleurs;
- min, max : représente l’étendue des valeurs numériques affichées sur la carte. Les valeurs par défaut sont 8000 et 17000 comme min et max, respectivement;
- ‘Sentinel-2 Level-1C‘ : l’étiquette pour les données que vous visualisez sur la carte. Elle apparaitra dans la liste des couches du « Gestionnaire de couches », en haut à droite de la carte.
Il existe un autre moyen d’améliorer la visualisation des images sans spécifier d’argument. Vous devez passer la souris sur le « Gestionnaire de couches » et cliquer sur l’engrenage. Cela vous ouvrira un autre panneau appelé « paramètres de visualisation », où vous pourrez essayer différents types d’équilibrage radiométrique pour une seule bande ou trois bandes de votre imagerie. Après avoir défini les paramètres de visualisation, vous pouvez les appliquer à l’affichage de la carte, et lorsque vous trouvez le meilleur réglage, importez-le dans l’éditeur de code (il apparaitra dans la section « Imports » en haut du script dans le panneau de l’éditeur de code) et utilisez-le comme ci-dessous (Figure 27) :
Astuce
Si vous voulez simplement visualiser une couche sans aucun paramètre de visualisation mais que vous comptez spécifier une étiquette, vous devez mettre {} ou null ou undefined dans l’argument des paramètres de visualisation de l’image.
Map.addLayer(image, null, ‘Sentinel-2 Level-1C’) ;
Malgré ce paramétrage, il reste toujours une lacune avec notre visualisation et c’est que nous devons déplacer la carte à l’endroit où l’image est affichée dans la carte. Afin de palier à cette situation, la solution simple est d’utiliser la commande Map.centerObject.
Tout d’abord, placez un marqueur sur la zone que l’imagerie doit afficher (une fois que vous avez créé un marqueur sur la carte, une géométrie est créée en haut du panneau de votre éditeur de code) et utilisez la commande. Le premier argument à fournir à Map.centerObject est la géométrie (geometry) que nous avons définie comme notre zone d’intérêt (ici nous l’avons arbitrairement nommée geometry) et le second argument est l’échelle de zoom (ici 10) que vous souhaitez que la carte affiche à l’écran (Figure 28).
Manipulation de l’image
La sélection des bandes
Pour sélectionner les bandes à afficher d’une image, il y a deux avenues possibles :
- .select([var_args]); : Sélectionner les bandes à afficher en utilisant leur nom d’origine (Figure 29);
- .select([var_args],[nouveaux_nom]); : Sélectionner les bandes à afficher en utilisant leur nom d’origine et en leur réassignant un nouveau nom plus significatif (Figure 30).
Astuce
Comment connaître les noms des bandes ?
Il y a deux façons courantes (Figure 31):
- en ouvrant la boîte de dialogue des données que vous utilisez à ce moment-là;
- en imprimant simplement l’image et en cliquant sur la flèche d’expansion à côté des bandes.
Astuce
Astuce
Il existe trois manières de créer la liste des bandes :
- En sélectionnant les bandes individuellement :
[‘B4′,’B3′,’B2’]
- En sélectionnant les bandes par gamme (range):
[‘B[2-4]’]
- En sélectionnant les bandes via une expression rationelle (RegEx)
[‘B*’]
Opérations arithmétiques
Les opérations arithmétiques entre les bandes d’une image se déclinent avec des noms qui sont instinctifs. Voyons un exemple afin de mieux comprendre :
var image = ee.Image(‘COPERNICUS/S2_SR/20210109T185751_20210109T185931_T10SEG’);
// Sélection individuelle de deux bandes distinctes
var swir1 = image.select(‘B11’);
var swir2 = image.select(‘B12’);
.add |
var addition = swir1.add(swir2); |
.subtract |
var subtraction = swir1.subtract(swir2); |
.multiply |
var multiplication = swir1.multiply(swir2); |
.divide |
var division = swir1.divide(swir2); |
Apprenez-en plus sur les opérateurs en consultant ce lien (+ sur les opérateurs arithmétiques GEE).
Imprimons donc l’un des calculs ci-dessus et voyons-le (Figure 32) :
Comme vous le voyez, GEE a nommé la multiplication de manière aléatoire en choisissant simplement le nom du groupe original (c’est-à-dire ‘B11‘) mais nous voulons que nos noms d’impression et d’image soient descriptifs. C’est pourquoi nous vous montrons ici comment renommer une image de manière explicite.
Renommer une image
Comme nous l’avons mentionné plus haut, lorsque vous effectuez un calcul, tel que le calcul d’un index à partir d’une image, GEE choisira un nom pour votre nouvelle image, et ce nom ne sera pas descriptif.
Donc, pour éviter toute confusion et pouvoir travailler plus efficacement avec les images calculées, nous devons les renommer. Nous prenons le dernier exemple et vous montrons la différence lorsque vous utilisez rename (Figure 33):
Concaténation
Concaténer les images données en une seule image qui contient toutes les bandes de toutes les images (Figure 34).
Calcul de ratios de bandes (index spectraux)
Avec ce que nous avons appris jusqu’à présent, nous pouvons calculer des ratios spectraux ((A-B)/A+B)) à partir d’images. Il existe différentes façons de le faire. Nous vous présentons ici deux des techniques les plus couramment utilisées pour calculer le NDVI.
- normalizedDifference : Calcule la différence normalisée entre deux bandes. La différence normalisée est calculée comme suit : (première – deuxième) / (première + deuxième).
Attention : Notez que le nom de la bande d’image renvoyée est ‘nd’, que les propriétés de l’image d’entrée ne sont pas conservées dans l’image de sortie et qu’une valeur de pixel négative dans l’une ou l’autre bande d’entrée entraînera le masquage du pixel de sortie. Pour éviter de masquer les valeurs négatives en entrée, utilisez ee.Image.expression pour calculer la différence normalisée.
// Importer l’image Landsat8 de réfectance.
var image = ee.Image(‘LANDSAT/LC08/C01/T1_SR/LC08_015028_20210529’);
// Sélectionner et renommer les bandes.
Var image = image.select([‘B5’,‘B4’,‘B2’],[‘nir’,‘red’,‘blue’]).clip(montreal);
// Calcul de la différence normalisée (NDVI).
// NDVI = (NIR – Red) / (NIR + Red)var ndvi = image.normalizedDifference([‘nir’,‘red’]);
// Afficher le NDVI.
var ndviParams = {min: -1, max: 1, palette: [‘blue’, ‘white’, ‘green’]};
Map.addLayer(ndvi, ndviParams, ‘NDVI Image’);
- .expression : Calcule en utilisant une expression arithmétique (Figure 35).
// Importer l’image Landsat8 de réfectance.
var image = ee.Image(‘LANDSAT/LC08/C01/T1_SR/LC08_015028_20210529’);
// Sélectionner et renommer les bandes.
Var image = image.select([‘B5’,‘B4’,‘B2’],[‘nir’,‘red’,‘blue’]).clip(montreal);
// Calcul de la différence normalisée (NDVI).
// NDVI = (NIR – Red) / (NIR + Red)// Calculer l’index grâce à une expression.
var ndvi = image.expression(‘(NIR – Red) / (NIR + Red)’, {‘NIR’: image.select(‘nir’), ‘Red’: image.select(‘red’)});
// Display NDVI results.
var ndviParams = {min: -1, max: 1, palette: [‘blue’, ‘white’, ‘green’]};
Map.addLayer(ndvi, ndviParams, ‘NDVI Image’);
Ajouter une bande à une image
On ajoute une bande à une image avec la fonction suivante.
Dans cet exemple, le NDVI calculé est ajouté à l’image originale comme une nouvelle bande. Vous pouvez voir le résultat de l’impression dans « Console » (Figure 36).
Opérations booléennes, relationnelles et conditionnelles
Les objets ee.Image disposent d’un ensemble de méthodes booléennes, relationnelles et conditionnelles permettant de construire des règles et des expressions décisionnelles.
Les résultats de ces méthodes permettent de limiter l’analyse à des pixels ou des régions spécifiques grâce au masquage, à l’élaboration de cartes classées et à la réaffectation de valeurs.
Opérations Booléennes
- .and : Il retournera vrai si les deux conditions étaient vraies.
- .or : Il retournera vrai si au moins l’une des conditions était vraie.
- .not : Il retournera vrai si aucune des conditions n’est vraie.
Opérations relationnelles
- .eq : Il retournera vrai si les deux valeurs sont égales.
- .gt : Il retournera vrai si la première valeur est supérieure à la seconde.
- .gte : Il retournera vrai si la première valeur est supérieure ou égale à la seconde.
- .lt : Il retournera vrai si la première valeur est inférieure à la seconde.
- .lte : Il retournera vrai si la première valeur est inférieure ou égale à la seconde.
Opérations conditionnelles
- .Where : Effectue un remplacement conditionnel des valeurs.
Maintenant, pour comprendre ce que ces opérations peuvent réellement faire et comment elles fonctionnent ensemble, nous utilisons un exemple qui a la combinaison de tous les opérateurs ci-dessus (Figure 37).
// Cet exemple effectue une classification basée sur les règles du code prédéfinies.
var image = ee.Image(‘LANDSAT/LC08/C01/T1_SR/LC08_015028_20210529’);
Map.addLayer(image, {bands:[‘B4’,‘B3’,‘B2’], min:108, max:1848}, ‘L8 Image’);
var image = image.select([‘B7’,‘B5’,‘B4’,‘B2’],[‘swir’,‘nir’,‘red’,‘blue’]);
var ndvi = image.normalizedDifference([‘nir’,‘red’]).rename(‘NDVI’);
var ndwi = image.normalizedDifference([‘blue’,‘swir’]).rename(‘NDWI’);
var swir = image.select([‘swir’]);
var ndviParams = {min: -1, max: 1, palette: [‘blue’, ‘white’, ‘green’]};
var ndwiParams = {min: -1, max: 1, palette: [‘green’, ‘white’, ‘blue’]};
Map.addLayer(ndvi, ndviParams, ‘NDVI Image’);
Map.addLayer(ndwi, ndwiParams, ‘NDWI Image’);
var dem = ee.Image(‘USGS/SRTMGL1_003’).clip(image.geometry());
Map.addLayer(dem, {min: 2, max: 779}, ‘SRTM DEM’);
//’regle1′: remplace chaque pixel qui présente un ndvi >= 0.7 par 0.
//’regle2′: remplace chaque pixel qui présente un ndvi entre 0 et 0.7 et dem < 400 par 1.
//’regle3′: remplace chaque pixel qui présente un ndvi < 0.3 et swir > 2000 par 2.
//’regle4′: remplace chaque pixel qui présente un ndvi < 0.3 et ndwi > 0 by 3.
var regle1 = ndvi.where(ndvi.gte(0.7), 0);
//vegetation (color:green)
var regle2 = regle1.where(ndvi.gt(0).and(ndvi.lt(0.7).and(dem.lt(400))), 1);
//urbain (color:black)
var regle3 = regle2.where(ndvi.lt(0.3).and(swir.gt(2000)), 2);
//sol nu (color:bright brown)
var regle4 = regle3.where(ndvi.lt(0.3).and(ndwi.gt(0)), 3).rename(‘CLASS’);
//eau (color:blue)
Map.addLayer(regle4, {palette:[‘#0da919’,‘#0da919’, ‘#000000’, ‘#ff9d39’, ‘#0014ff’]}, ‘Classification’);
Application d’un masque
Vous pouvez souhaiter masquer certaines parties de l’image. Le fait de masquer des pixels dans une image les exclut de l’analyse. Nous vous présentons ici deux des méthodes ee.Image qui sont fréquemment utilisées pour le masquage.
- updateMask
Met à jour le masque d’une image à toutes les positions où le masque existant n’est pas nul. L’image de sortie conserve les métadonnées et l’empreinte de l’image d’entrée (Figure 38).var image = ee.Image(‘LANDSAT/LC08/C01/T1_SR/LC08_015028_20210529’);
Map.addLayer(image, {bands:[‘B4’,‘B3’,‘B2’], min:108, max:1848}, ‘L8 Image’);
// Charger le jeu de données sur les changements forestiers de Hansen
var hansenImage = ee.Image(‘UMD/hansen/global_forest_change_2015’);
print(hansenImage);
// Selectionner le masque eau/terre
var datamask = hansenImage.select(‘datamask’);
// Creer un masque binaire.
// Les masques doivent avoir des valeurs 0 et 1.
// 0 – pixel rejeté
// 1 – pixel considéré
var mask = datamask.eq(1).clip(image.geometry());;
Map.addLayer(mask, {min:0, max:1}, ‘Mask’);
// Mets a jour le composite avec le masque.
var maskedComposite = image.updateMask(mask);
Map.addLayer(maskedComposite, {bands:[‘B4’,‘B3’,‘B2’], min:108, max:1848}, ‘Masked’);
- selfMask
Mets à jour le masque d’une image à toutes les positions où le masque existant n’est pas nul en utilisant la valeur de l’image comme nouvelle valeur de masque. L’image de sortie conserve les métadonnées et l’empreinte de l’image d’entrée.
La différence de cette méthode avec updateMask est qu’elle ne met pas à jour une autre image sur la base du masque ; au contraire, elle n’a pas besoin d’introduire le masque pour elle car elle se masque elle-même (ici dans cet exemple : sol nu) (Figure 39).var image = ee.Image(‘LANDSAT/LC08/C01/T1_SR/LC08_015028_20210529’);
Map.addLayer(image, {bands:[‘B4’,‘B3’,‘B2’], min:108, max:1848}, ‘L8 Image’);
// Creer les indices NDVI et NDWI
var ndvi = image.normalizedDifference([‘B5’, ‘B4’]);
var ndwi = image.normalizedDifference([‘B3’, ‘B5’]);
var solnu = ndvi.lt(0.2).and(ndwi.lt(0));
// Masquer et afficher l’image résultante
Map.addLayer(solnu.selfMask(), {palette:[‘#ff0000’]}, ‘Sols nus’);
Récupérer une information sur l’image
La fonction qui permet d’obtenir l’identifiant (ID) de l’image est .id et l’utilisation de .getInfo permet de transposer les objets du côté serveur vers le côté client (Figure 40).
Attention
Ajout d’une propriété à une image
Si vous voulez ajouter une nouvelle propriété à l’image, utilisez .set et suivez la structure ci-dessous (Figure 41):
Une API (application programming interface ou « interface de programmation d’application ») est une interface logicielle qui permet de « connecter » un logiciel ou un service à un autre logiciel ou service afin d’échanger des données et des fonctionnalités. (CNIL, 2023)
Sentinel-2 est une série de satellites d'observation de la Terre de l'Agence spatiale européenne développée dans le cadre du programme Copernicus dont les deux premiers exemplaires ont été mis en orbite en 2015 et 2017. L'objectif du programme est de fournir aux pays européens des données complètes et actualisées leur permettant d'assurer le contrôle et la surveillance de l'environnement. Les satellites Sentinel-2 constituent une des composantes spatiales de ce programme qui comprend également notamment les Sentinel-1 (observation radar tout temps) et Sentinel-3. Ils doivent fournir l'imagerie optique haute résolution permettant l'observation des sols (utilisation des sols, végétation, zones côtières, fleuves, etc.) ainsi que le traitement des situations d'urgence (catastrophes naturelles...). (Wikipédia, 2023)
Donnée qui renseigne sur la nature de certaines autres données dans le but d'en faciliter la compréhension et la gestion. (OQLF, 2020)
Système de projection utilisé pour la représentation cartographique de la surface terrestre, celle-ci étant supposée projetée sur un ellipsoïde de référence suivant les normales à ce dernier. (OQLF, 2006)
Dans le cas de l'écart entre deux objets, la distance la plus petite ou l'écart angulaire le plus petit, permettant de les discriminer. (Conseil international de la langue francaise, 1980)
Les trois couleurs de base sur lesquelles repose un mode de composition de couleurs fondé sur le principe des couleurs additives. (OQLF, 1992)
Image en couleur qui résulte de la combinaison d'images monochromes d'une même scène. (OQLF, 1988)
Ensemble d'opérations qui tend à améliorer les radiométries d'une image. (FranceTerme, 2000)
Landsat 5 était un satellite en orbite basse lancé le 1er mars 1984 pour recueillir des images de la surface de la Terre. Dans la continuité du programme Landsat, Landsat 5 a été géré conjointement par l'U.S. Geological Survey (USGS) et la National Aeronautics and Space Administration (NASA). Les données de Landsat 5 ont été recueillies et distribuées par le Centre d'observation et de science des ressources terrestres (EROS) de l'USGS.
Après 29 ans dans l'espace, Landsat 5 a été officiellement mis hors service le 5 juin 2013. Vers la fin de sa mission, l'utilisation de Landsat 5 a été entravée par des pannes d'équipement, et il a été largement supplanté par Landsat 7 et Landsat 8. Les scientifiques de la mission ont prévu que le satellite rentrerait dans l'atmosphère terrestre et se désintégrerait vers 2034. (Wikipédia, 2022)
Landsat 8 est un satellite d'observation de la Terre américain lancé le 11 février 2013. Il s'agit du huitième satellite du programme Landsat et le septième à atteindre l’orbite avec succès. Initialement appelé Landsat Data Continuity Mission (LDCM), il s'agit d'une collaboration entre la NASA et le United States Geological Survey (USGS). Le Goddard Space Flight Center de la NASA à Greenbelt, dans le Maryland, assure le développement, l'ingénierie des systèmes de mission et l'acquisition du lanceur, tandis que l'USGS assure le développement des systèmes au sol et poursuit les opérations de la mission. (Wikipédia, 2023)
Motif constitué d'une chaîne de caractères spécifiant des conditions à remplir lors d'une recherche effectuée dans un éditeur de texte, et qui correspond à la chaîne recherchée. (OQLF, 2003)
Assembler des chaînes de données pour former une seule chaîne manipulable comme un tout. (OQLF, 2001)
Mesure télédétectée par satellite de la « verdure » du couvert végétal. (OMS, 2011)
Opération dans laquelle les opérandes et le résultat prennent chacun l'une ou l'autre de deux valeurs distinctes (OQLF, 1999)