Servir-Mekong / hydra-floods

HYDrologic Remote sensing Analysis for Floods Python package
https://servir-mekong.github.io/hydra-floods/
GNU General Public License v3.0
165 stars 49 forks source link

Issue implementing thresholding algorithms #44

Open devapatel3 opened 2 years ago

devapatel3 commented 2 years ago

Hello, I am having an issue implementing thresholding algorithms. I am able to get my code to work for the edge_otsu algorithm, but no others. I would like to implement the bmax_otsu in particular. My code is below.

In particular, if I run it with the line: (hf.edge_otsu, dict(band = 'VH', thresh_no_data=-20, scale = 300))

It works fine. If instead, I replace with the commented line: (hf.bmax_otsu, dict(band = 'VH', initial_threshold=0, scale = 300))

The code breaks. Do you know what I am doing wrong?

Thank you very much!

################

import pandas as pd import ee import time import os import hydrafloods as hf from hydrafloods import corrections

try: ee.Initialize() except Exception as e: ee.Authenticate() ee.Initialize()

def fc_to_dict(fc): prop_names = fc.first().propertyNames() prop_lists = fc.reduceColumns( reducer=ee.Reducer.toList().repeat(prop_names.size()), selectors=prop_names).get('list') return ee.Dictionary.fromLists(prop_names, prop_lists)

testunions = ee.FeatureCollection('projects/ee-devapatel3-bgdfloods/assets/union_test')

idname = 'ADM4_PCODE' shapefile = testunions

ids = shapefile.aggregate_array(idname).getInfo()

elv = ee.Image("JAXA/ALOS/AW3D30/V2_2").select("AVE_DSM")

start_time = "2021-07-01" end_time = "2021-11-01"

i = 'BD40878647' print('Polygon: ' + str(i)) region = shapefile.filterMetadata(idname, 'equals', i)

regiongeom=region.geometry()

s1 = hf.Sentinel1(regiongeom,start_time,end_time)

water = s1.pipe( (

Apply speckle filter

            hf.lee_sigma,
            # Apply slope correction 
            (corrections.slope_correction, dict(elevation=elv)),
            # Apply thresholding algorithm to classify water
            (hf.edge_otsu, dict(band = 'VH', thresh_no_data=-20, scale = 300))
            #(hf.bmax_otsu, dict(band = 'VH', initial_threshold=0, scale = 300))
        )
    )

watercollection = water.collection

    # Calculate average within polygon by image
    def calcflood(image):
        reduced = image.reduceRegion(
        reducer = ee.Reducer.mean(),
        geometry = regiongeom,
        scale = 300)
        return ee.Feature(None, reduced)
    results = watercollection.map(calcflood)
    results = results.filter(ee.Filter.notNull(['water']))

    # Get flood data values for dataframe
    flood_dict = fc_to_dict(results).getInfo()
    flood_df = pd.DataFrame(dict([ (k,pd.Series(v)) for k,v in flood_dict.items() ]))

    final = flood_df
ArjenHaag commented 2 years ago

Hi, thanks for posting the issue. Could you please add the error itself next time as well? That would have saved us some time.

But the error is a result of something tackled in #11: Otsu's method requires a histogram that contains data. When very little or no water is present in the image that is used to construct the histogram, it will fail. You've set a thresh_no_data value for edge_otsu, but not for bmax_otsu. If you also set it for the latter, it will work.