TransWikia.com

How to add a dummy band to selected images in an image collection?

Geographic Information Systems Asked on April 12, 2021

I’m using the GEE Python API. The Hansen & Al. glad alert dataset is currently broken and the 20 last images are missing the ‘conf19’ band. In my process I need to use it whatever the image so I’d like to add a dummy 0 value band to each image that do not contains the ‘conf19’ band.

I tried the following :

all_alerts  = ee.ImageCollection('projects/glad/alert/UpdResult')

# add the missing conf2019 to all images
def addConf2019(image):
    #retreive bands name 
    names = image.bandNames()
    
    #add conf19 if missing
    if not names.contains('conf19'):
        conf19 = image.expression(
            'conf19 = 0 * A',
            {'A' : image.select('conf20')}
        )
        
        image = image.addBands(conf19)
    
    return image

alerts_cor = all_alerts.map(addConf2019)

but when I display the bands names of the imageCollection :

band_names = alerts_cor.map(lambda image:
    image.set('bandNames', image.bandNames())
).aggregate_array('bandNames').getInfo()

band_names

not a single one changed. Do you see what I am doing wrong ?

One Answer

This is a client vs. server issue. names.contains('conf19') is an Earth Engine "computed object" which does not represent any individual image, and a Python if will always consider it to be true. You need to use the server-side conditional ee.Algorithms.If:

# add the missing conf2019 to all images
def addConf2019(image):
    #retreive bands name 
    names = image.bandNames()
    
    #add conf19 if missing
    image = ee.Algorithms.If(
        names.contains('conf19'),
        image,                 # true branch
        image.expression(      # false branch
            'conf19 = 0 * A',
            {'A' : image.select('conf20')}))
    
    return image

Note that it is in general best to avoid using ee.Algorithms.If whenever possible, as it often has poor performance such as evaluating both branches even though only one is needed, due to the nature of Earth Engine's computation framework.

In this case, we can use addBands to implement a conditional replacement of bands:

def addConf2019(image):
    fake19 = ee.Image.constant(0).rename('conf19')
    return fake19.addBands(srcImg=image, overwrite=true).copyProperties(image)

fake19 always has a conf19 band, and addBands will here replace that band with the one from image only if image has one.

There's a slight difference here: fake19 will have the pixel type "all values are 0" whereas the real dataset has a different type, and some operations will fail when there is a type mismatch. Your strategy of multiplying by 0 instead handles matching the type automatically, or you could also write ee.Image.constant(0).toByte() to set the type explicitly.

Correct answer by Kevin Reid on April 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP