Skip to content

Commit

Permalink
Merge pull request #88 from hugobaudchon/v0.1.4-draft
Browse files Browse the repository at this point in the history
v0.1.4
  • Loading branch information
hugobaudchon authored Oct 4, 2024
2 parents 389f3c8 + 97d2cb2 commit a902e57
Show file tree
Hide file tree
Showing 6 changed files with 505 additions and 545 deletions.
23 changes: 23 additions & 0 deletions docs/source/_static/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,26 @@ a:active {
color: #388E3C; /* Darker green for active state */
}

h1 {
font-size: 2.5em;
}

h2 {
font-size: 2.0em;
}

h3 {
font-size: 1.75em;
}

h4 {
font-size: 1.5em;
}

h5 {
font-size: 1.25em;
}

h6 {
font-size: 1.1em;
}
9 changes: 1 addition & 8 deletions docs/source/aggregator.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
Aggregator
==========

.. autoclass:: geodataset.aggregator.DetectorAggregator
:members:
:undoc-members:
:show-inheritance:
:inherited-members:


.. autoclass:: geodataset.aggregator.SegmentationAggregator
.. autoclass:: geodataset.aggregator.Aggregator
:members:
:undoc-members:
:show-inheritance:
Expand Down
99 changes: 83 additions & 16 deletions docs/source/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Examples
========

Area of Interest
""""""""""""""""
~~~~~~~~~~~~~~~~

In order to provide more flexibility when tilerizing a raster, geodataset supports areas of interest (AOI).
2 types of AOIs configs are supported: AOIGeneratorConfig and AOIFromPackageConfig.
Expand All @@ -28,14 +28,14 @@ If no AOI config is passed to the Tilerizer, all the tiles will be kept in a sin
# AOIs are provided as polygons in geopackages (.gpkg, .geojson or .shp)
aoi_gpkg_config = AOIFromPackageConfig(
aois={'train': Path('QGIS_projects/train_aoi.shp'),
'valid': Path('QGIS_projects/valid_aoi.shp'),
'test': Path('Data/raw/quebec_trees_dataset_2021-09-02/inference_zone.gpkg')
aois={'train': 'QGIS_projects/train_aoi.gpkg',
'valid': 'QGIS_projects/valid_aoi.shp',
'test': 'Data/raw/quebec_trees_dataset_2021-09-02/inference_zone.gpkg'
}
)
Unlabeled Raster
""""""""""""""""
~~~~~~~~~~~~~~~~

The class RasterTilerizer can tilerize a raster, without labels. The tiles are then stored in the output_path/tiles.

Expand All @@ -45,8 +45,8 @@ The class RasterTilerizer can tilerize a raster, without labels. The tiles are t
from geodataset.tilerize import RasterTilerizer
tilerizer = RasterTilerizer(
raster_path=Path('/Data/raw/wwf_ecuador/RGB Orthomosaics/Carlos Vera Arteaga RGB.tif'),
output_path=Path('/Data/pre_processed/test'),
raster_path='/Data/raw/wwf_ecuador/RGB Orthomosaics/Carlos Vera Arteaga RGB.tif',
output_path='/Data/pre_processed/test',
tile_size=1024,
tile_overlap=0.5,
aois_config=aoi_gen_config,
Expand All @@ -65,7 +65,7 @@ The class RasterTilerizerGDF can tilerize a raster, without labels, and return t
from geodataset.tilerize import RasterTilerizerGDF
tilerizer = RasterTilerizerGDF(
raster_path=Path('/Data/raw/wwf_ecuador/RGB Orthomosaics/Carlos Vera Arteaga RGB.tif'),
raster_path='/Data/raw/wwf_ecuador/RGB Orthomosaics/Carlos Vera Arteaga RGB.tif',
tile_size=1024,
tile_overlap=0.5,
aois_config=aoi_gen_config,
Expand All @@ -77,7 +77,7 @@ The class RasterTilerizerGDF can tilerize a raster, without labels, and return t
tiles_boxes_gdf = tilerizer.generate_tiles_gdf()
Labeled Raster
""""""""""""""
~~~~~~~~~~~~~~

The class LabeledRasterTilerizer can tilerize a raster and its labels (.gpkg, .geojson, .shp, .csv and .xml).

Expand All @@ -87,9 +87,9 @@ The class LabeledRasterTilerizer can tilerize a raster and its labels (.gpkg, .g
from geodataset.tilerize import LabeledRasterTilerizer
tilerizer = LabeledRasterTilerizer(
raster_path=Path('Data/raw/quebec_trees_dataset_2021-09-02/2021-09-02/zone1/2021-09-02-sbl-z1-rgb-cog.tif'),
labels_path=Path('Data/raw/quebec_trees_dataset_2021-09-02/Z1_polygons.gpkg'),
output_path=Path('Data/pre_processed/test'),
raster_path='Data/raw/quebec_trees_dataset_2021-09-02/2021-09-02/zone1/2021-09-02-sbl-z1-rgb-cog.tif',
labels_path='Data/raw/quebec_trees_dataset_2021-09-02/Z1_polygons.gpkg',
output_path='Data/pre_processed/test',
tile_size=1024,
tile_overlap=0.5,
aois_config=aoi_gpkg_config,
Expand All @@ -106,7 +106,7 @@ The class LabeledRasterTilerizer can tilerize a raster and its labels (.gpkg, .g
tilerizer.generate_coco_dataset()
Dataset
"""""""
~~~~~~~

Geodataset provides the DetectionLabeledRasterCocoDataset and SegmentationLabeledRasterCocoDataset classes which given a single or a list of root folder(s), will recursively go into each subdirectory and parse the COCO json files matching a specific 'fold',
and the associated images paths.
Expand Down Expand Up @@ -136,21 +136,88 @@ You can also provide an albumentation transform (optional) to the dataset classe
# Labeled Detection Dataset
detection_train_ds = DetectionLabeledRasterCocoDataset(
root_path=Path('Data/pre_processed/all_datasets'),
root_path=['Data/pre_processed/subset_1',
'Data/pre_processed/subset_2'],
fold="train",
transform=augment_transform
)
# Labeled Segmentation Dataset
segmentation_valid_ds = SegmentationLabeledRasterCocoDataset(
root_path=Path('Data/pre_processed/all_datasets'),
root_path='Data/pre_processed/all_datasets',
fold="valid",
transform=None
)
# Unlabeled Dataset (useful for inference or unsupervised pre-training)
unlabeled_infer_ds = UnlabeledRasterDataset(
root_path=Path('Data/pre_processed/inference_data'),
root_path='Data/pre_processed/inference_data',
fold="infer", # assuming the tiles were tilerized using an aoi 'infer' instead of 'train', 'valid'...
transform=None
)
Aggregator
~~~~~~~~~~

The Aggregator class can be used to apply Non-Maximum Suppression style algorithms to aggregate bounding box or instance
segmentation predictions from a model from multiple tiles/images, and then save the results in a COCO json file.

For aggregating detection bounding boxes, you should currently use the nms_algorithm='iou' option.
For aggregating instance segmentation polygons, you can use both 'iou' and 'ioa-disambiguate', depending on what you need.


.. code-block:: python
from shapely.geometry import box, Polygon
from geodataset.aggregator import Aggregator
# aggregating detection bounding boxes from a coco file on the disk:
aggregator = Aggregator.from_coco(
output_path='your_output_path',
tiles_folder_path='path_to_folder_containing_tiles',
coco_json_path='path_to_coco_json_file',
polygons=[[box(0, 0, 1, 1), box(1, 1, 2, 2)],
[box(0, 0, 1, 1), box(1, 1, 2, 2)]],
scores_names=['detection_score'],
classes_names=['detection_class'],
score_threshold=0.3,
nms_threshold=0.8,
nms_algorithm='iou'
)
# aggregating detection bounding boxes from in-memory polygons:
aggregator = Aggregator.from_polygons(
output_path='your_output_path',
tiles_paths=['tile_1_path', 'tile_2_path'],
polygons=[[box(0, 0, 1, 1), box(1, 1, 2, 2)],
[box(0, 0, 1, 1), box(1, 1, 2, 2)]],
scores=[[0.9, 0.8],
[0.7, 0.85]],
classes=[[1, 2],
[2, 1]],
score_threshold=0.3,
nms_threshold=0.8,
nms_algorithm='iou'
)
# aggregating instance segmentation polygons from in-memory polygons, with 2 different sets of scores
# (you can also only use 1 set of scores if you want):
aggregator = Aggregator.from_polygons(
output_path='your_output_path',
tiles_paths=['tile_1_path', 'tile_2_path'],
polygons=[[Polygon([(0, 0), (1, 0), (0, 1)]), Polygon([(1, 1), (2, 1), (1, 2)])],
[Polygon([(2, 2), (3, 2), (2, 3)]), Polygon([(3, 3), (4, 3), (3, 4)])]],
scores={'detection_score': [[0.9, 0.8],
[0.7, 0.85]],
'segmentation_score': [[0.6, 0.5],
[0.9, 0.3]]},
classes=[[1, 2],
[2, 1]],
scores_weights={'detection_score': 2,
'segmentation_score': 1},
score_threshold=0.3,
nms_threshold=0.8,
nms_algorithm='ioa-disambiguate',
best_geom_keep_area_ratio=0.5
)
2 changes: 1 addition & 1 deletion geodataset/aggregator/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .aggregator import DetectorAggregator, SegmentationAggregator
from .aggregator import Aggregator, DetectorAggregator, SegmentationAggregator
Loading

0 comments on commit a902e57

Please sign in to comment.