gee-community/geemap

Access to Dynamic World segmentation masks

ArthurOuaknine opened this issue · 3 comments

Hello.

I attach a screenshot of my geemap report if it is useful.
Screen Shot 2023-02-10 at 6 37 53 PM

Description

I'm looking for the Dynamic World segmentation masks, i.e. either a mask with a class number per pixel, or a mask with a probability to belong to each class per each.
I found one use case here, and a sort of description of the function I use here.
However the outputs are not easy to understand and in any case, I can't access directly the segmentation masks.

What I Did

Here is a quick example of what I'm doing

import ee
import geemap
import numpy as np

ee.Initialize()
start_date = '2021-01-01'
end_date = '2022-01-01'
region = ee.Geometry.BBox(-89.7088, 42.9006, -89.647, 42.9167)

landcover_hillshade = geemap.dynamic_world(region, start_date, end_date, return_type='hillshade')
landcover_array_hillshade = geemap.ee_to_numpy(landcover_hillshade, region=region)

landcover_class = geemap.dynamic_world(region, start_date, end_date, return_type='class')
landcover_array_class = geemap.ee_to_numpy(landcover_class, region=region)

landcover_probability = geemap.dynamic_world(region, start_date, end_date, return_type='probability')
landcover_array_probability = geemap.ee_to_numpy(landcover_probability, region=region)

landcover_visualize = geemap.dynamic_world(region, start_date, end_date, return_type='visualize')
landcover_array_visualize = geemap.ee_to_numpy(landcover_visualize, region=region)

We have landcover_array_hillshade.shape which is (246, 689, 3): it's a beautiful image with a fancy visualization of the segmentation, but it cannot be used as is.

Then landcover_array_class.shape is (1, 1, 1): I would expect this one to be (246, 689, 1) with an integer in each pixel corresponding to the class, but it is not the case. It is just a single value (4).

The landcover_array_probability is (246, 689, 1): it seems to be a binary probability (I don't know of what) but it can't be related to the segmentation mask. Since we have 9 classes, I would expect (246, 689, 9) with the output of a softmax, i.e. summing to 1 through the third dimension.

And landcover_array_visualize.shape is (1, 1, 3): there are three values (228, 150, 53) and I don't understand what there are.

This is an example but the outputs have always the same shapes when I change the coordinates.
I guess there are a few problems around, it is not clear which return_type value should return what I'm looking for.
I hope my question is clear: how to access the segmentation masks with a class or a probability to belong to a class at each pixel?
Thanks for your help.

I think it is a projection issue. See this. Feel free to reopen the issue if the problem persists.

Great, thanks for the reference.
It was indeed a projection problem.
Here is the solution I found:

import ee
import geemap
import numpy as np

ee.Initialize()
start_date = '2021-01-01'
end_date = '2022-01-01'
region = ee.Geometry.BBox(-89.7088, 42.9006, -89.647, 42.9167)

landcover_class = geemap.dynamic_world(region, start_date, end_date, return_type='class')
landcover_class = landcover_class.reproject(crs=ee.Projection('EPSG:3395'), scale=9)
landcover_array_class = geemap.ee_to_numpy(landcover_class, region=region)

where landcover_array_class.shape is (272, 766, 1) and each pixel as an integer value related to the class it belongs to.
Thanks a lot!

Great to hear that. Thank you for providing the solution.