Skip to content

Commit

Permalink
Merge pull request #159 from PUTvision/devel
Browse files Browse the repository at this point in the history
devel -> master
  • Loading branch information
bartoszptak authored Mar 22, 2024
2 parents b397127 + 379407d commit 45d2b74
Show file tree
Hide file tree
Showing 66 changed files with 1,612 additions and 592 deletions.
13 changes: 5 additions & 8 deletions .github/workflows/python-app-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,14 @@ jobs:
export PYTHONPATH="/usr/lib/python3/dist-packages":PYTHONPATH && echo "import qgis" | python3
export PYTHONPATH="$PYTHONPATH:$(pwd)/src"
export PYTHONPATH="$PYTHONPATH:$(pwd)"
# apparently there is some issue with opencv-python-headless, we need to reinstall it
# apparently there is some issue with opencv-python-headless, we need to reinstall it
pip uninstall opencv-python-headless --yes
pip install --upgrade -r ./src/deepness/python_requirements/requirements.txt
# run one this without pytest, because pytest creates obfuscated error messages
# we need 'xvfb-run' to simulate UI - otherwise qgis crushes
xvfb-run python3 test/test_map_processor_segmentation.py
# run the actual tests
xvfb-run python3 -m pytest --cov=src/deepness/ --cov-report html test/
xvfb-run -e /dev/stdout python3 -m pytest --cov=src/deepness/ --cov-report html test/
- name: 'Upload Artifact - test coverage'
uses: actions/upload-artifact@v3
with:
Expand Down
74 changes: 45 additions & 29 deletions docs/source/creators/creators_add_metadata_to_model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,51 @@ The plugin allows you to load the meta parameters of the onnx model automaticall
List of parameters parsed by plugin
===================================

+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| Parameter | Type | Example | Description |
+======================+=======+=======================================+=============================================================+
| model_type | str | :code:`'Segmentor'` | Types of models available: Segmentor, Regressor, Detector. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| class_names | dict | :code:`{0: 'background', 1: 'field'}` | A dictionary that maps a class id to its name. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| resolution | float | :code:`100` | Real-world resolution of images (centimeters per pixel). |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| tiles_size | int | :code:`512` | What size (in pixels) is the tile to crop. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| tiles_overlap | int | :code:`40` | How many percent of the image size overlap. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| standardization_mean | list | :code:`[0.0, 0.0, 0.0]` | Mean - if you want to standarize input after normalisation |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| standardization_std | list | :code:`[1.0, 1.0, 1.0]` | Std - if you want to standarize input after normalisation |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| seg_thresh | float | :code:`0.5` | Segmentor: class confidence threshold. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| seg_small_segment | int | :code:`7` | Segmentor: remove small occurrences of the class. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| reg_output_scaling | float | :code:`1.0` | Regressor: scaling factor for the model output. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| det_conf | float | :code:`0.6` | Detector: object confidence threshold. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| det_iou_thresh | float | :code:`0.4` | Detector: IOU threshold for NMS. |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
| det_type | str | :code:`YOLO_v5_or_v7_default` | Detector: type of the detector model format |
+----------------------+-------+---------------------------------------+-------------------------------------------------------------+
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| Parameter | Type | Example | Description |
+======================+=======+=======================================+====================================================================+
| model_type | str | :code:`'Segmentor'` | Types of models. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| class_names | dict | :code:`{0: 'name1', 1: 'name2'}` | A dictionary that maps a class id to its name. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| class_names (mutli outputs) | list | :code:`[{0: 'name1'}, {0: 'name2'}]` | A dictionary that maps a class id to its name. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| resolution | float | :code:`100` | Real-world resolution of images (centimeters per pixel). |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| tiles_size | int | :code:`512` | What size (in pixels) is the tile to crop. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| tiles_overlap | int | :code:`40` | How many percent of the image size overlap. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| standardization_mean | list | :code:`[0.0, 0.0, 0.0]` | Mean - if you want to standarize input after normalisation |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| standardization_std | list | :code:`[1.0, 1.0, 1.0]` | Std - if you want to standarize input after normalisation |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| seg_thresh | float | :code:`0.5` | Segmentor: class confidence threshold. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| seg_small_segment | int | :code:`7` | Segmentor: remove small occurrences of the class. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| reg_output_scaling | float | :code:`1.0` | Regressor: scaling factor for the model output. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| det_conf | float | :code:`0.6` | Detector: object confidence threshold. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| det_iou_thresh | float | :code:`0.4` | Detector: IOU threshold for NMS. |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+
| det_type | str | :code:`YOLO_v5_or_v7_default` | Detector: type of the detector model format |
+-----------------------------+-------+---------------------------------------+-------------------------------------------------------------+

Available model types:
- :code:`Segmentor`
- :code:`Detector`
- :code:`Regressor`
- :code:`Recognition`
- :code:`Superresolution`

