Grundlagen der Fernerkundung

In diesem Modul beschäftigst Du dich mit den Grundlagen der Fernerkundung. Dabei werden Satellitendaten genutzt, um zu verstehen, dass die Welt nicht immer so aussieht, wie Du sie kennst.

Autor:in
Zugehörigkeit

IZG

Ruhr-Universität Bochum

Veröffentlichungsdatum

14. September 2025

1 Pakete importieren

Hinweis

Bitte führe den Code mit den Importbefehlen in der folgenden Zelle aus, um die Pakete zu importieren. Dies muss jedes Mal als Erstes getan werden, nachdem der Kernel neugestartet wurde.

import ee                 # importieren der Google Earth Engine Schnittstelle (API) 
import geemap             # importieren des geemap Paketes für die Analysetools
import os                 # importieren des Pakets für den Export von Daten auf die lokale Festplatte
/Users/soeren/PycharmProjects/cdec/wenv/lib/python3.12/site-packages/geemap/conversion.py:23: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
  import pkg_resources

2 Interaktive Karten erstellen

Es wird wieder damit gestartet, eine interaktive Karte mit Koordinaten und Zoom-Faktor zu konfigurieren. Dieser Karte wird ein Name gegeben (hier: my_map), und anschließend wird die Karte über den Befehl my_map (also einfach ihren Namen) aufgerufen.

my_map = geemap.Map(center=(52.5525865,13.4535448), zoom=17)  # neue Map konfigurieren mit Koordinate und Zoomstufe
my_map                                                        # in der Zeile zuvor konfigurierte Map aufrufen
*** Earth Engine *** Share your feedback by taking our Annual Developer Satisfaction Survey: https://google.qualtrics.com/jfe/form/SV_7TDKVSyKvBdmMqW?ref=4i2o6
Hinweis

Wenn Du Google Maps besuchst, kannst Du mit der rechten Maustaste in der Karte auf einen Bereich Deiner Wahl klicken. Anschließend werden die Koordinaten in dem Kontextmenü ausgewählt, um die angezeigten Koordinaten des Ortes im Zwischenpeicher (Copy and Paste) abzulegen.

Aufgabe: Suche Dir einen Ort aus (Wohnort, Schule, Stadion, Park, etc.), ersetze die Koordinaten im Code oben aus dem Zwischenspeicher durch Deine eigenen (Strg+V), passe gegebenenfalls den Zoom-Faktor an, und starte den Code danach neu (Strg+Enter). Hat das funktioniert?

Es können auch mehrere unterschiedliche Karten erstellt werden, indem eine weitere Karte konfiguriert und zum Beispiel my_map2 genannt wird.

Der Befehl my_map in der obigen Zelle führt immer zur Darstellung der spezifisch in der ersten Zeile konfigurierten Karte mit dem gleichen Namen. Solltest Du im weiteren Verlauf dieses Notebooks nicht immer zu dieser einen Map hochscrollen wollen, kann diese einfach über den Befehl my_map in einer eigenen Zeile erneut dargestellt werden.

3 Basemaps hinzufügen

my_map                              # erneutes Aufrufen der oben bereits konfigurierten Karte 'Map'

In GEE verfügen Maps über Hintergrundkarten (Basemaps) mit meist globaler Ausdehnung. Standardmäßig wird die Karte der OpenStreetMap-Community genutzt. Es stehen jedoch viele weitere Optionen zur Verfügung.

Mit den folgenden Befehlen können zuerst alle verfügbaren Basemaps abgefragt und anschließend beliebig viele als weitere Layer der Karte hinzugefügt werden:

# Abfrage aller möglichen Basemaps
basemaps = geemap.basemaps       # die Variable 'basemaps' beinhaltet nun eine Liste aller Basemaps aus dem geemap-Paket

# mit dieser Funktionsschleife wird jede Basemap in einer eigenen Zeile ausgegeben, sonst könnte man das kaum lesen.
for element in basemaps:         # "Gehe die Liste 'basemaps' durch und mache mit jedem Listeneintrag (element) folgendes:
    print(element)               #  Gib den Namen des jeweiligen Listeneintrags aus."
