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

Rename predictions -> detections #18

Merged
merged 15 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ A CUDA-enabled GPU is required.

* CUDA driver. This code was developed and tested with CUDA 11.3 on Ubuntu 20.04.

* Although we recommend the usage of Docker (see [here](#with-docker)), this code can also be run without Docker, provided that Python 3.8 is available. Python dependencies may be installed with either `pip` or `conda`, using the provided `requirements.txt` file. We advise using a [Python virtual environment](https://docs.python.org/3/library/venv.html).
* Although we recommend the usage of [Docker](https://www.docker.com/) (see [here](#with-docker)), this code can also be run without Docker, provided that Python 3.8 is available. Python dependencies may be installed with either `pip` or `conda`, using the provided `requirements.txt` file. We advise using a [Python virtual environment](https://docs.python.org/3/library/venv.html).

## Installation

### Without Docker

The object detector can be installed by issuing the following command (see [this page](https://setuptools.pypa.io/en/latest/userguide/development_mode.html) for more information on the "editable install"):
The object detector can be installed by issuing the following command (see [this page](https://setuptools.pypa.io/en/latest/userguide/development_mode.html) for more information on the "editable installs"):

```bash
$ pip install --editable .
Expand Down Expand Up @@ -71,8 +71,8 @@ This project implements the workflow described [here](https://tech.stdl.ch/TASK-
| :-: | --- | --- | --- |
| 1 | Tileset generation | `generate_tilesets` | [here](scripts/generate_tilesets.py) |
| 2 | Model training | `train_model` | [here](scripts/train_model.py) |
| 3 | Prediction | `make_predictions` | [here](scripts/train_model.py) |
| 4 | Assessment | `assess_predictions` | [here](scripts/assess_predictions.py) |
| 3 | Detection | `make_detections` | [here](scripts/make_detections.py) |
| 4 | Assessment | `assess_detections` | [here](scripts/assess_detections.py) |

These stages/scripts can be run one after the other, by issuing the following command from a terminal:

Expand Down Expand Up @@ -105,7 +105,7 @@ These stages/scripts can be run one after the other, by issuing the following co

The same configuration file can be used for all the commands, as each of them only reads the content related to a key named after its name. More detailed information about each stage and the related configuration is provided here-below. The following terminology is used:

* **ground-truth data**: data to be used to train the Deep Learning-based predictive model; such data is expected to be 100% true
* **ground-truth data**: data to be used to train the Deep Learning-based detection model; such data is expected to be 100% true

* **GT**: abbreviation of ground-truth

Expand Down Expand Up @@ -194,7 +194,7 @@ Note that:
> **Note**
This stage can be skipped if the user wishes to perform inference only, using a pre-trained model.

The `train_model` command allows one to train a predictive model based on a Convolutional Deep Neural Network, leveraging [FAIR's Detectron2](https://github.com/facebookresearch/detectron2). For further information, we refer the user to the [official documention](https://detectron2.readthedocs.io/en/latest/).
The `train_model` command allows one to train a detection model based on a Convolutional Deep Neural Network, leveraging [FAIR's Detectron2](https://github.com/facebookresearch/detectron2). For further information, we refer the user to the [official documention](https://detectron2.readthedocs.io/en/latest/).

Here's the excerpt of the configuration file relevant to this script, with values replaced by textual documentation:

Expand All @@ -214,17 +214,17 @@ train_model.py:

Detectron2 configuration files are provided in the example folders mentioned here-below. We warn the end-user about the fact that, **for the time being, no hyperparameters tuning is automatically performed**.

### Stage 3: prediction
### Stage 3: detection

The `make_predictions` command allows one to use the predictive model trained at the previous step to make predictions over various input datasets:
The `make_detections` command allows one to use the object detection model trained at the previous step to make detections over various input datasets:

* predictions over the `trn`, `val`, `tst` datasets can be used to assess the reliability of this approach on ground-truth data;
* predictions over the `oth` dataset are, in principle, the main goal of this kind of analyses.
* detections over the `trn`, `val`, `tst` datasets can be used to assess the reliability of this approach on ground-truth data;
* detections over the `oth` dataset are, in principle, the main goal of this kind of analyses.

Here's the excerpt of the configuration file relevant to this script, with values replaced by textual documentation:

```yaml
make_predictions.py:
make_detections.py:
working_folder: <the script will chdir into this folder>
log_subfolder: <the subfolder of the working folder where we allow Detectron2 writing some logs>
sample_tagged_img_subfolder: <the subfolder where some sample images will be output>
Expand All @@ -238,24 +238,24 @@ make_predictions.py:
pth_file: <e.g. "./logs/model_final.pth">
image_metadata_json: <the path to the image metadata JSON file, generated by the `generate_tilesets` command>
# the following section concerns the Ramer-Douglas-Peucker algorithm,
# which can be optionally applied to prediction before they are exported
# which can be optionally applied to detections before they are exported
rdp_simplification:
enabled: <true/false>
epsilon: <see https://rdp.readthedocs.io/en/latest/>
score_lower_threshold: <choose a value between 0 and 1, e.g. 0.05 - predictions with a score less than this threshold would be discarded>
score_lower_threshold: <choose a value between 0 and 1, e.g. 0.05 - detections with a score less than this threshold would be discarded>
```

### Stage 4: assessment

The `assess_predictions` command allows one to assess the reliability of predictions, comparing predictions with ground-truth data. The assessment goes through the following steps:
The `assess_detections` command allows one to assess the reliability of detections, comparing detections with ground-truth data. The assessment goes through the following steps:

1. Labels (GT + `oth`) geometries are clipped to the boundaries of the various AoI tiles, scaled by a factor 0.999 in order to prevent any "crosstalk" between neighboring tiles.

2. Vector features are extracted from Detectron2's predictions, which are originally in a raster format (`numpy` arrays, to be more precise).
2. Vector features are extracted from Detectron2's detections, which are originally in a raster format (`numpy` arrays, to be more precise).

3. Spatial joins are computed between the vectorized predictions and the clipped labels, in order to identify
* True Positives (TP), *i.e.* objects that are found in both datasets, labels and predictions;
* False Positives (FP), *i.e.* objects that are only found in the predictions dataset;
3. Spatial joins are computed between the vectorized detections and the clipped labels, in order to identify
* True Positives (TP), *i.e.* objects that are found in both datasets, labels and detections;
* False Positives (FP), *i.e.* objects that are only found in the detections dataset;
* False Negatives (FN), *i.e.* objects that are only found in the labels dataset.

4. Finally, TPs, FPs and FNs are counted in order to compute the following metrics (see [this page](https://en.wikipedia.org/wiki/Precision_and_recall)) :
Expand All @@ -265,17 +265,17 @@ The `assess_predictions` command allows one to assess the reliability of predict

Here's the excerpt of the configuration file relevant to this command, with values replaced by textual documentation:
```yaml
assess_predictions.py:
assess_detections.py:
datasets:
ground_truth_labels_geojson: <the path to GT labels in GeoJSON format>
other_labels_geojson: <the path to "other labels" in GeoJSON format>
image_metadata_json: <the path to the image metadata JSON file, generated by the `generate_tilesets` command>
split_aoi_tiles_geojson: <the path to the GeoJSON file including split (trn, val, tst, out) AoI tiles>
predictions:
trn: <the path to the Pickle file including predictions over the trn dataset (optional)>
val: <the path to the Pickle file including predictions over the val dataset (mandatory)>
tst: <the path to the Pickle file including predictions over the tst dataset (optional)>
oth: <the path to the Pickle file including predictions over the oth dataset (optional)>
detections:
trn: <the path to the Pickle file including detections over the trn dataset (optional)>
val: <the path to the Pickle file including detections over the val dataset (mandatory)>
tst: <the path to the Pickle file including detections over the tst dataset (optional)>
oth: <the path to the Pickle file including detections over the oth dataset (optional)>
output_folder: <the folder where we allow this command to write output files>
```

Expand Down
12 changes: 6 additions & 6 deletions examples/quarry-detection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ It consists of the following elements:
- the delimitation of the **Area of Interest (AoI)**;
- the Swiss DEM raster is too large to be saved on this platform but can be downloaded from this [link](https://github.com/lukasmartinelli/swissdem) using the [EPSG:4326](https://epsg.io/4326) coordinate reference system. The raster must be re-projected to [EPSG:2056](https://epsg.io/2056), renamed as `switzerland_dem_EPSG2056.tif` and located in the **DEM** subfolder. This procedure is managed by running the bash script `get_dem.sh`.
- A data preparation script (`prepare_data.py`) producing the files to be used as input to the `generate_tilesets` stage.
- A post-processing script (`filter_predictions.py`) which filters detections according to their confidence score, altitude and area. The script also identifies and merges groups of nearby polygons.
- A post-processing script (`filter_detections.py`) which filters detections according to their confidence score, altitude and area. The script also identifies and merges groups of nearby polygons.

The workflow can be run end-to-end by issuing the following list of commands, from the root folder of this GitHub repository:

Expand All @@ -23,20 +23,20 @@ nobody@<id>:/app# cd examples/quarry-detection
nobody@<id>:/app# python prepare_data.py config_trne.yaml
nobody@<id>:/app# stdl-objdet generate_tilesets config_trne.yaml
nobody@<id>:/app# stdl-objdet train_model config_trne.yaml
nobody@<id>:/app# stdl-objdet make_predictions config_trne.yaml
nobody@<id>:/app# stdl-objdet assess_predictions config_trne.yaml
nobody@<id>:/app# stdl-objdet make_detections config_trne.yaml
nobody@<id>:/app# stdl-objdet assess_detections config_trne.yaml
nobody@<id>:/app# python prepare_data.py config_prd.yaml
nobody@<id>:/app# stdl-objdet generate_tilesets config_prd.yaml
nobody@<id>:/app# stdl-objdet make_predictions config_prd.yaml
nobody@<id>:/app# stdl-objdet make_detections config_prd.yaml
nobody@<id>:/app# bash get_dem.sh
nobody@<id>:/app# python filter_predictions.py config_prd.yaml
nobody@<id>:/app# python filter_detections.py config_prd.yaml
nobody@<id>:/app# exit
$ sudo chmod -R a+w examples
```

We strongly encourage the end-user to review the provided `config_trne.yaml` and `config_prd.yaml` files as well as the various output files, a list of which is printed by each script before exiting.

The model is trained on the 2020 [SWISSIMAGE](https://www.swisstopo.admin.ch/fr/geodata/images/ortho/swissimage10.html) mosaic. Inference can be performed on SWISSIMAGE mosaics of the product SWISSIMAGE time travel by changing the year in `config_prd.yaml`. It should be noted that the model has been trained on RGB images and might not perform as well on B&W images.
The model is trained on the 2020 [SWISSIMAGE](https://www.swisstopo.admin.ch/fr/geodata/images/ortho/swissimage10.html) mosaic. Inference can be performed on SWISSIMAGE mosaics of the product [SWISSIMAGE time travel](https://map.geo.admin.ch/?lang=en&topic=swisstopo&bgLayer=ch.swisstopo.pixelkarte-farbe&zoom=0&layers_timestamp=2004,2004,&layers=ch.swisstopo.swissimage-product,ch.swisstopo.swissimage-product.metadata,ch.swisstopo.images-swissimage-dop10.metadata&E=2594025.91&N=1221065.68&layers_opacity=1,0.7,1&time=2004&layers_visibility=true,true,false) by changing the year in `config_prd.yaml`. It should be noted that the model has been trained on RGB images and might not perform as well on B&W images.

For more information about this project, see [this repository](https://github.com/swiss-territorial-data-lab/proj-dqry) (not public yet).

Expand Down
12 changes: 6 additions & 6 deletions examples/quarry-detection/config_prd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ generate_tilesets.py:
url: https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.swissimage-product/default/2020/3857/{z}/{x}/{y}.jpeg
output_folder: ./output/output_prd
tile_size: 256 # per side, in pixels
overwrite: True
overwrite: False
n_jobs: 10
COCO_metadata:
year: 2021
Expand All @@ -36,7 +36,7 @@ generate_tilesets.py:
supercategory: "Land usage"

# 3-Perform the object detection based on the optimized trained model
make_predictions.py:
make_detections.py:
working_folder: ./output/output_prd
log_subfolder: logs
sample_tagged_img_subfolder: sample_tagged_images
Expand All @@ -52,13 +52,13 @@ make_predictions.py:
score_lower_threshold: 0.3

# 4-Filtering and merging detection polygons to improve results
filter_predictions.py:
filter_detections.py:
year: 2020
input: ./output/output_prd/oth_predictions_at_0dot3_threshold.gpkg
input: ./output/output_prd/oth_detections_at_0dot3_threshold.gpkg
labels_shapefile: ./data/AoI/AoI_2020.shp
dem: ./data/DEM/switzerland_dem_EPSG2056.tif
elevation: 1200.0 # m, altitude threshold
score: 0.95 # prediction score (from 0 to 1) provided by detectron2
score: 0.95 # detection score (from 0 to 1) provided by detectron2
distance: 10 # m, distance use as a buffer to merge close polygons (likely to belong to the same object) together
area: 5000.0 # m2, area threshold under which polygons are discarded
output: ./output/output_prd/oth_predictions_at_0dot3_threshold_year-{year}_score-{score}_area-{area}_elevation-{elevation}_distance-{distance}.geojson
output: ./output/output_prd/oth_detections_at_0dot3_threshold_year-{year}_score-{score}_area-{area}_elevation-{elevation}_distance-{distance}.geojson
14 changes: 7 additions & 7 deletions examples/quarry-detection/config_trne.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ train_model.py:
model_zoo_checkpoint_url: "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml"

# 4-Perform the object detection based on the optimized trained model
make_predictions.py:
make_detections.py:
working_folder: ./output/output_trne
log_subfolder: logs
sample_tagged_img_subfolder: sample_tagged_images
Expand All @@ -67,14 +67,14 @@ make_predictions.py:
epsilon: 2.0 # cf. https://rdp.readthedocs.io/en/latest/
score_lower_threshold: 0.05

# 5-Evaluate the quality of the prediction for the different datasets with metrics calculation
assess_predictions.py:
# 5-Evaluate the quality of the detections for the different datasets with metrics calculation
assess_detections.py:
datasets:
ground_truth_labels_geojson: ./output/output_trne/labels.geojson
image_metadata_json: ./output/output_trne/img_metadata.json
split_aoi_tiles_geojson: ./output/output_trne/split_aoi_tiles.geojson # aoi = Area of Interest
predictions:
trn: ./output/output_trne/trn_predictions_at_0dot05_threshold.gpkg
val: ./output/output_trne/val_predictions_at_0dot05_threshold.gpkg
tst: ./output/output_trne/tst_predictions_at_0dot05_threshold.gpkg
detections:
trn: ./output/output_trne/trn_detections_at_0dot05_threshold.gpkg
val: ./output/output_trne/val_detections_at_0dot05_threshold.gpkg
tst: ./output/output_trne/tst_detections_at_0dot05_threshold.gpkg
output_folder: ./output/output_trne
5 changes: 3 additions & 2 deletions examples/swimming-pool-detection/GE/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ nobody@<id>:/app# cd output_GE && cat parcels.geojson | supermercado burn 18 | m
nobody@<id>:/app# python prepare_data.py config_GE.yaml
nobody@<id>:/app# stdl-objdet generate_tilesets config_GE.yaml
nobody@<id>:/app# stdl-objdet train_model config_GE.yaml
nobody@<id>:/app# stdl-objdet make_predictions config_GE.yaml
nobody@<id>:/app# stdl-objdet assess_predictions config_GE.yaml
nobody@<id>:/app# stdl-objdet make_detections config_GE.yaml
nobody@<id>:/app# stdl-objdet assess_detections config_GE.yaml
nobody@<id>:/app# exit
$ sudo chmod -R a+w examples
```

Expand Down
18 changes: 9 additions & 9 deletions examples/swimming-pool-detection/GE/config_GE.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ generate_tilesets.py:
output_folder: output_GE
tile_size: 256 # per side, in pixels
overwrite: False
n_jobs: 1
n_jobs: 10
COCO_metadata:
year: 2020
version: 1.0
Expand All @@ -45,10 +45,10 @@ train_model.py:
model_weights:
model_zoo_checkpoint_url: "COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml"

make_predictions.py:
make_detections.py:
working_folder: output_GE
log_subfolder: logs
sample_tagged_img_subfolder: sample_prediction_images
sample_tagged_img_subfolder: sample_detection_images
COCO_files: # relative paths, w/ respect to the working_folder
trn: COCO_trn.json
val: COCO_val.json
Expand All @@ -63,15 +63,15 @@ make_predictions.py:
epsilon: 0.5 # cf. https://rdp.readthedocs.io/en/latest/
score_lower_threshold: 0.05

assess_predictions.py:
assess_detections.py:
datasets:
ground_truth_labels_geojson: output_GE/ground_truth_labels.geojson
other_labels_geojson: output_GE/other_labels.geojson
image_metadata_json: output_GE/img_metadata.json
split_aoi_tiles_geojson: output_GE/split_aoi_tiles.geojson # aoi = Area of Interest
predictions:
trn: output_GE/trn_predictions_at_0dot05_threshold.gpkg
val: output_GE/val_predictions_at_0dot05_threshold.gpkg
tst: output_GE/tst_predictions_at_0dot05_threshold.gpkg
oth: output_GE/oth_predictions_at_0dot05_threshold.gpkg
detections:
trn: output_GE/trn_detections_at_0dot05_threshold.gpkg
val: output_GE/val_detections_at_0dot05_threshold.gpkg
tst: output_GE/tst_detections_at_0dot05_threshold.gpkg
oth: output_GE/oth_detections_at_0dot05_threshold.gpkg
output_folder: output_GE
5 changes: 3 additions & 2 deletions examples/swimming-pool-detection/NE/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ nobody@<id>:/app# cd output_NE && cat parcels.geojson | supermercado burn 18 | m
nobody@<id>:/app# python prepare_data.py config_NE.yaml
nobody@<id>:/app# stdl-objdet generate_tilesets config_NE.yaml
nobody@<id>:/app# stdl-objdet train_model config_NE.yaml
nobody@<id>:/app# stdl-objdet make_predictions config_NE.yaml
nobody@<id>:/app# stdl-objdet assess_predictions config_NE.yaml
nobody@<id>:/app# stdl-objdet make_detections config_NE.yaml
nobody@<id>:/app# stdl-objdet assess_detections config_NE.yaml
nobody@<id>:/app# exit
$ sudo chmod -R a+w examples
```

Expand Down
Loading
Loading