Availeble detector types:
- :code:`YOLO_v5_or_v7_default`
- :code:`YOLO_v6`
- :code:`YOLO_v9`
- :code:`YOLO_Ultralytics`
- :code:`YOLO_Ultralytics_segmentation`

=======
Example
Expand Down
17 changes: 13 additions & 4 deletions docs/source/creators/creators_description_classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,18 @@ Segmentation models allow to solve problem of Image segmentation, that is assign
Example application is segmenting earth surface areas into the following categories: forest, road, buildings, water, other.

The segmentation model output is also an image, with same dimension as the input tile, but instead of 'CHANNELS' dimension, each output class has a separate image.
Therefore, the shape of model output is :code:`[BATCH_SIZE, NUM_CLASSES, SIZE_PX, SIZE_PX)`.
Therefore, the shape of model output is :code:`[BATCH_SIZE, NUM_CLASSES, SIZE_PX, SIZE_PX]`.

For each output class, a separate vector layer can be created.
We support the following types of models:
* single output (one head) with the following output shapes:
* :code:`[BATCH_SIZE, 1, SIZE_PX, SIZE_PX]` - one class with sigmoid activation function (binary classification)
* :code:`[BATCH_SIZE, NUM_CLASSES, SIZE_PX, SIZE_PX]` - multiple classes with softmax activation function (multi-class classification) - outputs sum to 1.0
* multiple outputs (multiple heads) with each output head composed of the same shapes as single output.

Metaparameter :code:`class_names` saved in the model file should be as follows in this example:
* for single output with binary classification (sigmoid): :code:`[{0: "background", 1: "class_name"}]`
* for single output with multi-class classification (softmax): :code:`[{0: "class0", 1: "class1", 2: "class2"}]` or :code:`{0: "class0", 1: "class1", 2: "class2"}`
* for multiple outputs (multiple heads): :code:`[{0: "class0", 1: "class1", 2: "class2"}, {0: "background", 1: "class_name"}]`

Output report contains information about percentage coverage of each class.

Expand All @@ -43,7 +52,7 @@ Detection models allow to solve problem of objects detection, that is finding an
Example application is detection of oil and water tanks on satellite images.

The detection model output is list of bounding boxes, with assigned class and confidence value. This information is not really standardized between different model architectures.
Currently plugin supports :code:`YOLOv5`, :code:`YOLOv7` and :code:`ULTRALYTICS` output types. Detection model also supports the instance segmentation output type from :code:`ULTRALYTICS`.
Currently plugin supports :code:`YOLOv5`, :code:`YOLOv6`, :code:`YOLOv7`, :code:`YOLOv9` and :code:`ULTRALYTICS` output types. Detection model also supports the instance segmentation output type from :code:`ULTRALYTICS`.

For each object class, a separate vector layer can be created, with information saved as rectangle polygons (so the output can be potentially easily exported to a text).

Expand All @@ -57,7 +66,7 @@ Regression models allow to solve problem of Regression Analysis, that is assigni
Example application is determining the moisture content in soil, as percentage from 0.0 to 100.0 %, with an individual value assigned to each pixel.

The segmentation model output is also an image, with same dimension as the input tile, with one or many output maps. Each output map contains the values for pixels.
Therefore, the shape of model output is :code:`[BATCH_SIZE, NUMBER_OF_OUTPUT_MAPS, SIZE_PX, SIZE_PX)`.
Therefore, the shape of model output is :code:`[BATCH_SIZE, NUMBER_OF_OUTPUT_MAPS, SIZE_PX, SIZE_PX]`.

One output layer will be created for each output map (channel).
For each output, a raster layer will be created, where each pixel has individual value assigned.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/creators/creators_tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Model creation tutorial (Python)
Detection
=========

For one of models in our zoo - specifically for cars detection on aerial images - a complete tutorial is provided in a jupyter notebook:
For one of models in our zoo - specifically for cars detection on aerial images - a complete tutorial is `provided in a jupyter notebook <https://github.com/PUTvision/qgis-plugin-deepness/blob/master/tutorials/detection/cars_yolov7/car_detection__prepare_and_train.ipynb>'_:

.. code-block::

Expand Down
2 changes: 1 addition & 1 deletion docs/source/example/example_detection_cars_yolov7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The example is based on the `ITCVD cars detection dataset <https://arxiv.org/pdf
Training tutorial
=========================