OpenStreetMap
Esri.WorldStreetMap
Esri.WorldImagery
Esri.WorldTopoMap
FWS NWI Wetlands
FWS NWI Wetlands Raster
NLCD 2021 CONUS Land Cover
NLCD 2019 CONUS Land Cover
NLCD 2016 CONUS Land Cover
NLCD 2013 CONUS Land Cover
NLCD 2011 CONUS Land Cover
NLCD 2008 CONUS Land Cover
NLCD 2006 CONUS Land Cover
NLCD 2004 CONUS Land Cover
NLCD 2001 CONUS Land Cover
USGS NAIP Imagery
USGS NAIP Imagery False Color
USGS NAIP Imagery NDVI
USGS Hydrography
USGS 3DEP Elevation
ESA Worldcover 2020
ESA Worldcover 2020 S2 FCC
ESA Worldcover 2020 S2 TCC
ESA Worldcover 2021
ESA Worldcover 2021 S2 FCC
ESA Worldcover 2021 S2 TCC
BaseMapDE.Color
BaseMapDE.Grey
BasemapAT.basemap
BasemapAT.grau
BasemapAT.highdpi
BasemapAT.orthofoto
BasemapAT.overlay
BasemapAT.surface
BasemapAT.terrain
CartoDB.DarkMatter
CartoDB.DarkMatterNoLabels
CartoDB.DarkMatterOnlyLabels
CartoDB.Positron
CartoDB.PositronNoLabels
CartoDB.PositronOnlyLabels
CartoDB.Voyager
CartoDB.VoyagerLabelsUnder
CartoDB.VoyagerNoLabels
CartoDB.VoyagerOnlyLabels
CyclOSM
Esri.AntarcticBasemap
Esri.AntarcticImagery
Esri.ArcticImagery
Esri.ArcticOceanBase
Esri.ArcticOceanReference
Esri.NatGeoWorldMap
Esri.OceanBasemap
Esri.WorldGrayCanvas
Esri.WorldPhysical
Esri.WorldShadedRelief
Esri.WorldTerrain
FreeMapSK
Gaode.Normal
Gaode.Satellite
HikeBike.HikeBike
HikeBike.HillShading
JusticeMap.americanIndian
JusticeMap.asian
JusticeMap.black
JusticeMap.hispanic
JusticeMap.income
JusticeMap.multi
JusticeMap.nonWhite
JusticeMap.plurality
JusticeMap.white
MtbMap
NASAGIBS.ASTER_GDEM_Greyscale_Shaded_Relief
NASAGIBS.BlueMarble
NASAGIBS.BlueMarble3031
NASAGIBS.BlueMarble3413
NASAGIBS.BlueMarbleBathymetry3031
NASAGIBS.BlueMarbleBathymetry3413
NASAGIBS.MEaSUREsIceVelocity3031
NASAGIBS.MEaSUREsIceVelocity3413
NASAGIBS.ModisAquaBands721CR
NASAGIBS.ModisAquaTrueColorCR
NASAGIBS.ModisTerraAOD
NASAGIBS.ModisTerraBands367CR
NASAGIBS.ModisTerraBands721CR
NASAGIBS.ModisTerraChlorophyll
NASAGIBS.ModisTerraLSTDay
NASAGIBS.ModisTerraSnowCover
NASAGIBS.ModisTerraTrueColorCR
NASAGIBS.ViirsEarthAtNight2012
NASAGIBS.ViirsTrueColorCR
OPNVKarte
OneMapSG.Default
OneMapSG.Grey
OneMapSG.LandLot
OneMapSG.Night
OneMapSG.Original
OpenAIP
OpenFireMap
OpenRailwayMap
OpenSeaMap
OpenSnowMap.pistes
OpenStreetMap.BZH
OpenStreetMap.CAT
OpenStreetMap.CH
OpenStreetMap.DE
OpenStreetMap.HOT
OpenStreetMap.Mapnik
OpenTopoMap
SafeCast
Stadia.AlidadeSatellite
Stadia.AlidadeSmooth
Stadia.AlidadeSmoothDark
Stadia.OSMBright
Stadia.Outdoors
Stadia.StamenTerrain
Stadia.StamenTerrainBackground
Stadia.StamenTerrainLabels
Stadia.StamenTerrainLines
Stadia.StamenToner
Stadia.StamenTonerBackground
Stadia.StamenTonerLabels
Stadia.StamenTonerLines
Stadia.StamenTonerLite
Stadia.StamenWatercolor
Strava.All
Strava.Ride
Strava.Run
Strava.Water
Strava.Winter
SwissFederalGeoportal.JourneyThroughTime
SwissFederalGeoportal.NationalMapColor
SwissFederalGeoportal.NationalMapGrey
SwissFederalGeoportal.SWISSIMAGE
TopPlusOpen.Color
TopPlusOpen.Grey
UN.ClearMap
USGS.USImagery
USGS.USImageryTopo
USGS.USTopo
WaymarkedTrails.cycling
WaymarkedTrails.hiking
WaymarkedTrails.mtb
WaymarkedTrails.riding
WaymarkedTrails.skating
WaymarkedTrails.slopes
nlmaps.grijs
nlmaps.luchtfoto
nlmaps.pastel
nlmaps.standaard
nlmaps.water

