如何从 Google Earth Engine python api 迭代和下载图像集合中的每个图像

How to iterate over and download each image in an image collection from the Google Earth Engine python api

我是 google Earth Engine 的新手,正在尝试了解如何使用 Google Earth Engine python api。我可以创建图像集,但显然 getdownloadurl() 方法仅对单个图像起作用。所以我想了解如何遍历和下载集合中的所有图像。

这是我的基本代码。我为我正在做的其他一些工作详细地分解了它。

import ee
ee.Initialize()
col = ee.ImageCollection('LANDSAT/LC08/C01/T1')
col.filterDate('1/1/2015', '4/30/2015')
pt = ee.Geometry.Point([-2.40986111110000012, 26.76033333330000019])
buff = pt.buffer(300)
region = ee.Feature.bounds(buff)
col.filterBounds(region)

所以我提取了 Landsat 集合,按日期和缓冲区几何过滤。所以我应该在集合中有 7-8 张图像(所有波段)。

但是,我似乎无法对集合进行迭代。

例如:

for i in col:
    print(i)

错误提示TypeError: 'ImageCollection' object is not iterable

所以如果集合不可迭代,我如何访问单个图像?

有了图像后,我应该可以使用通常的

path = col[i].getDownloadUrl({
    'scale': 30,
    'crs': 'EPSG:4326',
    'region': region
})

您可以将 ee.ImageCollection.iterate() 与获取图像并将其添加到列表的函数一起使用。

import ee

def accumluate_images(image, images):
    images.append(image)
    return images

for img in col.iterate(accumulate_images, []):
    url = img.getDownloadURL(dict(scale=30, crs='EPSG:4326', region=region))

不幸的是,我无法测试此代码,因为我无法访问 API,但它可能会帮助您找到解决方案。

最好使用 ee.batch.Export for this. Also, it's good practice to avoid mixing client and server functions (reference)。因此,可以使用 for 循环,因为 Export 是一个客户端函数。这是一个帮助您入门的简单示例:

import ee
ee.Initialize()

rectangle = ee.Geometry.Rectangle([-1, -1, 1, 1])
sillyCollection = ee.ImageCollection([ee.Image(1), ee.Image(2), ee.Image(3)])

# This is OK for small collections
collectionList = sillyCollection.toList(sillyCollection.size())
collectionSize = collectionList.size().getInfo()
for i in xrange(collectionSize):
    ee.batch.Export.image.toDrive(
        image = ee.Image(collectionList.get(i)).clip(rectangle), 
        fileNamePrefix = 'foo' + str(i + 1), 
        dimensions = '128x128').start()

请注意,以这种方式将集合转换为列表对于大型集合 (reference) 也是危险的。但是,如果您确实需要下载,这可能是最具扩展性的方法。

这是我的解决方案:

import ee
ee.Initialize()
pt = ee.Geometry.Point([-2.40986111110000012, 26.76033333330000019])
region = pt.buffer(10)

col = ee.ImageCollection('LANDSAT/LC08/C01/T1')\
        .filterDate('2015-01-01','2015-04-30')\
        .filterBounds(region)

bands = ['B4','B5'] #Change it!

def accumulate(image,img):
  name_image = image.get('system:index')
  image = image.select([0],[name_image])
  cumm = ee.Image(img).addBands(image)
  return cumm

for band in bands:
  col_band = col.map(lambda img: img.select(band)\
                               .set('system:time_start', img.get('system:time_start'))\
                               .set('system:index', img.get('system:index')))
  #  ImageCollection to List           
  col_list = col_band.toList(col_band.size())

  #  Define the initial value for iterate.
  base = ee.Image(col_list.get(0))
  base_name = base.get('system:index')
  base = base.select([0], [base_name])

  #  Eliminate the image 'base'.
  new_col = ee.ImageCollection(col_list.splice(0,1))

  img_cummulative = ee.Image(new_col.iterate(accumulate,base))

  task = ee.batch.Export.image.toDrive(
      image = img_cummulative.clip(region),
      folder = 'landsat',
      fileNamePrefix = band,
      scale = 30).start()  

  print('Export Image '+ band+ ' was submitted, please wait ...')

img_cummulative.bandNames().getInfo()

您能否在此处找到可重现的示例:https://colab.research.google.com/drive/1Nv8-l20l82nIQ946WR1iOkr-4b_QhISu

我有一个类似的问题,无法使用提供的解决方案解决。然后我为此详细阐述了一个示例代码。它在客户端迭代图像集合,然后不受 .map().iterate().

限制(仅限服务器端)的影响

可以下载代码并查看其解释here

它基本上将 ImageCollection 转换为列表 (ic.toList())。然后它执行标准循环,对于每个单独的图像,可以将其转换回 ee.Image(list.get(i)),然后一张一张地处理集合中的所有图像。

在您的特定情况下,要下载每个图像,循环内调用的函数可以是:getDOwnloadURL()getThumbURL():

var url = imgNew.getDownloadURL({
    region: geometry,
  });

var thumbURL = imgNew.getThumbURL({region: geometry,dimensions: 512, format: 'png'});