The entire training process has been gathered in a tutorial notebook in jupyter notebook:
The entire training process has been gathered in `a tutorial notebook in jupyter notebook <https://github.com/PUTvision/qgis-plugin-deepness/blob/master/tutorials/detection/cars_yolov7/car_detection__prepare_and_train.ipynb>'_:


.. code-block::
Expand Down
2 changes: 0 additions & 2 deletions docs/source/main/main_ui_explanation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ These options may be a fixed value for some models.

**IoU threshold** - Parameter used in Non-Maximum Suppression in post-processing. Defines the threshold of overlap between neighboring detections, to consider them as the same object.

**Remove overlapping detections** - If checked then the overlapping detections (which may be an artifact of overlapped processing) will be removed.

------------
Tiles export
------------
Expand Down
1 change: 1 addition & 0 deletions docs/source/main/model_zoo/MODEL_ZOO.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The [Model ZOO](https://chmura.put.poznan.pl/s/2pJk4izRurzQwu3) is a collection
| [Airbus Oil Storage Detection](https://chmura.put.poznan.pl/s/gMundpKsYUC7sNb) | 512 | 150 | YOLOv5-m model for object detection on satellite images. Based on the [Airbus Oil Storage Detection dataset](https://www.kaggle.com/datasets/airbusgeo/airbus-oil-storage-detection-dataset). | [Image](https://chmura.put.poznan.pl/s/T3pwaKlbFDBB2C3) |
| [Aerial Cars Detection](https://chmura.put.poznan.pl/s/vgOeUN4H4tGsrGm) | 640 | 10 | YOLOv7-m model for cars detection on aerial images. Based on the [ITCVD](https://arxiv.org/pdf/1801.07339.pdf). | [Image](https://chmura.put.poznan.pl/s/cPzw1mkXlprSUIJ) |
| [UAVVaste Instance Segmentation](https://chmura.put.poznan.pl/s/v99rDlSPbyNpOCH) | 640 | 0.5 | YOLOv8-L Instance Segmentation model for litter detection on high-quality UAV images. Based on the [UAVVaste dataset](https://github.com/PUTvision/UAVVaste). | [Image](https://chmura.put.poznan.pl/s/KFQTlS2qtVnaG0q) |
| [Tree-Tops Detection](https://chmura.put.poznan.pl/s/A9zdp4mKAATEAGu) | 640 | 10 | YOLOv9 model for treetops detection on aerial images. Model is trained on the mix of publicly available datasets. | [Image](https://chmura.put.poznan.pl/s/F0lkIX9xhcwD4PG) |

## Super Resolution Models
| Model | Input size | CM/PX | Scale Factor | Description | Example image |
Expand Down
3 changes: 0 additions & 3 deletions src/deepness/common/config_entry_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ class ConfigEntryKey(enum.Enum):
DATA_EXPORT_SEGMENTATION_MASK_ENABLED = enum.auto(), False
DATA_EXPORT_SEGMENTATION_MASK_ID = enum.auto(), ''

MODEL_OUTPUT_FORMAT = enum.auto(), '' # string of ModelOutputFormat, e.g. "ONLY_SINGLE_CLASS_AS_LAYER.value"
MODEL_OUTPUT_FORMAT_CLASS_NUMBER = enum.auto(), 0

INPUT_CHANNELS_MAPPING__ADVANCED_MODE = enum.auto, False
INPUT_CHANNELS_MAPPING__MAPPING_LIST_STR = enum.auto, []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class DetectorType(enum.Enum):

YOLO_v5_v7_DEFAULT = 'YOLO_v5_or_v7_default'
YOLO_v6 = 'YOLO_v6'
YOLO_v9 = 'YOLO_v9'
YOLO_ULTRALYTICS = 'YOLO_Ultralytics'
YOLO_ULTRALYTICS_SEGMENTATION = 'YOLO_Ultralytics_segmentation'

Expand All @@ -30,6 +31,11 @@ def get_parameters(self):
return DetectorTypeParameters(
ignore_objectness_probability=True,
)
elif self == DetectorType.YOLO_v9:
return DetectorTypeParameters(
has_inverted_output_shape=True,
skipped_objectness_probability=True,
)
elif self == DetectorType.YOLO_ULTRALYTICS or self == DetectorType.YOLO_ULTRALYTICS_SEGMENTATION:
return DetectorTypeParameters(
has_inverted_output_shape=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ class ProcessedAreaType(enum.Enum):
def get_all_names(cls):
return [e.value for e in cls]


class ModelOutputFormat(enum.Enum):
ALL_CLASSES_AS_SEPARATE_LAYERS = 'All classes as separate layers'
CLASSES_AS_SEPARATE_LAYERS_WITHOUT_ZERO_CLASS = 'Classes as separate layers (without 0 class)'
ONLY_SINGLE_CLASS_AS_LAYER = 'Single class as a vector layer'
RECOGNITION_RESULT = 'Cosine distance between query image and map'

@classmethod
def get_all_names(cls):
return [e.value for e in cls]


@dataclass
class MapProcessingParameters:
"""
Expand All @@ -48,9 +36,6 @@ class MapProcessingParameters:

input_channels_mapping: ChannelsMapping # describes mapping of image channels to model inputs

model_output_format: ModelOutputFormat # what kind of model output do we want to achieve
model_output_format__single_class_number: int # if we want to show just one output channel - here is its number

@property
def tile_size_m(self):
return self.tile_size_px * self.resolution_cm_per_px / 100
Expand Down
Loading

0 comments on commit 45d2b74

Please sign in to comment.