Aufgabe: Wähle eine Basemap Deiner Wahl, z. B. ‘Esri.WorldImagery’, schreibe deren Name in Klammern und Anführungszeichen in die nächste Codezelle und führe sie aus.

Hinweis

Als Beispiel wird zusätzlich das topographische Kartenwerk der OpenStreetMap-Community hinzugefügt. Das Ergebnis dieses Codes kann entweder weiter oben in Deiner interaktiven Karte angeschaut werden, oder über den Befehl my_map wird eine erneute Instanz dieser Karte direkt unter der Code-Zelle angezeigt. Dies kann von Dir einfach in einer neuen Zeile ganz unten hinzugefügt werden.

my_map.add_basemap('OpenTopoMap')
my_map.add_basemap('')  # wenn die Klammer leer bleibt, wird eine Liste verfügbarer Basemaps angezeigt
# Map.add_basemap('')   # Backup
Basemap can only be one of the following:
  OpenStreetMap
  Esri.WorldStreetMap
  Esri.WorldImagery
  Esri.WorldTopoMap
  FWS NWI Wetlands
  FWS NWI Wetlands Raster
  NLCD 2021 CONUS Land Cover
  NLCD 2019 CONUS Land Cover
  NLCD 2016 CONUS Land Cover
  NLCD 2013 CONUS Land Cover
  NLCD 2011 CONUS Land Cover
  NLCD 2008 CONUS Land Cover
  NLCD 2006 CONUS Land Cover
  NLCD 2004 CONUS Land Cover
  NLCD 2001 CONUS Land Cover
  USGS NAIP Imagery
  USGS NAIP Imagery False Color
  USGS NAIP Imagery NDVI
  USGS Hydrography
  USGS 3DEP Elevation
  ESA Worldcover 2020
  ESA Worldcover 2020 S2 FCC
  ESA Worldcover 2020 S2 TCC
  ESA Worldcover 2021
  ESA Worldcover 2021 S2 FCC
  ESA Worldcover 2021 S2 TCC
  BaseMapDE.Color
  BaseMapDE.Grey
  BasemapAT.basemap
  BasemapAT.grau
  BasemapAT.highdpi
  BasemapAT.orthofoto
  BasemapAT.overlay
  BasemapAT.surface
  BasemapAT.terrain
  CartoDB.DarkMatter
  CartoDB.DarkMatterNoLabels
  CartoDB.DarkMatterOnlyLabels
  CartoDB.Positron
  CartoDB.PositronNoLabels
  CartoDB.PositronOnlyLabels
  CartoDB.Voyager
  CartoDB.VoyagerLabelsUnder
  CartoDB.VoyagerNoLabels
  CartoDB.VoyagerOnlyLabels
  CyclOSM
  Esri.AntarcticBasemap
  Esri.AntarcticImagery
  Esri.ArcticImagery
  Esri.ArcticOceanBase
  Esri.ArcticOceanReference
  Esri.NatGeoWorldMap
  Esri.OceanBasemap
  Esri.WorldGrayCanvas
  Esri.WorldPhysical
  Esri.WorldShadedRelief
  Esri.WorldTerrain
  FreeMapSK
  Gaode.Normal
  Gaode.Satellite
  HikeBike.HikeBike
  HikeBike.HillShading
  JusticeMap.americanIndian
  JusticeMap.asian
  JusticeMap.black
  JusticeMap.hispanic
  JusticeMap.income
  JusticeMap.multi
  JusticeMap.nonWhite
  JusticeMap.plurality
  JusticeMap.white
  MtbMap
  NASAGIBS.ASTER_GDEM_Greyscale_Shaded_Relief
  NASAGIBS.BlueMarble
  NASAGIBS.BlueMarble3031
  NASAGIBS.BlueMarble3413
  NASAGIBS.BlueMarbleBathymetry3031
  NASAGIBS.BlueMarbleBathymetry3413
  NASAGIBS.MEaSUREsIceVelocity3031
  NASAGIBS.MEaSUREsIceVelocity3413
  NASAGIBS.ModisAquaBands721CR
  NASAGIBS.ModisAquaTrueColorCR
  NASAGIBS.ModisTerraAOD
  NASAGIBS.ModisTerraBands367CR
  NASAGIBS.ModisTerraBands721CR
  NASAGIBS.ModisTerraChlorophyll
  NASAGIBS.ModisTerraLSTDay
  NASAGIBS.ModisTerraSnowCover
  NASAGIBS.ModisTerraTrueColorCR
  NASAGIBS.ViirsEarthAtNight2012
  NASAGIBS.ViirsTrueColorCR
  OPNVKarte
  OneMapSG.Default
  OneMapSG.Grey
  OneMapSG.LandLot
  OneMapSG.Night
  OneMapSG.Original
  OpenAIP
  OpenFireMap
  OpenRailwayMap
  OpenSeaMap
  OpenSnowMap.pistes
  OpenStreetMap.BZH
  OpenStreetMap.CAT
  OpenStreetMap.CH
  OpenStreetMap.DE
  OpenStreetMap.HOT
  OpenStreetMap.Mapnik
  OpenTopoMap
  SafeCast
  Stadia.AlidadeSatellite
  Stadia.AlidadeSmooth
  Stadia.AlidadeSmoothDark
  Stadia.OSMBright
  Stadia.Outdoors
  Stadia.StamenTerrain
  Stadia.StamenTerrainBackground
  Stadia.StamenTerrainLabels
  Stadia.StamenTerrainLines
  Stadia.StamenToner
  Stadia.StamenTonerBackground
  Stadia.StamenTonerLabels
  Stadia.StamenTonerLines
  Stadia.StamenTonerLite
  Stadia.StamenWatercolor
  Strava.All
  Strava.Ride
  Strava.Run
  Strava.Water
  Strava.Winter
  SwissFederalGeoportal.JourneyThroughTime
  SwissFederalGeoportal.NationalMapColor
  SwissFederalGeoportal.NationalMapGrey
  SwissFederalGeoportal.SWISSIMAGE
  TopPlusOpen.Color
  TopPlusOpen.Grey
  UN.ClearMap
  USGS.USImagery
  USGS.USImageryTopo
  USGS.USTopo
  WaymarkedTrails.cycling
  WaymarkedTrails.hiking
  WaymarkedTrails.mtb
  WaymarkedTrails.riding
  WaymarkedTrails.skating
  WaymarkedTrails.slopes
  nlmaps.grijs
  nlmaps.luchtfoto
  nlmaps.pastel
  nlmaps.standaard
  nlmaps.water
