TransWikia.com

Visualizing Clusters with Google Earth Engine

Geographic Information Systems Asked by Blue101black on August 12, 2021

I am using kMeans clustering to visual 3 clusters of an NDVI image. The clustering is always correct, but lower values could be green, when I want them to be red. Is there anyway to guarantee consistent coloring?

I have tried hard-coding values for the classes and remapping them. Still getting random outputs.

I have added indices such as NDVI and NDRE as bands to an image collection of Sentinel-2 images.

NDVI and NDVI Clustered (Expected Result):

enter image description hereenter image description here

Using Python, but will happily accept JavaScript

Code:

# Initalise the interactive map, centered on some coordinates.
myMap = geemap.Map()
myMap.centerObject(TimeSeries_AOI, 12);
myMap.add_basemap('HYBRID')

imageList = sentinel2_AOI.toList(sentinel2_AOI.size())
listSize = imageList.size().getInfo()

'''
averageBand is a function that can get the average band in a given list.

@ band: [string] mandatory string that the function uses to display a specific band.

Returns ee.Image
'''
def averageBand(band):
    image = ee.Image(imageList.get(0)).select(band)
    
    for i in range(1, listSize):
        if (i > 10):
            break
        image = (ee.Image(imageList.get(i)).select(band)).add(image)
                
    return image.divide(i)

def displayCluster(band, numClusters = 3):
    image = averageBand(band)

    #myMap.addLayer(ee.Image().paint(TimeSeries_AOI, 0, 4), {}, 'region');
    myMap.addLayer(image, visualise[band], band)
    #myMap.addLayer(image, {}, "NDVI")

    #Make the training dataset.
    points = image.sample(**{
        'scale': 10,
        'numPixels': 40000,
        'geometries': True
    })

    #myMap.addLayer(points, {}, 'training', False)

    # Instantiate the clusterer and train it.
    clusterer = ee.Clusterer.wekaKMeans(numClusters).train(points)
    
    result = image.cluster(clusterer, "kMean")
    
    classValues = [0, 1, 2, 3, 4]
    classPalette = ['F7A738', 'CDDA49', '7DB249', '327C36', '1FBCD2']
    
    newResult = result.set('kMean_class_values', classValues)
    newResult = newResult.set('kMean_class_palette', classPalette)
    newResult.remap([0, 1, 2, 3, 4], [1, 2, 3, 4, 5], 1, 'kMean')
    
    #class_values = result.get('kMean_class_values').getInfo()
    #print(result.select('kMean'))
    
    #print(newResult.select("data_type").getInfo())
    
    #subset = newResult.select("kMean").eq(2).selfMask();
    
    #geemap.ee_export_image(newResult, filename="Cluster2.tif", scale=90, file_per_band=True)
    
    myMap.addLayer(newResult, {}, band + ": Clustered")

displayCluster("NDVI")
displayCluster("NDRE")
#displayCluster("SAVI")
#displayCluster("NDWI")
#displayCluster("CCCI")
#displayCluster("MCARI")
#displayCluster("SAVI2")
#displayCluster("MSAVIhyper")
#displayCluster("RedEdge1")
#displayCluster("RedEdge2")

myMap

One Answer

The clusters were forming correctly, but the colors were not. So the solution to the problem was to figure out what the average pixel value was under each cluster group. This allowed me to then sort the clusters in ascending order.

The way I went about this was making a multi-polygon feature collection of each cluster group. Then used an image reducer to find the mean of each cluster with a multi-polygon as the geometry bounds. Then I ordered the clusters and masked each cluster out of the inital image to color it and formed a new image by combining those masks.

Correct answer by Blue101black on August 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