Greifen Sie auf die Sentinel-2-Rasterdatensammlung zu und erstellen Sie einen Erdbeobachtungsauftrag zur Landsegmentierung - Amazon SageMaker

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Greifen Sie auf die Sentinel-2-Rasterdatensammlung zu und erstellen Sie einen Erdbeobachtungsauftrag zur Landsegmentierung

Dieses Python-basierte Tutorial verwendet das SDK for Python (Boto3) und ein Amazon Studio Classic-Notizbuch. SageMaker Um diese Demo erfolgreich abzuschließen, stellen Sie sicher, dass Sie über die erforderlichen AWS Identity and Access Management (IAM) Berechtigungen für die Verwendung SageMaker von Geospatial und Studio Classic verfügen. SageMaker Geospatial erfordert, dass Sie über einen Benutzer, eine Gruppe oder eine Rolle verfügen, die auf Studio Classic zugreifen können. Sie müssen außerdem über eine SageMaker Ausführungsrolle verfügen, die den Prinzipal des SageMaker Geospatial Service sagemaker-geospatial.amazonaws.com in der Vertrauensrichtlinie angibt.

Weitere Informationen zu diesen Anforderungen finden Sie unter SageMaker Geodatenrollen IAM.

In diesem Tutorial erfahren Sie, wie Sie SageMaker Geospatial verwendenAPI, um die folgenden Aufgaben zu erledigen:

  • Finden Sie die verfügbaren Raster-Datensammlungen mit list_raster_data_collections.

  • Suchen Sie eine angegebene Raster-Datensammlung mithilfe von search_raster_data_collection.

  • Erstellen Sie einen Erdbeobachtungsauftrag (EOJ) mithilfe start_earth_observation_job von.

Verwenden von list_raster_data_collections, um verfügbare Datensammlungen zu finden

SageMaker Geospatial unterstützt mehrere Raster-Datensammlungen. Weitere Informationen zu den verfügbaren Datensammlungen finden Sie unter Datenerfassung.

In dieser Demo werden Satellitendaten verwendet, die von Sentinel-2Cloud-Optimized TIFF Geo-Satelliten gesammelt wurden. Diese Satelliten decken alle fünf Tage die Landoberfläche der Erde weltweit ab. Die Sentinel-2-Satelliten sammeln nicht nur Oberflächenbilder der Erde, sondern auch Daten über eine Vielzahl von Spektralbändern.

Um ein Interessengebiet (AOI) zu durchsuchen, benötigen Sie ARN das, was mit den Sentinel-2-Satellitendaten verknüpft ist. Um die verfügbaren Datensammlungen und die zugehörigen Datensammlungen ARNs in Ihrem zu finden AWS-Region, verwenden Sie die Operation. list_raster_data_collections API

Da die Antwort paginiert werden kann, müssen Sie den get_paginator Vorgang verwenden, um alle relevanten Daten zurückzugeben:

import boto3 import sagemaker import sagemaker_geospatial_map import json ## SageMaker Geospatial is currently only avaialable in US-WEST-2 session = boto3.Session(region_name='us-west-2') execution_role = sagemaker.get_execution_role() ## Creates a SageMaker Geospatial client instance geospatial_client = session.client(service_name="sagemaker-geospatial") # Creates a resusable Paginator for the list_raster_data_collections API operation paginator = geospatial_client.get_paginator("list_raster_data_collections") # Create a PageIterator from the paginator class page_iterator = paginator.paginate() # Use the iterator to iterate throught the results of list_raster_data_collections results = [] for page in page_iterator: results.append(page['RasterDataCollectionSummaries']) print(results)

Dies ist ein Beispiel für eine JSON Antwort aus der list_raster_data_collections API Operation. Sie ist so gekürzt, dass sie nur die Datensammlung (Sentinel-2) enthält, die in diesem Codebeispiel verwendet wird. Weitere Informationen zu einer bestimmten Raster-Datensammlung erhalten Sie mit get_raster_data_collection:

{ "Arn": "arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8", "Description": "Sentinel-2a and Sentinel-2b imagery, processed to Level 2A (Surface Reflectance) and converted to Cloud-Optimized GeoTIFFs", "DescriptionPageUrl": "https://registry.opendata.aws/sentinel-2-l2a-cogs", "Name": "Sentinel 2 L2A COGs", "SupportedFilters": [ { "Maximum": 100, "Minimum": 0, "Name": "EoCloudCover", "Type": "number" }, { "Maximum": 90, "Minimum": 0, "Name": "ViewOffNadir", "Type": "number" }, { "Name": "Platform", "Type": "string" } ], "Tags": {}, "Type": "PUBLIC" }

Nachdem Sie das vorherige Codebeispiel ausgeführt haben, erhalten Sie die ARN Sentinel-2-Raster-Datensammlung,. arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8 Im nächsten Abschnitt können Sie die Sentinel-2-Datensammlung mit dem abfragen. search_raster_data_collection API

Durchsuchen der Sentinel-2 Raster-Datensammlung mit search_raster_data_collection

Im vorherigen Abschnitt haben Sie die ARN für list_raster_data_collections die Sentinel-2 Datenerfassung abgerufen. Jetzt können Sie ARN damit die Datensammlung für einen bestimmten Interessenbereich (AOI), einen bestimmten Zeitraum, Eigenschaften und die verfügbaren UV-Bänder durchsuchen.

Um sie aufzurufen, müssen search_raster_data_collection API Sie dem RasterDataCollectionQuery Parameter ein Python Wörterbuch übergeben. Dieses Beispiel verwendet AreaOfInterest, TimeRangeFilter, PropertyFilters, und BandFilter. Der Einfachheit halber können Sie das Python-Wörterbuch mithilfe der Variablen search_rdc_query angeben, die die Suchabfrageparameter enthalten:

search_rdc_query = { "AreaOfInterest": { "AreaOfInterestGeometry": { "PolygonGeometry": { "Coordinates": [ [ # coordinates are input as longitute followed by latitude [-114.529, 36.142], [-114.373, 36.142], [-114.373, 36.411], [-114.529, 36.411], [-114.529, 36.142], ] ] } } }, "TimeRangeFilter": { "StartTime": "2022-01-01T00:00:00Z", "EndTime": "2022-07-10T23:59:59Z" }, "PropertyFilters": { "Properties": [ { "Property": { "EoCloudCover": { "LowerBound": 0, "UpperBound": 1 } } } ], "LogicalOperator": "AND" }, "BandFilter": [ "visual" ] }

In diesem Beispiel fragen Sie einen AreaOfInterest ab, der Lake Mead in Utah enthält. Darüber hinaus unterstützt Sentinel-2 mehrere Arten von Bildbändern. Um die Veränderung der Wasseroberfläche zu messen, benötigen Sie nur das visual Band.

Nachdem Sie die Abfrageparameter erstellt haben, können Sie sie verwenden, search_raster_data_collection API um die Anfrage zu stellen.

Das folgende Codebeispiel implementiert eine search_raster_data_collection API Anfrage. Die Paginierung mit dem get_paginator API wird API nicht unterstützt. Um sicherzustellen, dass die vollständige API Antwort erfasst wurde, verwendet das Codebeispiel eine while Schleife, um zu überprüfen, ob diese NextToken vorhanden ist. Das Codebeispiel wird dann verwendet.extend(), um das Satellitenbild URLs und andere Antwortmetadaten an die items_list anzuhängen.

Weitere Informationen zu finden Sie SearchRasterDataCollectionin der SageMaker APIAmazon-Referenz. search_raster_data_collection

search_rdc_response = sm_geo_client.search_raster_data_collection( Arn='arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8', RasterDataCollectionQuery=search_rdc_query ) ## items_list is the response from the API request. items_list = [] ## Use the python .get() method to check that the 'NextToken' exists, if null returns None breaking the while loop while search_rdc_response.get('NextToken'): items_list.extend(search_rdc_response['Items']) search_rdc_response = sm_geo_client.search_raster_data_collection( Arn='arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8', RasterDataCollectionQuery=search_rdc_query, NextToken=search_rdc_response['NextToken'] ) ## Print the number of observation return based on the query print (len(items_list))

Im Folgenden finden Sie eine JSON Antwort auf Ihre Anfrage. Sie wurde aus Gründen der Übersichtlichkeit gekürzt. Nur das in der Anfrage angegebene "BandFilter": ["visual"] wird im Schlüssel-Wert-Paar Assets zurückgegeben:

{ 'Assets': { 'visual': { 'Href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/15/T/UH/2022/6/S2A_15TUH_20220623_0_L2A/TCI.tif' } }, 'DateTime': datetime.datetime(2022, 6, 23, 17, 22, 5, 926000, tzinfo = tzlocal()), 'Geometry': { 'Coordinates': [ [ [-114.529, 36.142], [-114.373, 36.142], [-114.373, 36.411], [-114.529, 36.411], [-114.529, 36.142], ] ], 'Type': 'Polygon' }, 'Id': 'S2A_15TUH_20220623_0_L2A', 'Properties': { 'EoCloudCover': 0.046519, 'Platform': 'sentinel-2a' } }

Jetzt, wo Sie Ihre Abfrageergebnisse haben, können Sie die Ergebnisse im nächsten Abschnitt visualisieren, indem Sie matplotlib verwenden. Auf diese Weise wird überprüft, ob die Ergebnisse aus der richtigen geografischen Region stammen.

Visualisierung von search_raster_data_collection mit matplotlib

Bevor Sie mit dem Erdbeobachtungsjob (EOJ) beginnen, können Sie ein Ergebnis unserer Abfrage mit visualisieren matplotlib. Das folgende Codebeispiel verwendet das erste Element, items_list[0]["Assets"]["visual"]["Href"], aus der items_list-Variablen, die im vorherigen Codebeispiel erstellt wurde, und druckt ein Bild mit matplotlib.

# Visualize an example image. import os from urllib import request import tifffile import matplotlib.pyplot as plt image_dir = "./images/lake_mead" os.makedirs(image_dir, exist_ok=True) image_dir = "./images/lake_mead" os.makedirs(image_dir, exist_ok=True) image_url = items_list[0]["Assets"]["visual"]["Href"] img_id = image_url.split("/")[-2] path_to_image = image_dir + "/" + img_id + "_TCI.tif" response = request.urlretrieve(image_url, path_to_image) print("Downloaded image: " + img_id) tci = tifffile.imread(path_to_image) plt.figure(figsize=(6, 6)) plt.imshow(tci) plt.show()

Nachdem Sie überprüft haben, ob sich die Ergebnisse in der richtigen geografischen Region befinden, können Sie im nächsten Schritt den Erdbeobachtungsjob (EOJ) starten. Sie verwenden denEOJ, um die Gewässer anhand der Satellitenbilder zu identifizieren, indem Sie ein Verfahren anwenden, das als Landsegmentierung bezeichnet wird.

Starten Sie einen Erdbeobachtungsauftrag (EOJ), der eine Landsegmentierung für eine Reihe von Satellitenbildern durchführt

SageMaker Geospatial bietet mehrere vortrainierte Modelle, mit denen Sie Geodaten aus Rasterdatensammlungen verarbeiten können. Weitere Informationen zu den verfügbaren vortrainierten Modellen und benutzerdefinierten Operationen finden Sie unter Arten von Operationen.

Um die Veränderung der Wasseroberfläche zu berechnen, müssen Sie ermitteln, welche Pixel in den Bildern Wasser entsprechen. Die Landbedeckungssegmentierung ist ein semantisches Segmentierungsmodell, das von der unterstützt wird. start_earth_observation_job API Semantische Segmentierungsmodelle ordnen jedem Pixel in jedem Bild eine Bezeichnung zu. In den Ergebnissen wird jedem Pixel eine Bezeichnung zugewiesen, die auf der Klassenzuweisung für das Modell basiert. Im Folgenden finden Sie die Klassenkarte für das Landsegmentierungsmodell:

{ 0: "No_data", 1: "Saturated_or_defective", 2: "Dark_area_pixels", 3: "Cloud_shadows", 4: "Vegetation", 5: "Not_vegetated", 6: "Water", 7: "Unclassified", 8: "Cloud_medium_probability", 9: "Cloud_high_probability", 10: "Thin_cirrus", 11: "Snow_ice" }

Um einen Erdbeobachtungsjob zu starten, verwenden Sie den. start_earth_observation_job API Beim Senden Ihrer Anfrage müssen Sie Folgendes angeben:

  • InputConfig(dict) – Wird verwendet, um die Koordinaten des Bereichs, den Sie durchsuchen möchten, und andere Metadaten, die mit Ihrer Suche verknüpft sind, anzugeben.

  • JobConfig(dict) — Wird verwendet, um die Art der EOJ Operation anzugeben, die Sie mit den Daten ausgeführt haben. Dieses Beispiel verwendet LandCoverSegmentationConfig.

  • ExecutionRoleArn(string) — Die ARN SageMaker Ausführungsrolle mit den erforderlichen Berechtigungen, um den Job auszuführen.

  • Name(string) – Ein Name für den Erdbeobachtungsauftrag.

Das InputConfig ist ein Python Wörterbuch. Verwenden Sie die folgende Variable eoj_input_config, um die Suchabfrageparameter zu speichern. Verwenden Sie diese Variable, wenn Sie die start_earth_observation_job API Anfrage stellen. w.

# Perform land cover segmentation on images returned from the Sentinel-2 dataset. eoj_input_config = { "RasterDataCollectionQuery": { "RasterDataCollectionArn": "arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8", "AreaOfInterest": { "AreaOfInterestGeometry": { "PolygonGeometry": { "Coordinates":[ [ [-114.529, 36.142], [-114.373, 36.142], [-114.373, 36.411], [-114.529, 36.411], [-114.529, 36.142], ] ] } } }, "TimeRangeFilter": { "StartTime": "2021-01-01T00:00:00Z", "EndTime": "2022-07-10T23:59:59Z", }, "PropertyFilters": { "Properties": [{"Property": {"EoCloudCover": {"LowerBound": 0, "UpperBound": 1}}}], "LogicalOperator": "AND", }, } }

Das JobConfig ist ein Python Wörterbuch, das verwendet wird, um den EOJ Vorgang zu spezifizieren, den Sie mit Ihren Daten ausführen möchten:

eoj_config = {"LandCoverSegmentationConfig": {}}

Nachdem die Wörterbuchelemente jetzt angegeben sind, können Sie Ihre start_earth_observation_job API Anfrage mithilfe des folgenden Codebeispiels einreichen:

# Gets the execution role arn associated with current notebook instance execution_role_arn = sagemaker.get_execution_role() # Starts an earth observation job response = sm_geo_client.start_earth_observation_job( Name="lake-mead-landcover", InputConfig=eoj_input_config, JobConfig=eoj_config, ExecutionRoleArn=execution_role_arn, ) print(response)

Der Job „Eine Erdbeobachtung starten“ gibt ARN zusammen mit anderen Metadaten eine zurück.

Um eine Liste aller laufenden und aktuellen Erdbeobachtungsaufträge zu erhalten, verwenden Sie die list_earth_observation_jobsAPI. Um den Status eines einzelnen Erdbeobachtungsauftrags zu überwachen, verwenden Sie den get_earth_observation_jobAPI. Um diese Anfrage zu stellen, verwenden Sie die nach dem Absenden Ihrer EOJ Anfrage ARN erstellte. Weitere Informationen finden Sie GetEarthObservationJobin der SageMaker APIAmazon-Referenz.

Um die mit Ihnen ARNs verbundenen zu finden, EOJs verwenden Sie die list_earth_observation_jobs API Operation. Weitere Informationen finden Sie ListEarthObservationJobsin der SageMaker APIAmazon-Referenz.

# List all jobs in the account sg_client.list_earth_observation_jobs()["EarthObservationJobSummaries"]

Im Folgenden finden Sie ein Beispiel für eine JSON Antwort:

{ 'Arn': 'arn:aws:sagemaker-geospatial:us-west-2:111122223333:earth-observation-job/futg3vuq935t', 'CreationTime': datetime.datetime(2023, 10, 19, 4, 33, 54, 21481, tzinfo = tzlocal()), 'DurationInSeconds': 3493, 'Name': 'lake-mead-landcover', 'OperationType': 'LAND_COVER_SEGMENTATION', 'Status': 'COMPLETED', 'Tags': {} }, { 'Arn': 'arn:aws:sagemaker-geospatial:us-west-2:111122223333:earth-observation-job/wu8j9x42zw3d', 'CreationTime': datetime.datetime(2023, 10, 20, 0, 3, 27, 270920, tzinfo = tzlocal()), 'DurationInSeconds': 1, 'Name': 'mt-shasta-landcover', 'OperationType': 'LAND_COVER_SEGMENTATION', 'Status': 'INITIALIZING', 'Tags': {} }

Nachdem sich der Status Ihres EOJ Jobs auf geändert hatCOMPLETED, fahren Sie mit dem nächsten Abschnitt fort, um die Änderung der Mead's Seeoberfläche zu berechnen.

Berechnung der Veränderung der Oberfläche des Mead-Sees

Um die Änderung der Oberfläche von Lake Mead zu berechnen, exportieren Sie zunächst die Ergebnisse von EOJ nach Amazon S3, indem Sie Folgendes verwendenexport_earth_observation_job:

sagemaker_session = sagemaker.Session() s3_bucket_name = sagemaker_session.default_bucket() # Replace with your own bucket if needed s3_bucket = session.resource("s3").Bucket(s3_bucket_name) prefix = "export-lake-mead-eoj" # Replace with the S3 prefix desired export_bucket_and_key = f"s3://{s3_bucket_name}/{prefix}/" eoj_output_config = {"S3Data": {"S3Uri": export_bucket_and_key}} export_response = sm_geo_client.export_earth_observation_job( Arn="arn:aws:sagemaker-geospatial:us-west-2:111122223333:earth-observation-job/7xgwzijebynp", ExecutionRoleArn=execution_role_arn, OutputConfig=eoj_output_config, ExportSourceImages=False, )

Um den Status Ihres Exportauftrags zu sehen, verwenden Sie: get_earth_observation_job

export_job_details = sm_geo_client.get_earth_observation_job(Arn=export_response["Arn"])

Um die Veränderungen des Wasserspiegels von Lake Mead zu berechnen, laden Sie die Landbedeckungsmasken auf die lokale SageMaker Notebook-Instance herunter und laden Sie die Quellbilder aus unserer vorherigen Abfrage herunter. In der Klassenkarte für das Landsegmentierungsmodell ist der Klassenindex für Wasser 6.

Gehen Sie wie folgt vor, um die Wassermaske aus einem Sentinel-2-Bild zu extrahieren. Zählen Sie zunächst die Anzahl der Pixel, die im Bild als Wasser (Klassenindex 6) markiert sind. Zweitens multiplizieren Sie die Anzahl mit der Fläche, die jedes Pixel abdeckt. Bänder können sich in ihrer räumlichen Auflösung unterscheiden. Für das Modell der Landbedeckungssegmentierung werden alle Bänder auf eine räumliche Auflösung von 60 Metern heruntergerechnet.

import os from glob import glob import cv2 import numpy as np import tifffile import matplotlib.pyplot as plt from urllib.parse import urlparse from botocore import UNSIGNED from botocore.config import Config # Download land cover masks mask_dir = "./masks/lake_mead" os.makedirs(mask_dir, exist_ok=True) image_paths = [] for s3_object in s3_bucket.objects.filter(Prefix=prefix).all(): path, filename = os.path.split(s3_object.key) if "output" in path: mask_name = mask_dir + "/" + filename s3_bucket.download_file(s3_object.key, mask_name) print("Downloaded mask: " + mask_name) # Download source images for visualization for tci_url in tci_urls: url_parts = urlparse(tci_url) img_id = url_parts.path.split("/")[-2] tci_download_path = image_dir + "/" + img_id + "_TCI.tif" cogs_bucket = session.resource( "s3", config=Config(signature_version=UNSIGNED, region_name="us-west-2") ).Bucket(url_parts.hostname.split(".")[0]) cogs_bucket.download_file(url_parts.path[1:], tci_download_path) print("Downloaded image: " + img_id) print("Downloads complete.") image_files = glob("images/lake_mead/*.tif") mask_files = glob("masks/lake_mead/*.tif") image_files.sort(key=lambda x: x.split("SQA_")[1]) mask_files.sort(key=lambda x: x.split("SQA_")[1]) overlay_dir = "./masks/lake_mead_overlay" os.makedirs(overlay_dir, exist_ok=True) lake_areas = [] mask_dates = [] for image_file, mask_file in zip(image_files, mask_files): image_id = image_file.split("/")[-1].split("_TCI")[0] mask_id = mask_file.split("/")[-1].split(".tif")[0] mask_date = mask_id.split("_")[2] mask_dates.append(mask_date) assert image_id == mask_id image = tifffile.imread(image_file) image_ds = cv2.resize(image, (1830, 1830), interpolation=cv2.INTER_LINEAR) mask = tifffile.imread(mask_file) water_mask = np.isin(mask, [6]).astype(np.uint8) # water has a class index 6 lake_mask = water_mask[1000:, :1100] lake_area = lake_mask.sum() * 60 * 60 / (1000 * 1000) # calculate the surface area lake_areas.append(lake_area) contour, _ = cv2.findContours(water_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) combined = cv2.drawContours(image_ds, contour, -1, (255, 0, 0), 4) lake_crop = combined[1000:, :1100] cv2.putText(lake_crop, f"{mask_date}", (10,50), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 0), 3, cv2.LINE_AA) cv2.putText(lake_crop, f"{lake_area} [sq km]", (10,100), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 0), 3, cv2.LINE_AA) overlay_file = overlay_dir + '/' + mask_date + '.png' cv2.imwrite(overlay_file, cv2.cvtColor(lake_crop, cv2.COLOR_RGB2BGR)) # Plot water surface area vs. time. plt.figure(figsize=(20,10)) plt.title('Lake Mead surface area for the 2021.02 - 2022.07 period.', fontsize=20) plt.xticks(rotation=45) plt.ylabel('Water surface area [sq km]', fontsize=14) plt.plot(mask_dates, lake_areas, marker='o') plt.grid('on') plt.ylim(240, 320) for i, v in enumerate(lake_areas): plt.text(i, v+2, "%d" %v, ha='center') plt.show()

Mithilfe von matplotlib können Sie die Ergebnisse grafisch visualisieren. Die Grafik zeigt, dass die Oberfläche des Sees Mead von Januar 2021 bis Juli 2022 abgenommen hat.

Ein Balkendiagramm zeigt, dass die Oberfläche von Lake Mead von Januar 2021 bis Juli 2022 abgenommen hat