Hinweis

Über den Schraubenschlüssel oben rechts im Kartenfenster und einen Klick auf ‘Layers’ können die einzelnen Layer interaktiv ein- und ausgeschaltet sowie mit einer beliebigen Transparenz versehen werden.

4 Inspector-Tool benutzen

Zunächst wird ein digitales Geländemodell als weiterer Datensatz aus dem GEE Data Catalog in die Map geladen. Geländemodelle beschreiben die Oberfläche der Erde, wobei jedes Pixel die Höhe des entsprechenden Ortes angibt. Eine genauere Betrachtung der Geländemodelle erfolgt in Modul 3.

# Digitales Geländemodell SRTM (https://developers.google.com/earth-engine/datasets/catalog/USGS_SRTMGL1_003)
dgm = ee.Image('USGS/SRTMGL1_003')

# Visualisierungsparameter für DEM definieren (min-max ist der Wertebereich der Höhe, Palette legt den Farbverlauf fest)
vis_params = {
    'min': 0,
    'max': 250,
    'palette': ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5'],
}

# Beide neuen Layer der Map hinzufügen 
my_map.addLayer(dgm,                # Angabe des Datensatzes, der hinzugefügt werden soll
             vis_params,         # Visualisierungsparameter definieren (s.o.)
             'SRTM DEM',         # Name, den der Layer in unserer Map haben soll
             True,               # Layer ist aktiv und wird angezeigt (!= False)
             0.9)                # Die 0.9 gibt dem DEM-Layer direkt eine 10%ige Transparenz

my_map

Über den Schraubenschlüssel oben rechts im Kartenfenster wird über das (i) der Inspektor erreicht. Wenn er aktiviert ist, kann durch einen Klick der Wert aller getroffenen Pixel innerhalb der Maske ausgegeben werden. grafik.png

Aufgabe: Finde heraus, auf welcher Höhe sich der Rathausplatz Deiner Heimatstadt befindet. Und wie hoch ist laut Geländemodell der Teufelsberg? Schreibe Deine Antwort in die nächste, leere Zelle.

5 Den GEE Datenkatalog durchsuchen

my_map = geemap.Map(center=(52.5525865,13.4535448), zoom=13)
my_map

Basemaps werden in erster Linie zur Orientierung genutzt. Für Analysen werden jedoch „richtige“ Datensätze benötigt. Dafür steht in GEE ein großer Katalog zur Verfügung, der ähnlich wie bei den Basemaps über den Aufruf des Namens eines Datensatzes verwendet werden kann.

Oben links wird über das Welt-Symbol eine Suchmaske geöffnet, mit der Adressen, Koordinaten und auch GEE-Datensätze abgefragt werden können. grafik.png

Aufgabe: Nun werden die ersten Daten eingelesen. Hierfür gibst Du im Tab ‘data’ beispielsweise ‘sentinel 2’ oder ‘sentinel 5’ ein und bestätigst mit Enter. Über das Dropdown-Menü wählst Du aus der Liste entweder das Harmonized Sentinel-2 MSI: MultiSpectral Instrument, Level-2A oder Sentinel-5P NRTI NO2: Near Real-Time Nitrogen Dioxide aus. Danach klickst Du auf ‘import’, um den Code anzuzeigen. Dieser wird markiert und in die Zwischenablage kopiert (Copy-Paste). Anschließend kann der Code in die folgende Zelle eingefügt und ausgeführt werden.

Hinweis

Sollte eine Fehlermeldung auftreten, wird der Variablenname der Karte in der letzten Zeile überprüft (my_map). Er muss mit dem Namen der oben definierten Variable (my_map) übereinstimmen.

Wenn Du Dich für Harmonized Sentinel-2 MSI: MultiSpectral Instrument, Level-2A entscheidest, erstellt der Code ein Mosaik aus Sentinel-2-Bildern, das möglichst wolkenfrei (max. 20% Wolkenbedeckung) ist.

Damit das funktioniert, musst Du den Zeitraum der Bilder über die Datumsangaben in filterDate anpassen (idealerweise wählst Du die Vegetationsperiode von März bis September innerhalb eines Jahres). Das Einladen des Sentinel-5-Bildmaterials funktioniert analog.

Beim Sentinel-2-Vorschlag wird durch den Code ein zusammengesetztes, wolkenfreies Mosaik aus Bildern mit maximal 20 % Wolkenbedeckung generiert – dies sollte im Code so gut wie möglich nachvollzogen werden. Dafür muss der Zeitraum, aus dem die Bilder stammen, über die Datumsangaben hinter filterDate( angepasst werden (idealerweise wird die Vegetationsperiode von März bis September eines Jahres gewählt). Das Einladen des Sentinel-5-Bildmaterials funktioniert auf ähnliche Weise.

Soll der Raumausschnitt in der Karte nicht verändert werden, kann die Zeile am Ende mit m.setCenter() durch eine vorangestellte Raute (#) auskommentiert werden. Zeilen mit einer Raute werden nicht ausgeführt und eignen sich daher gut zum Kommentieren von Skripten.

Ändere die Datumsangaben (das Format beachten und beibehalten!) und vergleiche die Ergebnisse miteinander.

Hinweis

Das Laden der Bilddaten kann etwas dauern.

# Zelle zum Einfügen und Ausführen des Codes aus der Zwischenablage (Strg+V)

6 Untersuchung der Vegetation

6.1 GEE Datensätze hinzufügen, visualisieren und vergleichen

Für die Untersuchung von Klima und Klimawandel kann die Vegetation herangezogen werden, da sie unmittelbar auf Temperaturunterschiede und Trockenheit reagiert. Diese Reaktionen lassen sich auch in Satellitenbildern messen. Wenn Vegetation beobachtet werden soll, muss zuerst festgestellt werden, wo sie sich befindet. Dies scheint offensichtlich, doch nicht alles, was wie Vegetation aussieht, ist tatsächlich Vegetation. Dies wird am Beispiel einiger Sportplätze genauer betrachtet.

my_map = geemap.Map(center=(52.55561592210154, 13.48814255012774), zoom=15)
my_map.add_basemap('Esri.WorldImagery')
my_map

Es sind etliche Sportplätze sichtbar, die kräftig grün erscheinen, genauso wie die offensichtlichen Wälder drumherum. Beide würden ohne zu zögern als Vegetation bezeichnet werden. Doch einige der Plätze sind Kunstrasenplätze und somit keine echte Vegetation. Für eine sichere Erkennung werden jedoch mehr Daten benötigt.

Deshalb wird in der nächsten Zelle Sentinel-2-Bildmaterial aus dem Catalog in die Karte eingefügt. Der Code wurde erneut in die Zelle kopiert.

def maskS2clouds(image):
    qa = image.select('QA60')

    # Bits 10 and 11 are clouds and cirrus, respectively.
    cloudBitMask = 1 << 10
    cirrusBitMask = 1 << 11

    # Both flags should be set to zero, indicating clear conditions.
    mask = qa.bitwiseAnd(cloudBitMask).eq(0) \
    .And(qa.bitwiseAnd(cirrusBitMask).eq(0))

    return image.updateMask(mask).divide(10000)

sentinel2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') \
.filterDate('2020-05-01', '2020-08-30') \
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',20)) \
.map(maskS2clouds)

