Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Akses pengumpulan data raster Sentinel-2 dan buat pekerjaan observasi bumi untuk melakukan segmentasi lahan
Tutorial berbasis Python ini menggunakan untuk SDK Python (Boto3) dan notebook Amazon Studio Classic. SageMaker Untuk menyelesaikan demo ini dengan sukses, pastikan Anda memiliki izin AWS Identity and Access Management (IAM) yang diperlukan untuk menggunakan SageMaker geospasial dan Studio Classic. SageMaker geospasial mengharuskan Anda memiliki pengguna, grup, atau peran yang dapat mengakses Studio Classic. Anda juga harus memiliki peran SageMaker eksekusi yang menentukan prinsip layanan SageMaker geospasial, sagemaker-geospatial.amazonaws.com
dalam kebijakan kepercayaannya.
Untuk mempelajari lebih lanjut tentang persyaratan ini, lihat IAMperan SageMaker geospasial.
Tutorial ini menunjukkan cara menggunakan SageMaker geospasial API untuk menyelesaikan tugas-tugas berikut:
-
Temukan koleksi data raster yang tersedia dengan
list_raster_data_collections
. -
Cari pengumpulan data raster tertentu dengan menggunakan
search_raster_data_collection
. -
Buat pekerjaan observasi bumi (EOJ) dengan menggunakan
start_earth_observation_job
.
Menggunakan list_raster_data_collections
untuk menemukan koleksi data yang tersedia
SageMaker geospasial mendukung beberapa pengumpulan data raster. Untuk mempelajari lebih lanjut tentang pengumpulan data yang tersedia, lihatPengumpulan data.
Demo ini menggunakan data satelit yang dikumpulkan dari Sentinel-2 Satelit TIFF
Untuk mencari area minat (AOI), Anda memerlukan ARN yang terkait dengan data satelit Sentinel-2. Untuk menemukan koleksi data yang tersedia dan yang terkait dengan ARNs Anda Wilayah AWS, gunakan list_raster_data_collections
API operasi.
Karena respons dapat diberi paginasi, Anda harus menggunakan get_paginator
operasi untuk mengembalikan semua data yang relevan:
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)
Ini adalah contoh JSON respons dari list_raster_data_collections
API operasi. Itu terpotong untuk memasukkan hanya pengumpulan data (Sentinel-2) yang digunakan dalam contoh kodenya. Untuk detail selengkapnya tentang pengumpulan data raster tertentu, gunakanget_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" }
Setelah menjalankan contoh kode sebelumnya, Anda mendapatkan pengumpulan data raster Sentinel-2,. ARN arn:aws:sagemaker-geospatial:us-west-2:378778860802:raster-data-collection/public/nmqj48dcu3g7ayw8
Di bagian selanjutnya, Anda dapat menanyakan pengumpulan data Sentinel-2 menggunakan file. search_raster_data_collection
API
Mencari Sentinel-2 pengumpulan data raster menggunakan search_raster_data_collection
Di bagian sebelumnya, Anda biasa mendapatkan list_raster_data_collections
untuk ARN Sentinel-2 pengumpulan data. Sekarang Anda dapat menggunakannya ARN untuk mencari pengumpulan data di area tertentu yang diminati (AOI), rentang waktu, properti, dan pita UV yang tersedia.
Untuk memanggil search_raster_data_collection
API Anda harus melewati a Python dic tionary ke RasterDataCollectionQuery
parameter. Contoh ini menggunakanAreaOfInterest
,TimeRangeFilter
,PropertyFilters
, danBandFilter
. Untuk memudahkan, Anda dapat menentukan kamus Python menggunakan variabel search_rdc_query
untuk menahan parameter permintaan pencarian:
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"
] }
Dalam contoh ini, Anda menanyakan AreaOfInterest
yang menyertakan Danau Meadvisual
pita.
Setelah Anda membuat parameter kueri, Anda dapat menggunakan search_raster_data_collection
API untuk membuat permintaan.
Contoh kode berikut mengimplementasikan search_raster_data_collection
API permintaan. Ini API tidak mendukung pagination menggunakan file. get_paginator
API Untuk memastikan bahwa API respons lengkap telah dikumpulkan, sampel kode menggunakan while
loop untuk memeriksa apakah NextToken
ada. Sampel kode kemudian digunakan .extend()
untuk menambahkan citra satelit URLs dan metadata respons lainnya ke. items_list
Untuk mempelajari selengkapnya tentang inisearch_raster_data_collection
, lihat SearchRasterDataCollectiondi SageMaker APIReferensi Amazon.
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))
Berikut ini adalah JSON tanggapan dari kueri Anda. Itu telah dipotong untuk kejelasan. Hanya yang "BandFilter": ["visual"]
ditentukan dalam permintaan yang dikembalikan dalam pasangan Assets
kunci-nilai:
{ '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' } }
Sekarang setelah Anda memiliki hasil kueri, di bagian selanjutnya Anda dapat memvisualisasikan hasilnya dengan menggunakanmatplotlib
. Ini untuk memverifikasi bahwa hasil berasal dari wilayah geografis yang benar.
Memvisualisasikan penggunaan Anda search_raster_data_collection
matplotlib
Sebelum Anda memulai pekerjaan pengamatan bumi (EOJ), Anda dapat memvisualisasikan hasil dari kueri kami dengan matplotlib
. Contoh kode berikut mengambil item pertama,items_list[0]["Assets"]["visual"]["Href"]
, dari items_list
variabel yang dibuat dalam contoh kode sebelumnya dan mencetak gambar menggunakanmatplotlib
.
# 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()
Setelah memeriksa apakah hasilnya berada di wilayah geografis yang benar, Anda dapat memulai Earth Observation Job (EOJ) di langkah berikutnya. Anda menggunakan EOJ untuk mengidentifikasi badan air dari citra satelit dengan menggunakan proses yang disebut segmentasi tanah.
Memulai pekerjaan pengamatan bumi (EOJ) yang melakukan segmentasi tanah pada serangkaian citra Satelit
SageMaker geospasial menyediakan beberapa model pra-terlatih yang dapat Anda gunakan untuk memproses data geospasial dari pengumpulan data raster. Untuk mempelajari lebih lanjut tentang model pra-terlatih yang tersedia dan operasi kustom, lihatJenis Operasi.
Untuk menghitung perubahan luas permukaan air, Anda perlu mengidentifikasi piksel mana dalam gambar yang sesuai dengan air. Segmentasi tutupan lahan adalah model segmentasi semantik yang didukung oleh. start_earth_observation_job
API Model segmentasi semantik mengaitkan label dengan setiap piksel di setiap gambar. Dalam hasilnya, setiap piksel diberi label yang didasarkan pada peta kelas untuk model. Berikut ini adalah peta kelas untuk model segmentasi lahan:
{ 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" }
Untuk memulai pekerjaan pengamatan bumi, gunakan start_earth_observation_job
API. Ketika Anda mengirimkan permintaan Anda, Anda harus menentukan yang berikut:
-
InputConfig
(dict) - Digunakan untuk menentukan koordinat area yang ingin Anda cari, dan metadata lain yang terkait dengan pencarian Anda. -
JobConfig
(dict) - Digunakan untuk menentukan jenis EOJ operasi yang Anda lakukan pada data. Contoh ini menggunakanLandCoverSegmentationConfig
. -
ExecutionRoleArn
(string) — ARN Peran SageMaker eksekusi dengan izin yang diperlukan untuk menjalankan pekerjaan. -
Name
(string) —Nama untuk pekerjaan pengamatan bumi.
InputConfig
Itu adalah Python kamus. Gunakan variabel berikut eoj_input_config
untuk menahan parameter kueri penelusuran. Gunakan variabel ini saat Anda membuat start_earth_observation_job
API permintaan. 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", }, } }
JobConfig
Itu adalah Python kamus yang digunakan untuk menentukan EOJ operasi yang ingin Anda lakukan pada data Anda:
eoj_config = {"LandCoverSegmentationConfig": {}}
Dengan elemen kamus yang sekarang ditentukan, Anda dapat mengirimkan start_earth_observation_job
API permintaan Anda menggunakan contoh kode berikut:
# 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)
Awal pekerjaan pengamatan bumi mengembalikan ARN bersama dengan metadata lainnya.
Untuk mendapatkan daftar semua pekerjaan pengamatan bumi yang sedang berlangsung dan saat ini, gunakan list_earth_observation_jobs
API. Untuk memantau status pekerjaan pengamatan bumi tunggal, gunakan get_earth_observation_job
API. Untuk membuat permintaan ini, gunakan yang ARN dibuat setelah mengirimkan permintaan AndaEOJ. Untuk mempelajari lebih lanjut, lihat GetEarthObservationJobdi SageMaker APIReferensi Amazon.
Untuk menemukan yang ARNs terkait dengan Anda EOJs gunakan list_earth_observation_jobs
API operasi. Untuk mempelajari lebih lanjut, lihat ListEarthObservationJobsdi SageMaker APIReferensi Amazon.
# List all jobs in the account sg_client.list_earth_observation_jobs()["EarthObservationJobSummaries"]
Berikut ini adalah contoh JSON respon:
{ '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': {} }
Setelah status EOJ pekerjaan Anda berubah menjadiCOMPLETED
, lanjutkan ke bagian berikutnya untuk menghitung perubahan di Danau Mead's luas permukaan.
Menghitung perubahan di Danau Mead luas permukaan
Untuk menghitung perubahan luas permukaan Danau Mead, pertama-tama ekspor hasil EOJ ke Amazon S3 dengan menggunakan: export_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, )
Untuk melihat status pekerjaan ekspor Anda, gunakanget_earth_observation_job
:
export_job_details = sm_geo_client.get_earth_observation_job(Arn=export_response["Arn"])
Untuk menghitung perubahan ketinggian air Danau Mead, unduh masker tutupan lahan ke instance SageMaker notebook lokal dan unduh gambar sumber dari kueri kami sebelumnya. Dalam peta kelas untuk model segmentasi tanah, indeks kelas air adalah 6.
Untuk mengekstrak masker air dari a Sentinel-2 gambar, ikuti langkah-langkah ini. Pertama, hitung jumlah piksel yang ditandai sebagai air (indeks kelas 6) pada gambar. Kedua, kalikan hitungan dengan area yang dicakup setiap piksel. Band dapat berbeda dalam resolusi spasialnya. Untuk model segmentasi tutupan lahan, semua pita diambil sampelnya ke resolusi spasial sebesar 60 meter.
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()
Dengan menggunakanmatplotlib
, Anda dapat memvisualisasikan hasilnya dengan grafik. Grafik menunjukkan bahwa luas permukaan danau Mead menurun dari Januari 2021—Juli 2022.