From f88cfe1e57331dd2067ae75ef4261fc303ccff6b Mon Sep 17 00:00:00 2001 From: msorvoja Date: Fri, 26 Jan 2024 14:13:33 +0200 Subject: [PATCH 1/6] Add cli functions for focal, gaussian and mexican hat filters --- eis_toolkit/cli.py | 102 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/eis_toolkit/cli.py b/eis_toolkit/cli.py index 029f4ea4..cc643906 100644 --- a/eis_toolkit/cli.py +++ b/eis_toolkit/cli.py @@ -151,6 +151,27 @@ class NodataHandling(str, Enum): remove = "remove" +class FocalFilterMethod(str, Enum): + """Focal filter methods.""" + + mean = "mean" + median = "median" + + +class FocalFilterShape(str, Enum): + """Shape of the filter window.""" + + square = "square" + circle = "circle" + + +class MexicanHatFilterDirection(str, Enum): + """Direction of calculating kernel values.""" + + rectangular = "rectangular" + circular = "circular" + + RESAMPLING_MAPPING = { "nearest": warp.Resampling.nearest, "bilinear": warp.Resampling.bilinear, @@ -451,6 +472,87 @@ def descriptive_statistics_vector_cli(input_file: Annotated[Path, INPUT_FILE_OPT # --- RASTER PROCESSING --- +# FOCAL FILTER +@app.command() +def focal_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + method: FocalFilterMethod = FocalFilterMethod.mean, + size: int = 3, + shape: FocalFilterShape = FocalFilterShape.circle, +): + """Apply a basic focal filter to the input raster.""" + from eis_toolkit.raster_processing.filters.focal import focal_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + out_image, out_meta = focal_filter(raster=raster, method=method, size=size, shape=shape) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) + typer.echo("Progress: 100%") + + typer.echo(f"Focal filtering completed, output raster written to {output_raster}.") + + +# GAUSSIAN FILTER +@app.command() +def gaussian_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + sigma: float = 1.0, + truncate: float = 4.0, + size: int = None, +): + """Apply a gaussian filter to the input raster.""" + from eis_toolkit.raster_processing.filters.focal import gaussian_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + out_image, out_meta = gaussian_filter(raster=raster, sigma=sigma, truncate=truncate, size=size) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) + typer.echo("Progress: 100%") + + typer.echo(f"Gaussial filtering completed, output raster written to {output_raster}.") + + +# MEXICAN HAT FILTER +@app.command() +def mexican_hat_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + sigma: float = 1.0, + truncate: float = 4.0, + size: float = None, + direction: MexicanHatFilterDirection = MexicanHatFilterDirection.circular, +): + """Apply a mexican hat filter to the input raster.""" + from eis_toolkit.raster_processing.filters.focal import mexican_hat_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + out_image, out_meta = mexican_hat_filter( + raster=raster, sigma=sigma, truncate=truncate, size=size, direction=direction + ) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) + typer.echo("Progress: 100%") + + typer.echo(f"Mexican hat filtering completed, output raster written to {output_raster}.") + + # CHECK RASTER GRIDS @app.command() def check_raster_grids_cli(input_rasters: INPUT_FILES_ARGUMENT, same_extent: bool = False): From 59654eca34f5dc92899dc7641c3b47e05ae3e76a Mon Sep 17 00:00:00 2001 From: msorvoja Date: Wed, 31 Jan 2024 15:21:22 +0200 Subject: [PATCH 2/6] Add cli functions to gamma, frost and kuan filters and all the Lee filters --- eis_toolkit/cli.py | 217 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 209 insertions(+), 8 deletions(-) diff --git a/eis_toolkit/cli.py b/eis_toolkit/cli.py index cc643906..fb0ae435 100644 --- a/eis_toolkit/cli.py +++ b/eis_toolkit/cli.py @@ -492,10 +492,10 @@ def focal_filter_cli( typer.echo("Progress: 75%") with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) + dest.write(out_image, 1) typer.echo("Progress: 100%") - typer.echo(f"Focal filtering completed, output raster written to {output_raster}.") + typer.echo(f"Focal filter applied, output raster written to {output_raster}.") # GAUSSIAN FILTER @@ -518,10 +518,10 @@ def gaussian_filter_cli( typer.echo("Progress: 75%") with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) + dest.write(out_image, 1) typer.echo("Progress: 100%") - typer.echo(f"Gaussial filtering completed, output raster written to {output_raster}.") + typer.echo(f"Gaussial filter applied, output raster written to {output_raster}.") # MEXICAN HAT FILTER @@ -531,7 +531,7 @@ def mexican_hat_filter_cli( output_raster: Annotated[Path, OUTPUT_FILE_OPTION], sigma: float = 1.0, truncate: float = 4.0, - size: float = None, + size: int = None, direction: MexicanHatFilterDirection = MexicanHatFilterDirection.circular, ): """Apply a mexican hat filter to the input raster.""" @@ -547,10 +547,211 @@ def mexican_hat_filter_cli( typer.echo("Progress: 75%") with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) + dest.write(out_image, 1) + typer.echo("Progress: 100%") + + typer.echo(f"Mexican hat filter applied, output raster written to {output_raster}.") + + +# LEE ADDITIVE NOISE FILTER +@app.command() +def lee_additive_noise_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + size: int = 3, + add_noise_var: float = 0.25, +): + """Apply a Lee filter considering additive noise components in the input raster.""" + from eis_toolkit.raster_processing.filters.speckle import lee_additive_noise_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + out_image, out_meta = lee_additive_noise_filter(raster=raster, size=size, add_noise_var=add_noise_var) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) + typer.echo("Progress: 100%") + + typer.echo(f"Additive Lee noise filter applied, output raster written to {output_raster}.") + + +# LEE MULTIPLICATIVE NOISE FILTER +@app.command() +def lee_multiplicative_noise_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + size: int = 3, + multi_noise_mean: float = 1.0, + n_looks: int = 1, +): + """Apply a Lee filter considering multiplicative noise components in the input raster.""" + from eis_toolkit.raster_processing.filters.speckle import lee_multiplicative_noise_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + out_image, out_meta = lee_multiplicative_noise_filter( + raster=raster, size=size, mult_noise_mean=multi_noise_mean, n_looks=n_looks + ) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) + typer.echo("Progress: 100%") + + typer.echo(f"Multiplicative Lee noise filter applied, output raster written to {output_raster}.") + + +# LEE ADDITIVE MULTIPLICATIVE NOISE FILTER +@app.command() +def lee_additive_multiplicative_noise_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + size: int = 3, + add_noise_var: float = 0.25, + add_noise_mean: float = 0, + multi_noise_mean: float = 1.0, +): + """Apply a Lee filter considering both additive and multiplicative noise components in the input raster.""" + from eis_toolkit.raster_processing.filters.speckle import lee_additive_multiplicative_noise_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + out_image, out_meta = lee_additive_multiplicative_noise_filter( + raster=raster, + size=size, + add_noise_var=add_noise_var, + add_noise_mean=add_noise_mean, + mult_noise_mean=multi_noise_mean, + ) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) + typer.echo("Progress: 100%") + + typer.echo(f"Additive multiplicative Lee noise filter applied, output raster written to {output_raster}.") + + +# LEE ENHANCED FILTER +# TODO: SystemError: returned a result with an exception set +@app.command() +def lee_enhanced_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + size: int = 3, + n_looks: float = 1.0, + damping_factor: float = 1.0, +): + """Apply an enhanced Lee filter to the input raster.""" + from eis_toolkit.raster_processing.filters.speckle import lee_enhanced_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + out_image, out_meta = lee_enhanced_filter( + raster=raster, size=size, n_looks=n_looks, damping_factor=damping_factor + ) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) + typer.echo("Progress: 100%") + + typer.echo(f"Enhanced Lee filter applied, output raster written to {output_raster}.") + + +# GAMMA FILTER +@app.command() +def gamma_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + size: int = 3, + n_looks: float = 1.0, +): + """Apply a Gamma filter to the input raster.""" + from eis_toolkit.raster_processing.filters.speckle import gamma_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + print(f"input_raster: {type(raster)}") + print(f"size: {type(size)}") + print(f"n_looks: {type(n_looks)}") + out_image, out_meta = gamma_filter(raster=raster, size=size, n_looks=n_looks) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) + typer.echo("Progress: 100%") + + typer.echo(f"Gamma filter applied, output raster written to {output_raster}.") + + +# FROST FILTER +# TODO: SystemError: returned a result with an exception set +@app.command() +def frost_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + size: int = 3, + damping_factor: float = 1.0, +): + """Apply a Frost filter to the input raster.""" + from eis_toolkit.raster_processing.filters.speckle import frost_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("Progress: 25%") + print(f"input_raster: {type(raster)}") + print(f"size: {type(size)}") + print(f"damping_factor: {type(damping_factor)}") + out_image, out_meta = frost_filter(raster=raster, size=size, damping_factor=damping_factor) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) + typer.echo("Progress: 100%") + + typer.echo(f"Frost filter applied, output raster written to {output_raster}.") + + +# KUAN FILTER +# TODO: SystemError: returned a result with an exception set +@app.command() +def kuan_filter_cli( + input_raster: Annotated[Path, INPUT_FILE_OPTION], + output_raster: Annotated[Path, OUTPUT_FILE_OPTION], + size: int = 3, + n_looks: float = 1.0, +): + """Apply a Kuan filter to the input raster.""" + from eis_toolkit.raster_processing.filters.speckle import kuan_filter + + typer.echo("Progress: 10%") + + with rasterio.open(input_raster) as raster: + typer.echo("progress: 25%") + print(f"input_raster: {type(raster)}") + print(f"size: {type(size)}") + print(f"n_looks: {type(n_looks)}") + out_image, out_meta = kuan_filter(raster=raster, size=size, n_looks=n_looks) + typer.echo("Progress: 75%") + + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) typer.echo("Progress: 100%") - typer.echo(f"Mexican hat filtering completed, output raster written to {output_raster}.") + typer.echo(f"Kuan filter applied, output raster written to {output_raster}.") # CHECK RASTER GRIDS @@ -1625,7 +1826,7 @@ def sum_overlay_cli( # GAMMA OVERLAY @app.command() -def gamme_overlay_cli( +def gamma_overlay_cli( input_raster: Annotated[Path, INPUT_FILE_OPTION], output_raster: Annotated[Path, OUTPUT_FILE_OPTION], gamma: float = typer.Option(), From 69787be36faf2663089d1161e4189cd0a418aff2 Mon Sep 17 00:00:00 2001 From: Michael Steffen Date: Fri, 1 Mar 2024 12:54:31 +0100 Subject: [PATCH 3/6] Bug fix for CLI filter functions in speckle.py and cli.py Bug fixes for kuan, frost and lee-enhanced speckle filters. Functions had inconsistent type declarations for n_looks (must be integer) and damping_factor (must be Number or float). That issue apparently confused the CLI calls. Also updated the cli.py to be consistent with the speckle code. --- eis_toolkit/cli.py | 6 +++--- eis_toolkit/raster_processing/filters/speckle.py | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/eis_toolkit/cli.py b/eis_toolkit/cli.py index f194d2ba..e592e634 100644 --- a/eis_toolkit/cli.py +++ b/eis_toolkit/cli.py @@ -695,7 +695,7 @@ def lee_enhanced_filter_cli( input_raster: Annotated[Path, INPUT_FILE_OPTION], output_raster: Annotated[Path, OUTPUT_FILE_OPTION], size: int = 3, - n_looks: float = 1.0, + n_looks: int = 1, damping_factor: float = 1.0, ): """Apply an enhanced Lee filter to the input raster.""" @@ -723,7 +723,7 @@ def gamma_filter_cli( input_raster: Annotated[Path, INPUT_FILE_OPTION], output_raster: Annotated[Path, OUTPUT_FILE_OPTION], size: int = 3, - n_looks: float = 1.0, + n_looks: int = 1, ): """Apply a Gamma filter to the input raster.""" from eis_toolkit.raster_processing.filters.speckle import gamma_filter @@ -781,7 +781,7 @@ def kuan_filter_cli( input_raster: Annotated[Path, INPUT_FILE_OPTION], output_raster: Annotated[Path, OUTPUT_FILE_OPTION], size: int = 3, - n_looks: float = 1.0, + n_looks: int = 1, ): """Apply a Kuan filter to the input raster.""" from eis_toolkit.raster_processing.filters.speckle import kuan_filter diff --git a/eis_toolkit/raster_processing/filters/speckle.py b/eis_toolkit/raster_processing/filters/speckle.py index 387fd801..0c0a552c 100644 --- a/eis_toolkit/raster_processing/filters/speckle.py +++ b/eis_toolkit/raster_processing/filters/speckle.py @@ -179,7 +179,7 @@ def _gamma(window: np.ndarray, n_looks: int) -> np.ndarray: @beartype -def _frost(window: np.ndarray, damping_factor: int) -> Number: +def _frost(window: np.ndarray, damping_factor: Number) -> Number: """ Calculate the weighted value for a Frost filter from a window of pixels. @@ -381,8 +381,8 @@ def lee_additive_multiplicative_noise_filter( def lee_enhanced_filter( raster: rasterio.io.DatasetReader, size: int = 3, - n_looks: Number = 1, - damping_factor: Number = 1, + n_looks: int = 1, + damping_factor: Number = 1.0, ) -> tuple[np.ndarray, dict]: """ Apply an enhanced Lee filter to the input raster. @@ -423,7 +423,7 @@ def lee_enhanced_filter( out_array = cast_array_to_float(out_array, cast_float=True) out_meta = raster.meta.copy() - + return out_array, out_meta @@ -431,7 +431,7 @@ def lee_enhanced_filter( def gamma_filter( raster: rasterio.io.DatasetReader, size: int = 3, - n_looks: Number = 1, + n_looks: int = 1, ) -> tuple[np.ndarray, dict]: """ Apply a Gamma filter to the input raster. @@ -476,7 +476,7 @@ def gamma_filter( def frost_filter( raster: rasterio.io.DatasetReader, size: int = 3, - damping_factor: Number = 1, + damping_factor: Number = 1.0, ) -> tuple[np.ndarray, dict]: """ Apply a Frost filter to the input raster. @@ -521,7 +521,7 @@ def frost_filter( def kuan_filter( raster: rasterio.io.DatasetReader, size: int = 3, - n_looks: Number = 1, + n_looks: int = 1, ) -> tuple[np.ndarray, dict]: """ Apply a Kuan filter to the input raster. From d6c6eabc1c14ace37a56a340133e295129b5f14d Mon Sep 17 00:00:00 2001 From: Niko Aarnio Date: Mon, 4 Mar 2024 09:28:56 +0200 Subject: [PATCH 4/6] clean(cli): removed debug prints and todo comments for filter functions --- eis_toolkit/cli.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/eis_toolkit/cli.py b/eis_toolkit/cli.py index e592e634..79061fc5 100644 --- a/eis_toolkit/cli.py +++ b/eis_toolkit/cli.py @@ -689,7 +689,6 @@ def lee_additive_multiplicative_noise_filter_cli( # LEE ENHANCED FILTER -# TODO: SystemError: returned a result with an exception set @app.command() def lee_enhanced_filter_cli( input_raster: Annotated[Path, INPUT_FILE_OPTION], @@ -732,9 +731,6 @@ def gamma_filter_cli( with rasterio.open(input_raster) as raster: typer.echo("Progress: 25%") - print(f"input_raster: {type(raster)}") - print(f"size: {type(size)}") - print(f"n_looks: {type(n_looks)}") out_image, out_meta = gamma_filter(raster=raster, size=size, n_looks=n_looks) typer.echo("Progress: 75%") @@ -746,7 +742,6 @@ def gamma_filter_cli( # FROST FILTER -# TODO: SystemError: returned a result with an exception set @app.command() def frost_filter_cli( input_raster: Annotated[Path, INPUT_FILE_OPTION], @@ -761,9 +756,6 @@ def frost_filter_cli( with rasterio.open(input_raster) as raster: typer.echo("Progress: 25%") - print(f"input_raster: {type(raster)}") - print(f"size: {type(size)}") - print(f"damping_factor: {type(damping_factor)}") out_image, out_meta = frost_filter(raster=raster, size=size, damping_factor=damping_factor) typer.echo("Progress: 75%") @@ -775,7 +767,6 @@ def frost_filter_cli( # KUAN FILTER -# TODO: SystemError: returned a result with an exception set @app.command() def kuan_filter_cli( input_raster: Annotated[Path, INPUT_FILE_OPTION], @@ -790,9 +781,6 @@ def kuan_filter_cli( with rasterio.open(input_raster) as raster: typer.echo("progress: 25%") - print(f"input_raster: {type(raster)}") - print(f"size: {type(size)}") - print(f"n_looks: {type(n_looks)}") out_image, out_meta = kuan_filter(raster=raster, size=size, n_looks=n_looks) typer.echo("Progress: 75%") From bf771513771dfed0d8e07b470dd345befa512346 Mon Sep 17 00:00:00 2001 From: Niko Aarnio Date: Mon, 4 Mar 2024 09:34:51 +0200 Subject: [PATCH 5/6] lint --- eis_toolkit/raster_processing/filters/speckle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eis_toolkit/raster_processing/filters/speckle.py b/eis_toolkit/raster_processing/filters/speckle.py index 0c0a552c..b1aa2779 100644 --- a/eis_toolkit/raster_processing/filters/speckle.py +++ b/eis_toolkit/raster_processing/filters/speckle.py @@ -423,7 +423,7 @@ def lee_enhanced_filter( out_array = cast_array_to_float(out_array, cast_float=True) out_meta = raster.meta.copy() - + return out_array, out_meta From 0e078aee31235bef930599b09db67fd396d38714 Mon Sep 17 00:00:00 2001 From: Niko Aarnio Date: Mon, 4 Mar 2024 09:46:05 +0200 Subject: [PATCH 6/6] lint --- eis_toolkit/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eis_toolkit/cli.py b/eis_toolkit/cli.py index c41e82af..c92246c8 100644 --- a/eis_toolkit/cli.py +++ b/eis_toolkit/cli.py @@ -220,7 +220,7 @@ class MexicanHatFilterDirection(str, Enum): rectangular = "rectangular" circular = "circular" - + class LocalMoranWeightType(str, Enum): """Weight type for Local Moran's I."""