RGBvisualization = {
    "min": 0.0,
    "max": 0.3,
            "bands": ['B4', 'B3', 'B2'],
# Bildschirm-Kanal:  [ Rot, Grün, Blau]
}

my_map.addLayer(sentinel2.mean(), RGBvisualization, 'RGB')

Auf den ersten Blick erscheinen die Daten schlechter. Dies liegt daran, dass ein Pixel nur noch einem Quadrat von 10m x 10m entspricht und dadurch die räumliche Auflösung sinkt. Dabei gehen Details verloren, doch die Fußballplätze bleiben weiterhin sichtbar.

Die Farben bleiben grundsätzlich unverändert, da es sich immer noch um ein Echtfarbenbild handelt. Dies entsteht folgendermaßen: Der Bildschirm mischt alle Farben aus Rot, Grün und Blau (RGB). Dem roten Kanal des Bildschirms wird das rote reflektierte Licht zugeordnet, das vom Satelliten aufgezeichnet wurde. Dem grünen Kanal wird das grüne Licht und dem blauen Kanal das blaue Licht zugeordnet.
R = Rotes Licht (B4)
G = Grünes Licht (B3)
B = Blaues Licht (B2)

Bei jedem Foto, das auf einem Smartphone angezeigt wird, passiert dasselbe. Filter verändern dann die Kanalkombination, um mehr Kontrast oder lustige Farbeffekte zu erzeugen.

Satelliten wie Sentinel-2 nehmen mehr Licht auf, als das menschliche Auge sehen kann, z. B. infrarotes Licht (bekannt von Fernbedienungen oder Wärmelampen). Dieses Licht kann auf einen der drei Farbkanäle des Bildschirms gelegt und so sichtbar gemacht werden.

In der nächsten Codezeile wird das Satellitenbild erneut hinzugefügt, allerdings werden andere Bereiche des reflektierten Lichts ausgewählt. Der rote Kanal des Bildschirms stellt Infrarotlicht dar, der grüne Kanal rotes Licht und der blaue Kanal grünes Licht. Blaues Licht wird nicht dargestellt. Dadurch entsteht ein sogenanntes Falschfarbenbild.
R = Infrarotes Licht (B8)
G = Rotes Licht (B4)
B = Grünes Licht (B3)

Die Kanalkombination wird in der nächsten Code-Zelle in eine Variable geschrieben.

CIRvisualization = {
  'min': 0.0,
  'max': 0.3,
            'bands': ['B8', 'B4', 'B3'],
# Bildschirm-Kanal:  [ Rot, Grün, Blau]
}

Um die beiden Visualisierungen besser vergleichen zu können, wird jetzt eine Split-Map verwendet. Zunächst werden der rechte und der linke Teil der Karte definiert. Anschließend wird eine neue Karte erstellt, die in zwei Hälften geteilt wird.

SplitMap = geemap.Map(center=(52.55561592210154, 13.48814255012774), zoom=15)
SplitMap.add_basemap('Esri.WorldImagery')

left_layer  = geemap.ee_tile_layer(sentinel2, RGBvisualization, 'Sentinel-2 Echtfarbkomposit')
right_layer = geemap.ee_tile_layer(sentinel2, CIRvisualization, 'Sentinel-2 Falschfarbkomposit')

SplitMap.split_map(left_layer, right_layer)
SplitMap

In der Falschfarbendarstellung beginnt das Bild plötzlich rot zu leuchten. Dies ist die Vegetation, deren Farbstoff Chlorophyll infrarotes Licht stark reflektiert. Versiegelte Flächen oder solche mit nacktem Erdboden, wie Straßen oder abgeerntete Felder, reflektieren dieses Licht nicht und erscheinen weiterhin dunkel.

Aufgabe: Nutze den Slider in der Kartenmitte, um zwischen Echt- und Falschfarbenbild hin- und herzublenden, und beobachte, wie die Vegetation anfängt rot zu leuchten. Wie viele Kunstrasenplätze entdeckst Du im angezeigten Bildausschnitt? Beschreibe kurz, wie Du die Kunstrasenplätze identifiziert hast.

Aufgabe: Vertausche oben in der Variable CIRvisualization die Kanalkombination in der eckigen Klammer (z. B. B8 mit B3) und probiere weitere Farbkombinationen aus. Versuche, die Vegetation beispielsweise in Blau oder Deiner Lieblingsfarbe leuchten zu lassen. Für die Expert*innen: Versuche mal Violett.

Hinweis

Nach Änderungen müssen sowohl die Codezelle mit CIRvisualization als auch die Codezelle für die Split-Map erneut ausgeführt werden.

