Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

water detection... a suggestion. #44

Open
tlohde opened this issue Jul 26, 2024 · 1 comment
Open

water detection... a suggestion. #44

tlohde opened this issue Jul 26, 2024 · 1 comment

Comments

@tlohde
Copy link

tlohde commented Jul 26, 2024

hi.

i have had a little play with the preprocessor (see code block below) that gives the option of only masking with nan areas that are connected and large enough (pick a threshold, any threshold).

difference when plotting the DEM (values ) with/without identifying the connected groups

image

the result: fewer (spurious) line breaks in the final ridgeplot.

cheers,

from scipy.ndimage import label  # requires additional import

def preprocess(
    values=None,
    water_ntile=10,
    lake_flatness=2,
    vertical_ratio=40
    filter_groups=True,
    sq_size=3,
    grp_size=9,
    ):
    
    if values is None:
        values = self.get_elevation_data()
    nan_vals = np.isnan(values)

    values[nan_vals] = np.nanmin(values)
    scaled_values = (values - np.min(values)) / (np.max(values) - np.min(values))

    is_water = scaled_values < np.percentile(scaled_values, water_ntile)
    is_lake = rank.gradient(img_as_ubyte(scaled_values),
                                         square(sq_size)) < lake_flatness

    masked = (nan_vals | is_water | is_lake)
    
    # identify connected regions of nans / water / lake
    if filter_groups:
        
        structure = np.ones((3,3), dtype=int) # i.e. fully connected
        
        labelled, _ = label(masked,
                            structure)
        
        unique, counts = np.unique(labelled,
                                   return_counts=True)
        
        # only set to nan connected regions that 
        # are bigger than grp > size
        connected = np.in1d(labelled,
                            unique[counts > grp_size]
                            ).reshape(labelled.shape)
        
        scaled_values[connected & masked] = np.nan
    else:
        scaled_values[masked] = np.nan
    
    scaled_values = vertical_ratio * scaled_values[-1::-1]  # switch north and south
    
    return scaled_values
@ColCarroll
Copy link
Owner

This is interesting, thank you! I'll try to incorporate it when I have some time (unless you or someone else wants to make a PR...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants