REMOTE SENSING

Google Earth Engine & QGIS: Sentinel-2 이미지 조회 및 내보내기

유병혁 2024. 2. 7. 00:00

안녕하세요? 이번 글은 Google Earth Engine에서 Sentinel-2 이미지를 조회 및 내보내는 방법을 정리해 보겠습니다. GEE에서는 내가 원하는 시기와 지역을 대상으로 다수의 이미지를 조회 및 병합할 수 있습니다. 예를 들면, 1년간 특정 국립공원을 관측한 다수의 이미지를 수집한 후, 구름 피복이 5% 미만인 데이터만 픽셀 단위로 요약(예: 중간값)해서 하나의 이미지로 병합하는 것이 가능합니다. 또한 이것을 Google Drive로 내보낸 후 다운로드 해서 QGIS와 같은 지리공간 소프트웨어에서 사용할 수도 있습니다. 일련의 과정을 코드로 확인해 보도록 하겠습니다.

 

먼저 ee와 geemap 라이브러리를 호출하고 Earth Engine 인증 및 초기화를 진행하겠습니다.

import ee
import geemap

# Earth Engine 인증
ee.Authenticate()

# Earth Engine 초기화
ee.Initialize(project='my-project')

 

대상 지역은 팔공산국립공원으로 하겠습니다. 팔공산국립공원의 경계는 WDPA 피처 컬렉션에서 WDPA ID로 호출할 수 있습니다.

# 팔공산: WDPA ID가 555571373인 보호지역
wdpa = ee.FeatureCollection("WCMC/WDPA/current/polygons") \
    .filter(ee.Filter.eq('WDPAID', 555571373))
aoi = wdpa.geometry()

 

다음으로 특정 조건을 만족하는 Sentinel-2 이미지 컬렉션을 정의해 보겠습니다. 기간은 2024년 1월 1일부터 31일까지이고 지역은 팔공산국립공원 경계, 구름 피복률은 5% 미만으로 설정했습니다.

# Sentinel-2 이미지 컬렉션 선택
collection = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED") \
    .filterDate('2024-01-01', '2024-01-31') \
    .filterBounds(aoi) \
    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 5))

 

Sentinel-2 이미지 컬렉션의 크기를 출력해 봅니다. 총 11장이 조회되었는데요, 이것은 팔공산국립공원 지역과 중첩되면서 동시에 날짜 및 구름피복률 조건을 만족하는 이미지를 모두 확인한 결과입니다.

# Sentinel-2 이미지 컬렉션의 크기 출력
collection_size = collection.size()
print("Sentinel-2 이미지 컬렉션의 크기:", collection_size.getInfo())
Sentinel-2 이미지 컬렉션의 크기: 11

 

조회된 Sentinel-2 이미지 컬렉션 내 각 이미지의 속성 정보는 다음과 같이 확인해볼 수 있습니다.

# Sentinel-2 이미지 컬렉션 내 각 이미지의 속성 정보 출력
image_list = collection.toList(collection_size)
for i in range(collection_size.getInfo()):
    image = ee.Image(image_list.get(i))
    date = image.date().format("YYYY-MM-dd").getInfo()
    cloud_percentage = image.get("CLOUDY_PIXEL_PERCENTAGE").getInfo()
    print(f"이미지 {i+1}: 날짜={date}, 구름 피복률={cloud_percentage}%")
이미지 1: 날짜=2024-01-04, 구름 피복률=3.074293%
이미지 2: 날짜=2024-01-04, 구름 피복률=1.332756%
이미지 3: 날짜=2024-01-07, 구름 피복률=4.386907%
이미지 4: 날짜=2024-01-07, 구름 피복률=4.488421%
이미지 5: 날짜=2024-01-12, 구름 피복률=0.448056%
이미지 6: 날짜=2024-01-12, 구름 피복률=1.065743%
이미지 7: 날짜=2024-01-14, 구름 피복률=0.721162%
이미지 8: 날짜=2024-01-27, 구름 피복률=0.220503%
이미지 9: 날짜=2024-01-27, 구름 피복률=2.45147%
이미지 10: 날짜=2024-01-29, 구름 피복률=2.292939%
이미지 11: 날짜=2024-01-29, 구름 피복률=4.434421%

 

Sentinel-2 이미지 컬렉션 내 각 이미지의 픽셀 값은 간단히 요약할 수 있습니다. 예를 들어, 아래와 같은 정의로 중간값 이미지를 손쉽게 계산할 수 있습니다. 간단하죠?!

# 중간값 이미지 계산
median_image = collection.median()

 

이제 Sentinel-2 중간값 이미지와 팔공산국립공원 경계를 함께 지도화해 보겠습니다. 이때 중간값 이미지의 밴드 조합은 자연색 (B4, B3, B2)으로 설정해 봅니다.

# 지도 객체 생성
Map = geemap.Map(width="800px", height="500px")

# 중간값 이미지 추가
Map.addLayer(median_image, {'bands': ['B4', 'B3', 'B2'], 'max': 2000}, 'Median Image')

# AOI 추가
Map.addLayer(aoi, {
  'color': '00FF00', # 녹색
  'width': 2  # 외곽선 두께
}, 'Palgongsan National Park')

Map.centerObject(aoi, 12)
Map

 

이제 중간값 이미지를 Google Drive로 내보내 보겠습니다. 아래와 같이 이름(description), 폴더(export), 영역(region), 해상도(scale), 최대 픽셀(maxPixels) 등을 설정해 주시면 됩니다. 여기서 "description"은 설명을 뜻하지만 실제로는 파일 이름을 지정하며, "maxPixels"은 내보내기 가능한 픽셀 수를 설정하는 것으로 '1e13', 즉 1조 픽셀로 과다하게 설정하여 픽셀 수 초과로 인한 오류를 방지하고자 하는 것입니다.

# 이미지를 Google Drive에 내보내기
geemap.ee_export_image_to_drive(median_image,
                                description='median_image',
                                folder='export',
                                region=aoi,
                                scale=10,
                                maxPixels=1e13)

 

이미지를 Google Drive에 내보내기 하는 작업은, 파일 크기에 따라 약간의 시간이 소요됩니다. 그리고 아래와 같이 해당 폴더에서 "median_image.tif" 파일을 확인하실 수 있습니다. 이것을 다운로드 받아 QGIS에서 한번 열어보겠습니다.

 

QGIS에서 해당 데이터를 열고 프로젝트 좌표계는 EPSG:32652로,  밴드 조합은 자연색 (B4, B3, B2)으로 설정해 봅니다. "median_image.tif" 파일은 단일 다중밴드 이미지로 Sentinel-2 밴드 정보를 온전히 가지고 있습니다. 따라서 QGIS의 기능을 통해 추가 분석이 가능한 상태입니다. 이번 실습은 여기까지입니다. 감사합니다.