Als Nächstes wird die Beurteilung kontrolliert, indem eine Landbedeckungsklassifikation der europäischen Raumfahrtbehörde ESA geladen wird. Um die Farben besser zu verstehen, wird auch direkt eine Legende hinzugefügt.

# ESA World Cover
esa = ee.Image('ESA/WorldCover/v200/2021')
my_map.addLayer(esa, {}, 'ESA Land Cover')
my_map.add_legend(builtin_legend='ESA_WorldCover')
my_map

Die Naturrasenplätze werden gelb dargestellt, was der Klasse Grassland entspricht. Die Kunstrasenplätze werden der Klasse Built-up zugeordnet. Diese steht zwar eigentlich für Bebauung, umfasst jedoch nicht nur Gebäude, sondern auch generell versiegelte bzw. künstliche Materialien wie Asphalt, Beton, Dachziegel sowie künstliche Oberflächen wie Tartan oder Kunstrasen. Die Analyse hat also erfolgreich funktioniert!

Aufgabe: Schau Dich in Berlin um und identifiziere mit Deiner Splitmap weitere Kunstrasenplätze.

6.2 Waldbrände - Vitalität der Vegetation berechnen und Veränderungen erkennen

In der vorherigen Übung hast Du gelernt, dass Materialien die verschiedenen Wellenlängenbereiche bzw. Farben des Lichts unterschiedlich stark reflektieren. Vegetation reflektiert im sichtbaren Bereich eine Mischung, die für das Auge grün erscheint, und zusätzlich auch Infrarotlicht. Andere grün erscheinende Materialien wie Kunstrasen reflektieren jedoch kein Infrarotlicht.

Dieses Verhalten wird genutzt, um gesunde von geschwächter Vegetation zu unterscheiden. Dies liegt daran, dass fehlendes Chlorophyll das Reflektionsverhalten der Pflanze verändert. Die folgende Abbildung verdeutlicht dies.

Reflektanzkurven Bildquelle

Um herauszufinden, wie gesund die Vegetation in den Satellitenbildern ist, wird der NDVI verwendet. Der NDVI ist ein Index, der die Reflektion des roten Lichts mit der des infraroten Lichts vergleicht bzw. verrechnet. Durch eine relativ einfache mathematische Formel entstehen Werte zwischen -1 und +1. Je höher der NDVI eines Pixels ist, desto vitaler (gesünder) ist die Vegetation, die abgebildet wird – wenn überhaupt. Der Wert 0 bedeutet keine oder tote Vegetation, und der Wert 1 steht für extrem grüne und vitale Vegetation (weitere Infos). Diese Werte können dann mithilfe beliebiger Farbskalen dargestellt werden.

Wenn der NDVI zu verschiedenen Zeitpunkten berechnet und verglichen wird, können Veränderungen der Vegetation ziemlich zuverlässig untersucht werden. Es gibt viele sinnvolle Anwendungsfälle, wie beispielsweise Waldbrände oder Rodungen.

Im Jahr 2018 hat in Treuenbrietzen ein großer Waldbrand stattgefunden. Dies wird nun genauer betrachtet.

Waldbrand Bildquelle

Zuerst wird der NDVI auf Basis des Sentinel-2-Satelliten vor dem Ereignis berechnet. Dafür werden alle Aufnahmen zwischen dem 1. Juni 2018 und dem 22. August 2018 verwendet.

# Funktion um die Wolken auszumaskieren

def maskS2clouds(image):
  qa = image.select('QA60')

  # Bits 10 and 11 are clouds and cirrus, respectively.
  cloudBitMask = 1 << 10
  cirrusBitMask = 1 << 11

  # Both flags should be set to zero, indicating clear conditions.
  mask = qa.bitwiseAnd(cloudBitMask).eq(0) \
      .And(qa.bitwiseAnd(cirrusBitMask).eq(0))

  return image.updateMask(mask).divide(10000)

# Sentinel-2 ImageCollection filtern und NDVI berechnen

sentinel2_vorher = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') \
                  .filterDate('2018-06-01', '2018-08-22') \
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)) \
                  .map(maskS2clouds) \
                  .mean() \
                  .normalizedDifference(['B8', 'B4']) \
                  .rename('ndvi')
# .filterDate('2019-01-01', '2019-05-01') \     # Für Brandrodungen im Amazonas-Regenwald
# .filterDate('2018-06-01', '2018-08-22') \     # Für Waldbrände in Treuenbrietzen

# Visualisierungsparameter festlegen

visualization_ndvi = {
  'min': 0,
  'max': 1,
  'palette': ['8bc4f9', 'c9995c', 'c7d270', '8add60', '097210'],
  'bands': ['ndvi']
}

# Layer der Karte hinzufügen

