遥感数据多种多样,存储格式各异,处理起来很麻烦。 比如很多MODIS数据都是采用HDF格式存储的,在制作深度学习样本时,需要把它转换为GeoTiff格式,可能还需要进行重投影或重采样的操作。
GEE在这方面的主要有以下优点
数据全面,不仅有很多官方数据,还有个人上传的数据。 下面介绍一下怎么从GEE下载训练数据。
1 确定数据的空间范围训练数据往往在空间分布上是零散的,如下图所示。在时间上可能各个位置也需要不同时间的数据。这个时候就需要先确定每一块的空间范围和时间。
空间范围的信息为,这一块影像的上下左右的四个坐标值,以及坐标系(每一块影像的坐标系可能不同)。时间信息为年、月、日等。
上两章我们用Langdsat8数据为例,这次也以两景Landsat8数据为例,提取这两景数据对应的相同时间相同空间位置的MODIS数据。数据存储格式如下
- data - LC08_L1TP_018030_20150907_20200908_02_T1 - LC08_L1TP_018030_20150907_20200908_02_T1_B1.TIF - LC08_L1TP_039035_20160304_20200907_02_T1 - LC08_L1TP_039035_20160304_20200907_02_T1_B1.TIF
以下代码用于提取两景影像的空间范围:
df = pd.DataFrame(columns=['id' , 'year' , 'left' , 'top' , 'right' , 'bottom' , 'crs' ])for i, id in enumerate(os.listdir('./data/' )): src = rio.open( os.path.join('./data/' , id, id+'_B1.TIF' ) ) df.loc[i, 'id' ] = id df.loc[i, 'year' ] = int(id[17 :21 ]) df.loc[i, 'left' ] = src.bounds.left df.loc[i, 'bottom' ] = src.bounds.bottom df.loc[i, 'right' ] = src.bounds.right df.loc[i, 'top' ] = src.bounds.top df.loc[i, 'crs' ] = src.crs.to_epsg() df.to_csv('./data/list.csv' , index=False ) df
2 把上一步提取的信息上传到谷歌云盘这次使用Python版的GEE下载数据,相比JavaScript版本,Python版本可以方便的读取表格数据。而JavaScript版本只支持很有限的格式,而且读取起来也很麻烦。
Python版的GEE需要在Google Colab中操作,如果不会用可以参考我的另一篇文章基于Python的遥感云计算 。
3 在Colab中读取表格信息首先新建一个 Jupyter 笔记本,使用如下代码连接到自己的谷歌云盘。
from google.colab import drive drive.mount('/content/drive' )
Colab的Python环境自带很多数据分析的包,如pandas
和numpy
等,而且还可以自己安装需要的包。下面使用pandas
读取表格信息。
import pandas as pd df = pd.read_csv('./drive/MyDrive/MCD12Q1/list.csv' ) df.head()
4 连接Earth Engine API
# 导入API import ee# 验证身份信息 ee.Authenticate()# 初始化 ee.Initialize()
5 下载数据下面的代码中,第十三行用于定义下载数据的空间范围,如果训练数据的空间范围是用shp数据指定的话,把这部分改为读取shp数据的边框范围即可。
tasks = []for row in df.itertuples(): right, bottom = row.right, row.bottom left, top = row.left, row.top crs = row.crs year = str(row.year) id = row.id image = ee.ImageCollection('MODIS/061/MCD12Q1' ) \ .filterDate(year + '-01-01' , year + '-12-31' ) \ .select('LC_Prop2' ).first() roi = ee.Geometry.Rectangle([left, bottom, right, top], proj=f'EPSG:{crs} ' , evenOdd=False ) # 设置导出参数 task_config = { 'driveFolder' : 'MCD12Q1' , # Google云盘中的文件夹名称 'driveFileNamePrefix' : id, # 导出图像的文件名前缀 'scale' : 480 , # 导出图像的空间分辨率 'region' : roi, # 导出图像的区域 'maxPixels' : 1e13 , # 允许的最大像素数 'crs' : f'EPSG:{crs} ' } # 开始导出任务 task = ee.batch.Export.image.toDrive(image, **task_config) task.start() tasks.append(task) print(id)
6 检测数据下载是否完成上述代码只是提交了下载任务,以下代码用于检查这些任务有没有全部下载完成。
import timeimport numpy as np tasks_status = [False ] * len(tasks) num = 0 while True : for i, task in enumerate(tasks): status = task.status() if status['state' ] == 'COMPLETED' : tasks_status[i] = True time.sleep(10 ) num += 1 if np.all(np.array(tasks_status)): break if num % 60 == 0 : print(f'Check {num % 60 } ' , tasks_status) print('Done' )