나의 사소한 여행 이야기

여행이란 무엇일까, 우리는 일상을 여행하면서도 여행을 염원한다. 바쁜 일상을 살아가면서 떠나는 세상에서 가장 사소한 여행 이야기.

인공위성과 지구통계학

Google Earth Enginge에서 위성영상 받아보기

OriBurii 2024. 11. 30. 13:53

인공위성 원격탐사는 냉전시대에 인공위성이 개발되면서 1960년대에 새롭게 생겨난 학문분야다. 

인공위성의 발달은 기존 항공사진을 이용할 때와는 비교도 되지 않을만큼의 광역적인 지역의 정보를 짧은 시간에 주기적으로 획득할 수 있게 해주었다.

 

인공위성 기술의 발달은 지구관측위성이 다양한 궤도에서 다양한 특성을 갖게 해주었으며, 탑재된 전자장비의 발달은 다양한 위성 센서를 통해 다양한 지구정보를 획득할 수 있게 해주었다. 

하지만, 위성영상은 한 장에 수십에서 수천만원의 고액으로 판매가 되기 때문에 민간에서 활용하기에는 한계가 있었다.

 

2014년, 유럽우주국(European Space Agency, ESA)에서는 Sentinel-1 위성을 발사하였는데, 이 위성은 위성 원격탐사의 새로운 시대를 열었다. 그 이유는 전세계의 80%에 달하는 지역에서 영상을 획득하는 Sentinel-1위성의 데이터를 무료로 공개하였기 때문이다.

Sentienl 프로젝트를 시작으로 다른 기관에서도 한정된 위성에 한해서 위성 영상을 무료로 공개하기 시작하였다.

 

하지만, 합성개구레이더(Synthetic Aperture Radar, SAR)의 경우에는 데이터를 사용하기 이전에도 위성시스템과 신호처리 등의 분야에 대한 수준 높은 이해가 있어야만 사용할 수 있었다. 

Google Earth Engine (GEE)에서는 전세계에 공개된 위성데이터를 집대성하여 사용자가 손쉽게 이용할 수 있는 수준까지 가공을 해준다. GEE를 이용하면 데이터의 특별한 전처리 없이 분석이 가능하다. 

 

이번에는 GEE를 통해 간단하게 Sentinel-1 SAR 영상을 다운로드 하는 방법을 포스팅하였다. 

 

먼저, Google earth engine에서 프로젝트를 생성해야한다. 다음 링크에 접속하여 우측 상단의 "Get Started"를 클릭하면 새로운 프로젝트를 생성할 수 있다.

https://earthengine.google.com/

 

Google Earth Engine

 

earthengine.google.com

 

그리고, python에  earthengine-api 모듈을 설치하면 python을 통해 위성 영상을 다운로드 받을 수 있다.

jupyter 노트북에 다음 코드를 입력하면 해당 모듈이 설치된다.

!conda install -c conda-forge earthengine-api

 

설치가 완료되었으면 다음 코드를 이용하여 모듈을 실행한다.

import ee
ee.Authenticate()
ee.Initialize()

AOI (Area Of Interest)설정

geoJSON 링크:

http://geojson.io/#map=2/20/0

링크에서 원하는 지역을 POLYGON으로 설정하여 다음 셀에서 geoJSON을 설정한다.

 

오른쪽에 생성되는 데이터를 다음과 같은 코드로 작성하면 된다.

geoJSON = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "coordinates": [
          [
            [
              126.3709956325589,
              37.52638749631406
            ],
            [
              126.3709956325589,
              37.31170424202402
            ],
            [
              126.70563689307983,
              37.31170424202402
            ],
            [
              126.70563689307983,
              37.52638749631406
            ],
            [
              126.3709956325589,
              37.52638749631406
            ]
          ]
        ],
        "type": "Polygon"
      }
    }
  ]
}

coords = geoJSON['features'][0]['geometry']['coordinates']
aoi = ee.Geometry.Polygon(coords)

위성 영상 검색

# 'COPERNICUS/S1_GRD_FLOAT' 를 링크에서 검색하여 원하는 데이터로 전환
#  (https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S2_SR_HARMONIZED)
# 위 링크는 대기보정이 완료된 Sentinel-2 영상임

im_coll = (ee.ImageCollection('COPERNICUS/S1_GRD_FLOAT') 
                .filterBounds(aoi)
                .filterDate(ee.Date('2017-01-01'),ee.Date('2023-12-31'))
                .filter(ee.Filter.eq('orbitProperties_pass', 'ASCENDING')) #
                .filter(ee.Filter.eq('relativeOrbitNumber_start', 127)) #orbit track
                .filter(ee.Filter.eq('sliceNumber', 3)) #Sentinel-1 일때 사용하는 것으로 알고 있음
                .sort('system:time_start'))

검색된 영상 확인

# 검색된 영상 개수 확인
import time
acq_times = im_coll.aggregate_array('system:time_start').getInfo()
date = [time.strftime('%x', time.gmtime(acq_time/1000)) for acq_time in acq_times]
len(date)
# 영상 메타데이터 확인
im_list = im_coll.toList(im_coll.size())
i=0
print(im_list.get(i).getInfo()['properties']['transmitterReceiverPolarisation'])
print(im_list.get(i).getInfo()['properties']['orbitProperties_pass'])
print(im_list.get(i).getInfo()['properties']['relativeOrbitNumber_start'])
print(im_list.get(i).getInfo()['properties']['sliceNumber'])

