【问题标题】:How to iterate over and download each image in an image collection from the Google Earth Engine python api如何从 Google Earth Engine python api 迭代和下载图像集中的每个图像
【发布时间】:2018-11-10 04:48:58
【问题描述】:

我是谷歌地球引擎的新手,并试图了解如何使用谷歌地球引擎 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
})

【问题讨论】:

    标签: python python-3.x google-earth-engine landsat


    【解决方案1】:

    为此使用ee.batch.Export 是个好主意。此外,最好避免混合客户端和服务器功能 (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)。但是,如果您确实需要下载,这可能是最具扩展性的方法。

    【讨论】:

    • 好电话。是的,我会看看这个方法。我以前没见过。
    【解决方案2】:

    这是我的解决方案:

    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

    【讨论】:

      【解决方案3】:

      您可以将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,但它可能会帮助您找到解决方案。

      【讨论】:

      • 是的,我看到提到了iterate 方法。我会试一试。非常感谢您的建议。
      • 您应该避免这种方法有两个原因。一,避免混合客户端(getDownloadURL())和服务器(iterate())函数(reference)是一种很好的做法。二,getDownloadURL() 不稳定,有时会导致下载损坏。
      • @NicholasClinton:谢谢。根据您的参考,getDownloadURL() 是一个 server 函数,因为它是 ee.Image() 对象上的一个方法。您是指传递给iterate() 的Python 列表和对list.append() 的调用吗?
      • @NicholasClinton:关于您的第二点,API 及其功能是实验性的,可能会发生变化。我们可以假设该方法的脆弱性可能是由于这个原因吗?
      • getDownloadURL() 片状的最佳解释是here。请注意 getDownloadURL() sends a request to the server 而 'iterate()` runs on the server
      猜你喜欢
      • 1970-01-01
      • 2019-11-25
      • 2019-03-29
      • 2021-07-21
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多