NDVIvorher = geemap.ee_tile_layer(sentinel2_vorher, visualization_ndvi, 'Sentinel-2 NDVI vorher')

Anschließend wird auf der gleichen Datenbasis der NDVI nach dem Ereignis berechnet. Dabei werden alle Bilder aus dem September 2018 verwendet, also direkt nach dem Brand.

sentinel2_nachher = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') \
                   .filterDate('2018-09-01', '2018-09-30') \
                   .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)) \
                   .map(maskS2clouds) \
                   .mean() \
                   .normalizedDifference(['B8', 'B4']) \
                   .rename('ndvi')
# .filterDate('2019-10-15', '2020-02-01') \     # Für Brandrodungen im Amazonas-Regenwald
# .filterDate('2018-09-01', '2018-09-30') \     # FÜR Waldbrände in Treuenbrietzen


NDVInachher = geemap.ee_tile_layer(sentinel2_nachher, visualization_ndvi, 'Sentinel-2 NDVI nachher')

Nun werden die beiden NDVI-Bilder in einer Split-Map gegenübergestellt. Zum Vergleich mit der heutigen Situation wird zusätzlich eine Luftbild-Basemap hinzugefügt.

# neue interaktive Karte erstellen, beide NDVI-Layer hinzufügen und anzeigen

NDVIMap = geemap.Map(center=(52.04246028999631, 12.922582408028168), zoom=14)
#NDVIMap = geemap.Map(center=(-21.67113558863388, -60.816409695725085), zoom=8) # Für Brandrodungen im Amazonas-Regenwald
#NDVIMap = geemap.Map(center=(52.04246028999631, 12.922582408028168), zoom=14) # Für Waldbrände in Treuenbrietzen
NDVIMap.split_map(NDVIvorher, NDVInachher)
NDVIMap.add_basemap('Esri.WorldImagery')

NDVIMap

Mit einem Differenzbild wird die Veränderung der Vegetation in einem einzigen Datensatz dargestellt. Dazu werden die Werte des Vorher-Bildes Pixel für Pixel von denen des Nachher-Bildes subtrahiert. Dadurch erhalten abnehmende Werte ein negatives Vorzeichen.

# NDVI-Differenz berechnen, visualisieren, neue interaktive Karte erstellen, den entstehenden Layer hinzufügen und Karte anzeigen

ndvi_diff = sentinel2_nachher.subtract(sentinel2_vorher)

visualization_diff = {
  'min': -1,
  'max': 1,
  'palette': ['red', 'white', 'green'],
  'bands': ['ndvi']
}

DiffMap = geemap.Map(center=(52.04246028999631, 12.922582408028168), zoom=14)
#DiffMap = geemap.Map(center=(-21.67113558863388, -60.816409695725085), zoom=8) # Für Brandrodungen im Amazonas-Regenwald
#DiffMap = geemap.Map(center=(52.04246028999631, 12.922582408028168), zoom=14) # Für Waldbrände in Treuenbrietzen

DiffMap.add_basemap('Esri.WorldImagery')
DiffMap.addLayer(ndvi_diff, visualization_diff, 'NDVI Brandrodungen Sommer')
DiffMap

Aufgabe: Mit dem Pixel Inspector (vgl. Absatz 4: “Inspector-Tool benutzen”) wird die Abnahme des NDVI untersucht. Versuche, die roten und grünen Flächen abseits der Brandfläche zu erklären. Tipp: Nicht alle Flächen sind tatsächlich auf eine Veränderung der Vegetation zurückzuführen.

Aufgabe: Diese Untersuchung kann ebenso im Amazonas-Regenwald durchgeführt werden, um Brandrodung zu identifizieren. In den Codezellen zur NDVI-Berechnung (vgl. Absatz 6.2: “Waldbrände”) befinden sich mit Rauten (#) auskommentiere, alternative Datumsfilter. Füge diese an die entsprechende Stelle ein und führe die Zellen erneut aus. Passe außerdem den Ausschnitt an, den die Karte anzeigt, und erstelle die Karte neu.

Wiederverwendung

Dieses Material steht unter der Lizenz CC BY-SA 4.0. (Lizenz Anzeigen)

Zitat

Mit BibTeX zitieren:
@online{2025,
  author = {, IZG},
  title = {Grundlagen der Fernerkundung},
  date = {2025-09-14},
  url = {https://material.cdec.io/modul_1/notebooks/01c_Fernerkundung.html},
  langid = {de}
}
Bitte zitieren Sie diese Arbeit als:
IZG. 2025. “Grundlagen der Fernerkundung.” September 14, 2025. https://material.cdec.io/modul_1/notebooks/01c_Fernerkundung.html.
close all nutshells