위의 코드에서는 i의 값을 설정하여 i번째 영상의 데이터를 확인할 수 있다. 그 결과를 이용해 위성영상 검색 파라미터를 조절하여 원하는 영상만을 추려서 검색할 수 있다.

# 영상 날짜 확인
date
['02/24/17',
 '03/08/17',
 '03/20/17',
 
    ...
 
 '12/02/23',
 '12/14/23',
 '12/26/23']

 

다음은 검색한 영상의 상태를 확인하는 코드다. 원하는 지역의 영상이 잘 나왔는지, 눈으로 확인했을 때 영상에 어떤 특징이 있는지 등을 간단하게 확인할 수 있다. 

다음 명령어를 통해 folium 모듈을 설치한다.

!pip install folium
# Import the Folium library.
import folium

# Define a method for displaying Earth Engine image tiles to folium map.
def add_ee_layer(self, ee_image_object, vis_params, name):
  map_id_dict = ee.Image(ee_image_object).getMapId(vis_params)
  folium.raster_layers.TileLayer(
    tiles = map_id_dict['tile_fetcher'].url_format,
    attr = 'Map Data &copy; <a href="https://earthengine.google.com/">Google Earth Engine</a>',
    name = name,
    overlay = True,
    control = True
  ).add_to(self)

# Add EE drawing method to folium.

folium.Map.add_ee_layer = add_ee_layer
im1 = ee.Image(im_list.get(0)).select('VV').clip(aoi)
im2 = ee.Image(im_list.get(78)).select('VV').clip(aoi)
im3 = ee.Image(im_list.get(-1)).select('VV').clip(aoi)
rgb = ee.Image.rgb(im1, im2, im3)

location = aoi.centroid().coordinates().getInfo()[::-1]
mp = folium.Map(location=location, zoom_start=10)
mp.add_ee_layer(im1,{'min': 0, 'max': 1, 'palette': ['black', 'white']}, 'GRD_FLOAT')
mp.add_ee_layer(im2,{'min': 0, 'max': 1, 'palette': ['black', 'white']}, 'GRD_FLOAT2')
mp.add_ee_layer(im3,{'min': 0, 'max': 1, 'palette': ['black', 'white']}, 'GRD_FLOAT3')
mp.add_ee_layer(rgb, {'min': [0, 0, 0], 'max': [2, 2, 2]}, 'rgb')
mp.add_child(folium.LayerControl())

display(mp)

 

위의 코드를 실행하면 다음과 같은 결과가 나온다.

 

원하는 영상이 모두 검색되었다고 판단이 되면 다음 코드를 통해 영상을 원하는 파일경로에 저장할 수 있다.

# Multi-band GeoTIFF file.
path = 'Z:/tstory/icn/' #영상을 저장할 파일 위치 설정
for i in range(0, len(date)):
    
    url = ee.Image(im_list.get(i)).getDownloadUrl({
        'bands': ['VV'], # 원하는 밴드 입력 RGB를 원할 경우 ['B2','B3','B4']
        'region': aoi,
        'scale': 10, # pixel spacing 설정 (10m 간격으로 픽셀 배치)
        'format': 'GEO_TIFF'
    })
    response = requests.get(url) #아래 저장 경로설정하고 그 뒤에 저장할 파일명.tif
    with open(path+'S1A_' + '20' + date[i][6:]+date[i][0:2]+date[i][3:5] + '.tif', 'wb') as fd:
      fd.write(response.content)
    print(i+1, 'images dowloaded')

 

저장된 파일은 Geotiff 형식이다. Geotiff는 영상의 정보와 함께 지리좌표 정보를 함께 저장한다. 따라서, 다양한 프로그래밍 언어 또는 GIS 툴 등에서 사용할 수 있다. 

 

어쩌면 파이썬 프로그래밍에 익숙하지 않거나 위성영상에 대해 익숙하지 않은 사람은 포스팅을 이해하기 어려울 수 있을 것 같다.

하지만, 관심과 열정 그리고 정보가 있으면 세상에는 안 되는게 없다. 

관심을 갖고 여러 매체를 찾아보다 보면 그동안 이해하지 못했던 정보들이 어느 순간 연쇄적으로 서로를 이해하게 해주는 것 같다. 그 전까지는 일단, 무작정 따라하는 것도 방법이다.

 

포스팅에 제공하는 내용들이 많은 사람에게 많은 도움이 됐으면 좋겠다.

 

다음 링크에서는 SAR 영상을 처리하기 위한 모듈이 소개되어있다.

모듈을 이용하면 이미 작성된 프로그램을 이용해 위성영상처리를 비교적 쉽게 접근할 수 있을 것 같다.

https://github.com/oriburi-quack/OriBuri/tree/main

 

GitHub - oriburi-quack/OriBuri

Contribute to oriburi-quack/OriBuri development by creating an account on GitHub.

github.com