Skip to content

Commit 87c6b64

Browse files
authored
Merge pull request #55 from swiss-territorial-data-lab/ch/mes_filter-script
Ch/mes filter script
2 parents 437d650 + 65c0614 commit 87c6b64

File tree

2 files changed

+5
-55
lines changed

2 files changed

+5
-55
lines changed

examples/mineral-extract-sites-detection/config_det.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,11 @@ merge_detections.py:
6363
iou_threshold: 0.1
6464
score_threshold: 0.3 # choose a value
6565

66-
# Filtering and merging detection polygons
66+
# Filtering and merging detection polygons to improve final results
6767
filter_detections.py:
6868
working_directory: data
6969
detections: ../output/det/merged_detections_at_0dot3_threshold.gpkg
70-
aoi: AoI/AoI_2020.shp
71-
dem: DEM/switzerland_dem_EPSG2056.tif
70+
dem: DEM/switzerland_dem_EPSG2056.tif # optional
7271
elevation_threshold: 1200 # m, altitude threshold, optional
7372
score_threshold: 0.95 # detection score (from 0 to 1) provided by detectron2, optional
7473
area_threshold: 5000 # m2, area threshold under which polygons are discarded, optional

examples/mineral-extract-sites-detection/filter_detections.py

Lines changed: 3 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#!/bin/python
2-
# -*- coding: utf-8 -*-
3-
41
import argparse
52
import os
63
import sys
@@ -33,41 +30,14 @@ def check_gdf_len(gdf):
3330
sys.exit(1)
3431

3532

36-
def get_mean_slope_for_detection(detection_geometry, slope_raster):
37-
"""
38-
Calculate the mean slope for the detection polygon.
39-
40-
Args:
41-
detection_geometry (Shape): polygon shape of the detections.
42-
slope_raster (raster): raster slope.
43-
44-
Returns:
45-
mean_slope: float value of the polygon mean slope
46-
"""
47-
48-
# Mask the slope raster with the detection geometry, crop to the detection area
49-
out_image, out_transform = mask(slope_raster, [detection_geometry], crop=True)
50-
# Mask the slope values that are outside the detection area (i.e., no data or zeros)
51-
out_image = np.ma.masked_where(out_image == slope_raster.nodata, out_image)
52-
# Calculate the mean slope for the masked area
53-
mean_slope = out_image.mean() # Mean of the valid, non-masked slope values
54-
55-
return mean_slope
56-
57-
58-
def none_if_undefined(cfg, key):
59-
60-
return cfg[key] if key in cfg.keys() else None
61-
62-
6333
if __name__ == "__main__":
6434

6535
# Chronometer
6636
tic = time.time()
6737
logger.info('Starting...')
6838

6939
# Argument and parameter specification
70-
parser = argparse.ArgumentParser(description="The script post-processes the detections obtained with the object-detector")
40+
parser = argparse.ArgumentParser(description="The script filters the detection of potential Mineral Extraction Sites obtained with the object-detector scripts")
7141
parser.add_argument('config_file', type=str, help='input geojson path')
7242
args = parser.parse_args()
7343

@@ -78,15 +48,11 @@ def none_if_undefined(cfg, key):
7848

7949
# Load input parameters
8050
WORKING_DIR = cfg['working_directory']
81-
AOI = cfg['aoi']
8251
DETECTIONS = cfg['detections']
8352
DEM = misc.none_if_undefined(cfg, 'dem')
84-
SLOPE = misc.none_if_undefined(cfg, 'slope')
8553
SCORE_THD = cfg['score_threshold']
8654
AREA_THD = cfg['area_threshold']
8755
ELEVATION_THD = misc.none_if_undefined(cfg, 'elevation_threshold')
88-
MIN_SLOPE_THD = misc.none_if_undefined(cfg, 'min_slope_threshold')
89-
MAX_SLOPE_THD = misc.none_if_undefined(cfg, 'max_slope_threshold')
9056

9157
os.chdir(WORKING_DIR)
9258
logger.info(f'Working directory set to {WORKING_DIR}')
@@ -98,17 +64,13 @@ def none_if_undefined(cfg, key):
9864
detections_gdf = detections_gdf.to_crs(2056)
9965
if 'tag' in detections_gdf.keys():
10066
detections_gdf = detections_gdf[detections_gdf['tag']!='FN']
101-
detections_gdf['area'] = detections_gdf.geometry.area
10267
detections_gdf['det_id'] = detections_gdf.index
10368
total = len(detections_gdf)
10469
logger.info(f"{total} detections")
10570

10671
detections_gdf = misc.check_validity(detections_gdf, correct=True)
10772

108-
aoi_gdf = gpd.read_file(AOI)
109-
aoi_gdf = aoi_gdf.to_crs(2056)
110-
111-
# Discard polygons detected at/below 0 m and above the threshold elevation and above a given slope
73+
# Discard polygons detected at/below 0 m and above the threshold elevation
11274
if DEM:
11375
dem_raster = rio.open(DEM)
11476

@@ -122,17 +84,6 @@ def none_if_undefined(cfg, key):
12284
total = total - len(detections_gdf)
12385
logger.info(f"{total} detections were removed by elevation threshold: {ELEVATION_THD} m")
12486

125-
# Discard polygons detected above the slope threshold
126-
if SLOPE:
127-
check_gdf_len(detections_gdf)
128-
129-
slope_raster = rio.open(SLOPE)
130-
131-
detections_gdf['mean_slope'] = detections_gdf.geometry.apply(lambda geom: get_mean_slope_for_detection(geom, slope_raster))
132-
detections_gdf = detections_gdf[(detections_gdf['mean_slope'] > MIN_SLOPE_THD) & (detections_gdf['mean_slope'] < MAX_SLOPE_THD)]
133-
total = total - len(detections_gdf)
134-
logger.info(f"{total} detections were removed by slope threshold: [{MIN_SLOPE_THD} - {MAX_SLOPE_THD}] degrees")
135-
13687
# Filter dataframe by score value
13788
check_gdf_len(detections_gdf)
13889
detections_score_gdf = detections_gdf[detections_gdf.score > SCORE_THD]
@@ -154,7 +105,7 @@ def none_if_undefined(cfg, key):
154105
logger.info(f"{len(detections_gdf)} detections remaining after filtering")
155106

156107
# Formatting the output name of the filtered detection
157-
feature = f'{DETECTIONS[:-5]}_score-{SCORE_THD}_area-{str(AREA_THD)}_elevation-{str(ELEVATION_THD)}_slope-{str(MIN_SLOPE_THD)}-{str(MAX_SLOPE_THD)}'.replace('0.', '0dot') + '.gpkg'
108+
feature = f'{DETECTIONS[:-5]}_score-{SCORE_THD}_area-{str(AREA_THD)}_elevation-{str(ELEVATION_THD)}'.replace('0.', '0dot') + '.gpkg'
158109
detections_gdf.to_file(feature)
159110

160111
written_files.append(feature)

0 commit comments

Comments
 (0)