oriented-det 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {oriented_det-0.1.0 → oriented_det-0.2.0}/PKG-INFO +27 -17
- {oriented_det-0.1.0 → oriented_det-0.2.0}/README.md +21 -14
- oriented_det-0.2.0/export/contract.json +73 -0
- oriented_det-0.2.0/export/ort_runtime.py +144 -0
- oriented_det-0.2.0/export/postprocess.py +228 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/build_faster_rcnn_savedmodel.py +40 -10
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/export_onnx.py +55 -12
- oriented_det-0.2.0/export/scripts/export_tf.py +187 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/predict_savedmodel.py +17 -12
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/save_predictions_tf.py +14 -4
- oriented_det-0.2.0/export/tests/test_export_cli.py +201 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/tests/test_export_wrappers.py +63 -3
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/tests/test_faster_rcnn_export_parity.py +13 -9
- oriented_det-0.2.0/export/tests/test_keras_detect_bundle.py +130 -0
- oriented_det-0.2.0/export/tests/test_oriented_rcnn_export_parity.py +312 -0
- oriented_det-0.2.0/export/tests/test_ort_runtime.py +101 -0
- oriented_det-0.2.0/export/tests/test_postprocess.py +50 -0
- oriented_det-0.2.0/export/tests/test_rotated_fcos_export_parity.py +220 -0
- oriented_det-0.2.0/export/tf_serving_model.py +176 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/wrappers.py +102 -7
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/__init__.py +5 -1
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/cli/__init__.py +19 -23
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/models/rotated_faster_rcnn_r50.json +1 -0
- oriented_det-0.2.0/oriented_det/configs/_base_/models/rotated_fcos_r50.json +35 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/config.schema.json +57 -3
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/oriented_rcnn/dota_le90_1x.json +1 -1
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_faster_rcnn/dota_le90_1x.json +6 -4
- oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_1x.json +107 -0
- oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_1x_kfiou_aux.json +10 -0
- oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_1x_riou.json +11 -0
- oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_3x.json +27 -0
- oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_3x_kfiou_aux.json +15 -0
- oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_3x_riou.json +15 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_retinanet/dota_le90_1x.json +2 -2
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/__init__.py +12 -2
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/airbus_playground.py +8 -1
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/evaluation.py +284 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/__init__.py +9 -1
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/backbones/resnet_fpn.py +8 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/bbox_coder.py +127 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/faster_rcnn_inference.py +48 -37
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/horizontal_roi_coder.py +47 -7
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/oriented_rcnn.py +30 -5
- oriented_det-0.2.0/oriented_det/models/oriented_rcnn_inference.py +242 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/oriented_roi.py +270 -98
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/oriented_rpn.py +20 -4
- oriented_det-0.2.0/oriented_det/models/rotated_fcos.py +1086 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/rotated_retinanet.py +293 -148
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/utils.py +33 -9
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/__init__.py +5 -0
- oriented_det-0.2.0/oriented_det/ops/diff_iou_rotated.py +196 -0
- oriented_det-0.2.0/oriented_det/ops/gaussian_angle.py +60 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/pretrained/__init__.py +4 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/pretrained/hub.py +39 -0
- oriented_det-0.2.0/oriented_det/pretrained/manifest.json +78 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/checkpoint.py +183 -18
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/config.py +43 -1
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/engine.py +28 -2
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/utils.py +68 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/PKG-INFO +27 -17
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/SOURCES.txt +29 -1
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/requires.txt +5 -1
- {oriented_det-0.1.0 → oriented_det-0.2.0}/pyproject.toml +11 -5
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_airbus_playground.py +31 -0
- oriented_det-0.2.0/tests/test_annotation_csv.py +87 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_bbox_coder.py +42 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_config_behavior.py +1 -14
- oriented_det-0.2.0/tests/test_config_model_wiring.py +477 -0
- oriented_det-0.2.0/tests/test_diff_iou_rotated.py +103 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_evaluation.py +30 -0
- oriented_det-0.2.0/tests/test_gaussian_angle.py +66 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_models.py +558 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_pretrained_hub.py +56 -6
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_roi.py +263 -6
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_rpn.py +38 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_score_thresholds.py +4 -0
- oriented_det-0.2.0/tests/test_source_provenance.py +28 -0
- oriented_det-0.2.0/tests/test_viewer_gradio_compat.py +9 -0
- oriented_det-0.2.0/tools/annotation_csv.py +167 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/app.py +110 -15
- oriented_det-0.2.0/tools/compare_hbb_obb_counts.py +63 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/dataset_stats.py +3 -0
- oriented_det-0.2.0/tools/filter_predictions_by_gt.py +58 -0
- oriented_det-0.2.0/tools/generate_oriented_annotations.py +96 -0
- oriented_det-0.2.0/tools/hbb_to_obb.py +563 -0
- oriented_det-0.2.0/tools/image_demo.py +614 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/lr_finder.py +12 -3
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/preview_augmentation.py +5 -2
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/save_predictions.py +83 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/train.py +196 -51
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/train_multi_gpu.py +3 -3
- oriented_det-0.2.0/tools/viewer_annotations.py +681 -0
- oriented_det-0.1.0/export/ort_runtime.py +0 -67
- oriented_det-0.1.0/export/postprocess.py +0 -151
- oriented_det-0.1.0/export/tests/test_ort_runtime.py +0 -41
- oriented_det-0.1.0/export/tf_serving_model.py +0 -96
- oriented_det-0.1.0/oriented_det/pretrained/manifest.json +0 -46
- oriented_det-0.1.0/tests/test_config_model_wiring.py +0 -195
- oriented_det-0.1.0/tools/image_demo.py +0 -200
- oriented_det-0.1.0/tools/visualize_boxes.py +0 -183
- {oriented_det-0.1.0 → oriented_det-0.2.0}/LICENSE +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/onnx_to_savedmodel.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/to_tflite.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/tests/test_export_onnx_optional.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/export/val_dataset.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/cli/train.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/augmentation.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/datasets/dota_le90.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/fp16.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/models/oriented_rcnn_r50.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/models/rotated_retinanet_r50.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/preprocessing.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/schedules/1x.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/oriented_rcnn/dota_le90_3x.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_faster_rcnn/dota_le90_3x.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_retinanet/dota_le90_3x.json +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/dota.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/dota_classes.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/flips.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/preprocessing.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/tiling.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/transforms.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/poly.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/qbox.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/rbox.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/transforms.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/backbones/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/backbones/utils.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/gpu_ops.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/iou.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/kfiou.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/nms.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/probiou.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/rotated_ops.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/utils.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/collate.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/inference.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/grouped_ce.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/piecewise_schedule.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/profiler.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/config.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/device.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/logging.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/progress.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/viz.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/dependency_links.txt +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/entry_points.txt +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/top_level.txt +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/setup.cfg +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_cosine_tail_scheduler.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_deploy_generate_description.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_dota.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_dota_tile_roots.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_exact_rotated_iou.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_geometry.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_geometry_transforms.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_gpu_ops.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_grouped_ce.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_iou.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_kfiou.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_metrics_margin_filter.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_nms.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_ops_utils.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_optimizer_param_groups.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_piecewise_schedule.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_preprocessing.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_probiou.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_sliding_window_margin.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_tiling.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_train.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_train_flips.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_training_config_strict.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_transforms.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_utils_config.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_utils_viz.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_vendored_configs_sync.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/__init__.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/dota_labels_to_comma.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/free_gpu.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/generate_airbus_playground_csv.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/measure_sampled_riou_error.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/playground_to_dota.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/pretrained_download.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/publish_checkpoint.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/sync_vendored_configs.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/tile_dota.py +0 -0
- {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/train_example.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oriented-det
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A lightweight, modern PyTorch library for rotated object detection in aerial and satellite imagery
|
|
5
5
|
Author: Jeff Faudi, DL4EO
|
|
6
6
|
Maintainer: Jeff Faudi, DL4EO
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
Project-URL: Homepage, https://github.com/DL4EO/oriented-det
|
|
9
|
-
Project-URL: Documentation, https://github.
|
|
9
|
+
Project-URL: Documentation, https://dl4eo.github.io/oriented-det/
|
|
10
10
|
Project-URL: Repository, https://github.com/DL4EO/oriented-det
|
|
11
11
|
Project-URL: Issues, https://github.com/DL4EO/oriented-det/issues
|
|
12
12
|
Project-URL: Bug Tracker, https://github.com/DL4EO/oriented-det/issues
|
|
@@ -25,6 +25,7 @@ Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
|
25
25
|
Requires-Python: >=3.10
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
|
+
Requires-Dist: setuptools<82,>=65.0
|
|
28
29
|
Requires-Dist: torch>=2.3.0
|
|
29
30
|
Requires-Dist: torchvision>=0.18.0
|
|
30
31
|
Requires-Dist: numpy<2
|
|
@@ -35,9 +36,11 @@ Requires-Dist: tensorboard>=2.10
|
|
|
35
36
|
Requires-Dist: matplotlib>=3.5.0
|
|
36
37
|
Requires-Dist: huggingface_hub>=0.20.0
|
|
37
38
|
Requires-Dist: shapely>=2.0.0
|
|
39
|
+
Provides-Extra: viewer
|
|
40
|
+
Requires-Dist: gradio==6.8.0; extra == "viewer"
|
|
38
41
|
Provides-Extra: export
|
|
39
42
|
Requires-Dist: onnx>=1.14.0; extra == "export"
|
|
40
|
-
Requires-Dist: onnxruntime>=1.16.0; extra == "export"
|
|
43
|
+
Requires-Dist: onnxruntime-gpu[cuda,cudnn]>=1.16.0; extra == "export"
|
|
41
44
|
Requires-Dist: onnx2tf>=1.22.0; extra == "export"
|
|
42
45
|
Requires-Dist: tensorflow>=2.14.0; extra == "export"
|
|
43
46
|
Provides-Extra: dev
|
|
@@ -65,7 +68,7 @@ Dynamic: license-file
|
|
|
65
68
|
- **Geometry**: Rotated bounding boxes (rbox: cx, cy, w, h, angle), quadrilateral boxes (qbox), polygon ↔ rbox ↔ hbox conversions, angle normalization (le90, 0–180°), flip/rotate/scale transforms, visualization helpers
|
|
66
69
|
- **IoU & NMS**: Rotated IoU and oriented NMS (CPU with optional GPU kernels when available); AABB pre-filtering; `obb_to_xyxy` / HBB conversion
|
|
67
70
|
- **Datasets**: DOTA polygon loader (pattern, split file, or separate folders), image tiling, label filtering, ignore masks, oriented mAP evaluation
|
|
68
|
-
- **Models**: **Oriented R-CNN** (horizontal RPN + MidpointOffset → oriented ROI), **Rotated Faster R-CNN** (
|
|
71
|
+
- **Models**: **Oriented R-CNN** ([Xie et al., ICCV 2021](https://openaccess.thecvf.com/content/ICCV2021/html/Xie_Oriented_R-CNN_for_Object_Detection_ICCV_2021_paper.html); horizontal RPN + MidpointOffset → oriented RoIAlign + oriented ROI head), **Rotated Faster R-CNN** (Ren et al., NeurIPS 2015 two-stage baseline with horizontal RPN + horizontal RoIAlign + rotated ROI head; MMRotate reference), **Rotated RetinaNet** ([Lin et al., ICCV 2017](https://openaccess.thecvf.com/content_ICCV_2017/papers/Lin_Focal_Loss_for_ICCV_2017_paper.pdf); oriented anchors, sigmoid focal loss), **Rotated FCOS** (anchor-free single-stage; distance-angle coder, centerness, L1 / KFIoU / decoded rIoU); ResNet + FPN backbones; selective loading of external checkpoints where configs wire `checkpoint.load_from_checkpoint`
|
|
69
72
|
- **Training**: JSON configs + **`odet train`**, mixed precision (AMP), gradient accumulation, checkpointing, best-metric tracking, TensorBoard, optional curriculum learning and profiling
|
|
70
73
|
|
|
71
74
|
## Installation
|
|
@@ -90,8 +93,10 @@ uv pip install -r requirements.txt
|
|
|
90
93
|
uv pip install -e .
|
|
91
94
|
```
|
|
92
95
|
|
|
93
|
-
-
|
|
96
|
+
- To auto-activate `.venv` when entering this repo, install the [`direnv`](https://direnv.net/) shell hook and run `direnv allow` from the repo root. The local `.envrc` is intentionally gitignored so each developer can opt in on their machine.
|
|
97
|
+
- From PyPI: `pip install oriented-det`
|
|
94
98
|
- For development and tests: `uv pip install -e ".[dev]"`
|
|
99
|
+
- For the Gradio prediction viewer: `uv pip install -e ".[viewer]"` or `pip install "oriented-det[viewer]"`
|
|
95
100
|
- For **macOS Apple Silicon** or **CPU-only**, see [Installation](docs/getting-started/installation.md).
|
|
96
101
|
- Verify: `pytest tests/test_geometry.py tests/test_iou.py tests/test_nms.py`
|
|
97
102
|
|
|
@@ -101,13 +106,13 @@ After [installation](#installation):
|
|
|
101
106
|
|
|
102
107
|
```bash
|
|
103
108
|
# Train on DOTA tiles (edit dataset paths in the config first)
|
|
104
|
-
odet train --config configs/
|
|
109
|
+
odet train --config configs/oriented_rcnn/dota_le90_1x.json
|
|
105
110
|
|
|
106
111
|
# Or use the Makefile wrapper (same default config)
|
|
107
112
|
make train
|
|
108
113
|
```
|
|
109
114
|
|
|
110
|
-
Default
|
|
115
|
+
Default starter recipe: `configs/oriented_rcnn/dota_le90_1x.json` (see [configs/oriented_rcnn/README.md](configs/oriented_rcnn/README.md)). Use `configs/oriented_rcnn/dota_le90_3x.json` when you want the longer Oriented R-CNN schedule.
|
|
111
116
|
|
|
112
117
|
Programmatic APIs and a longer walkthrough: [Getting Started](docs/getting-started/installation.md). Config fields: [Configuration](docs/user-guide/configuration.md).
|
|
113
118
|
|
|
@@ -150,7 +155,7 @@ After that, copy-pasted commands and unmodified configs that reference `/path/to
|
|
|
150
155
|
Full documentation is in the **docs/** folder and can be built and served with MkDocs:
|
|
151
156
|
|
|
152
157
|
- **Build/serve**: `make docs` or `make docs-serve` (see [docs/README.md](docs/README.md)); or `uv pip install -e ".[docs]"` then `mkdocs serve`.
|
|
153
|
-
- **Guides**: [Getting Started](docs/getting-started/installation.md), [User Guide](docs/user-guide/geometry.md), [API Reference](docs/api/geometry.md), [Examples](docs/examples/
|
|
158
|
+
- **Guides**: [Getting Started](docs/getting-started/installation.md), [User Guide](docs/user-guide/geometry.md), [API Reference](docs/api/geometry.md), [Examples](docs/examples/inference.md).
|
|
154
159
|
|
|
155
160
|
## Documentation by folder
|
|
156
161
|
|
|
@@ -171,18 +176,18 @@ Install once: `uv pip install -e .`. Then:
|
|
|
171
176
|
|
|
172
177
|
| Task | Command |
|
|
173
178
|
|------|---------|
|
|
174
|
-
| Train | `odet train --config configs/
|
|
179
|
+
| Train | `odet train --config configs/oriented_rcnn/dota_le90_1x.json` or `make train` |
|
|
175
180
|
| Multi-GPU | `make train-multi-gpu` (`torchrun` + cuDNN on `LD_LIBRARY_PATH`) |
|
|
176
181
|
| Tile DOTA | `odet tile-dota /path/to/dota/train` |
|
|
177
|
-
| Val predictions | `odet preds --experiment-dir runs/
|
|
182
|
+
| Val predictions | `odet preds --experiment-dir runs/oriented_rcnn/<timestamp>` or `make preds` |
|
|
178
183
|
| Offline mAP | `make eval-val` or `make preds` then `make metrics` |
|
|
179
184
|
|
|
180
185
|
DOTA configs: per-model `dota_le90_1x.json` / `dota_le90_3x.json` under [configs/](configs/). Run `odet --help` for all subcommands. Makefile shortcuts and script-level options: [tools/README.md](tools/README.md). Config reference: [docs/user-guide/configuration.md](docs/user-guide/configuration.md), [configs/config.schema.json](configs/config.schema.json), [configs/README.md](configs/README.md).
|
|
181
186
|
|
|
182
187
|
## Pretrained weights and evaluation
|
|
183
188
|
|
|
184
|
-
- Place exported best checkpoints under **`pretrained/`** or use Hub slugs (`odet pretrained download oriented_rcnn_dota_le90_1x`). See [pretrained/README.md](pretrained/README.md) and [configs/README.md](configs/README.md#dota-pretrained-models-model-zoo).
|
|
185
|
-
- **Tiled validation:** after training, run `make preds` then `make metrics
|
|
189
|
+
- Place exported best checkpoints under **`pretrained/`** or use Hub slugs (`odet pretrained download oriented_rcnn_dota_le90_3x` or `oriented_rcnn_dota_le90_1x`). See [pretrained/README.md](pretrained/README.md) and [configs/README.md](configs/README.md#dota-pretrained-models-model-zoo).
|
|
190
|
+
- **Tiled validation:** after training, run `make preds` then `make metrics`. Published mAP reports: [`docs/eval-reports/`](docs/eval-reports/) (git). Raw detections for the viewer: gitignored [`predictions/`](predictions/).
|
|
186
191
|
|
|
187
192
|
## Important notes
|
|
188
193
|
|
|
@@ -192,9 +197,14 @@ DOTA configs: per-model `dota_le90_1x.json` / `dota_le90_3x.json` under [configs
|
|
|
192
197
|
|
|
193
198
|
## Roadmap
|
|
194
199
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
- **
|
|
200
|
+
See **[docs/roadmap.md](docs/roadmap.md)** for the full public plan. Summary:
|
|
201
|
+
|
|
202
|
+
- **v0.1** (shipped): Geometry, IoU/NMS, DOTA, three ResNet-FPN detectors, config training, Hub pretrained weights
|
|
203
|
+
- **v0.1.1** (shipped): ProbIoU Faster R-CNN 1×/3× on Hub
|
|
204
|
+
- **v0.2** (shipped): Rotated FCOS (anchor-free single-stage); Hub `rotated_fcos_dota_le90_3x_riou` (81.58% eval-val mAP50)
|
|
205
|
+
- **v0.3**: HRSC2016 and FAIR1M dataset support
|
|
206
|
+
- **v0.4**: RTMDet-R and native YOLO-OBB (AGPL-free production tier)
|
|
207
|
+
- **v0.5+**: Swin-FPN backbone; optional fused CUDA kernels; hosted docs
|
|
198
208
|
|
|
199
209
|
## Contributing
|
|
200
210
|
|
|
@@ -202,7 +212,7 @@ Contributions are welcome. Run tests with `pytest`, format with `black` and `ruf
|
|
|
202
212
|
|
|
203
213
|
## Publishing to PyPI
|
|
204
214
|
|
|
205
|
-
Version **0.
|
|
215
|
+
Version **0.2.0** — tag releases as **`v0.2.0`** (git) matching `version` in `pyproject.toml`.
|
|
206
216
|
|
|
207
217
|
Configs: edit **`configs/`** at the repo root, then **`make sync-configs`** so **`oriented_det/configs/`** stays in sync (see **`oriented_det/configs/vendored_manifest.txt`**). CI runs **`make check-configs`**.
|
|
208
218
|
|
|
@@ -287,7 +297,7 @@ Create a [GitHub Release](https://github.com/DL4EO/oriented-det/releases) from t
|
|
|
287
297
|
|
|
288
298
|
#### 6. After publish
|
|
289
299
|
|
|
290
|
-
-
|
|
300
|
+
- Verify `pip install oriented-det` in a clean environment.
|
|
291
301
|
- Users still install **PyTorch** separately for their CUDA/CPU platform.
|
|
292
302
|
|
|
293
303
|
### Makefile targets
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- **Geometry**: Rotated bounding boxes (rbox: cx, cy, w, h, angle), quadrilateral boxes (qbox), polygon ↔ rbox ↔ hbox conversions, angle normalization (le90, 0–180°), flip/rotate/scale transforms, visualization helpers
|
|
8
8
|
- **IoU & NMS**: Rotated IoU and oriented NMS (CPU with optional GPU kernels when available); AABB pre-filtering; `obb_to_xyxy` / HBB conversion
|
|
9
9
|
- **Datasets**: DOTA polygon loader (pattern, split file, or separate folders), image tiling, label filtering, ignore masks, oriented mAP evaluation
|
|
10
|
-
- **Models**: **Oriented R-CNN** (horizontal RPN + MidpointOffset → oriented ROI), **Rotated Faster R-CNN** (
|
|
10
|
+
- **Models**: **Oriented R-CNN** ([Xie et al., ICCV 2021](https://openaccess.thecvf.com/content/ICCV2021/html/Xie_Oriented_R-CNN_for_Object_Detection_ICCV_2021_paper.html); horizontal RPN + MidpointOffset → oriented RoIAlign + oriented ROI head), **Rotated Faster R-CNN** (Ren et al., NeurIPS 2015 two-stage baseline with horizontal RPN + horizontal RoIAlign + rotated ROI head; MMRotate reference), **Rotated RetinaNet** ([Lin et al., ICCV 2017](https://openaccess.thecvf.com/content_ICCV_2017/papers/Lin_Focal_Loss_for_ICCV_2017_paper.pdf); oriented anchors, sigmoid focal loss), **Rotated FCOS** (anchor-free single-stage; distance-angle coder, centerness, L1 / KFIoU / decoded rIoU); ResNet + FPN backbones; selective loading of external checkpoints where configs wire `checkpoint.load_from_checkpoint`
|
|
11
11
|
- **Training**: JSON configs + **`odet train`**, mixed precision (AMP), gradient accumulation, checkpointing, best-metric tracking, TensorBoard, optional curriculum learning and profiling
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
@@ -32,8 +32,10 @@ uv pip install -r requirements.txt
|
|
|
32
32
|
uv pip install -e .
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
-
|
|
35
|
+
- To auto-activate `.venv` when entering this repo, install the [`direnv`](https://direnv.net/) shell hook and run `direnv allow` from the repo root. The local `.envrc` is intentionally gitignored so each developer can opt in on their machine.
|
|
36
|
+
- From PyPI: `pip install oriented-det`
|
|
36
37
|
- For development and tests: `uv pip install -e ".[dev]"`
|
|
38
|
+
- For the Gradio prediction viewer: `uv pip install -e ".[viewer]"` or `pip install "oriented-det[viewer]"`
|
|
37
39
|
- For **macOS Apple Silicon** or **CPU-only**, see [Installation](docs/getting-started/installation.md).
|
|
38
40
|
- Verify: `pytest tests/test_geometry.py tests/test_iou.py tests/test_nms.py`
|
|
39
41
|
|
|
@@ -43,13 +45,13 @@ After [installation](#installation):
|
|
|
43
45
|
|
|
44
46
|
```bash
|
|
45
47
|
# Train on DOTA tiles (edit dataset paths in the config first)
|
|
46
|
-
odet train --config configs/
|
|
48
|
+
odet train --config configs/oriented_rcnn/dota_le90_1x.json
|
|
47
49
|
|
|
48
50
|
# Or use the Makefile wrapper (same default config)
|
|
49
51
|
make train
|
|
50
52
|
```
|
|
51
53
|
|
|
52
|
-
Default
|
|
54
|
+
Default starter recipe: `configs/oriented_rcnn/dota_le90_1x.json` (see [configs/oriented_rcnn/README.md](configs/oriented_rcnn/README.md)). Use `configs/oriented_rcnn/dota_le90_3x.json` when you want the longer Oriented R-CNN schedule.
|
|
53
55
|
|
|
54
56
|
Programmatic APIs and a longer walkthrough: [Getting Started](docs/getting-started/installation.md). Config fields: [Configuration](docs/user-guide/configuration.md).
|
|
55
57
|
|
|
@@ -92,7 +94,7 @@ After that, copy-pasted commands and unmodified configs that reference `/path/to
|
|
|
92
94
|
Full documentation is in the **docs/** folder and can be built and served with MkDocs:
|
|
93
95
|
|
|
94
96
|
- **Build/serve**: `make docs` or `make docs-serve` (see [docs/README.md](docs/README.md)); or `uv pip install -e ".[docs]"` then `mkdocs serve`.
|
|
95
|
-
- **Guides**: [Getting Started](docs/getting-started/installation.md), [User Guide](docs/user-guide/geometry.md), [API Reference](docs/api/geometry.md), [Examples](docs/examples/
|
|
97
|
+
- **Guides**: [Getting Started](docs/getting-started/installation.md), [User Guide](docs/user-guide/geometry.md), [API Reference](docs/api/geometry.md), [Examples](docs/examples/inference.md).
|
|
96
98
|
|
|
97
99
|
## Documentation by folder
|
|
98
100
|
|
|
@@ -113,18 +115,18 @@ Install once: `uv pip install -e .`. Then:
|
|
|
113
115
|
|
|
114
116
|
| Task | Command |
|
|
115
117
|
|------|---------|
|
|
116
|
-
| Train | `odet train --config configs/
|
|
118
|
+
| Train | `odet train --config configs/oriented_rcnn/dota_le90_1x.json` or `make train` |
|
|
117
119
|
| Multi-GPU | `make train-multi-gpu` (`torchrun` + cuDNN on `LD_LIBRARY_PATH`) |
|
|
118
120
|
| Tile DOTA | `odet tile-dota /path/to/dota/train` |
|
|
119
|
-
| Val predictions | `odet preds --experiment-dir runs/
|
|
121
|
+
| Val predictions | `odet preds --experiment-dir runs/oriented_rcnn/<timestamp>` or `make preds` |
|
|
120
122
|
| Offline mAP | `make eval-val` or `make preds` then `make metrics` |
|
|
121
123
|
|
|
122
124
|
DOTA configs: per-model `dota_le90_1x.json` / `dota_le90_3x.json` under [configs/](configs/). Run `odet --help` for all subcommands. Makefile shortcuts and script-level options: [tools/README.md](tools/README.md). Config reference: [docs/user-guide/configuration.md](docs/user-guide/configuration.md), [configs/config.schema.json](configs/config.schema.json), [configs/README.md](configs/README.md).
|
|
123
125
|
|
|
124
126
|
## Pretrained weights and evaluation
|
|
125
127
|
|
|
126
|
-
- Place exported best checkpoints under **`pretrained/`** or use Hub slugs (`odet pretrained download oriented_rcnn_dota_le90_1x`). See [pretrained/README.md](pretrained/README.md) and [configs/README.md](configs/README.md#dota-pretrained-models-model-zoo).
|
|
127
|
-
- **Tiled validation:** after training, run `make preds` then `make metrics
|
|
128
|
+
- Place exported best checkpoints under **`pretrained/`** or use Hub slugs (`odet pretrained download oriented_rcnn_dota_le90_3x` or `oriented_rcnn_dota_le90_1x`). See [pretrained/README.md](pretrained/README.md) and [configs/README.md](configs/README.md#dota-pretrained-models-model-zoo).
|
|
129
|
+
- **Tiled validation:** after training, run `make preds` then `make metrics`. Published mAP reports: [`docs/eval-reports/`](docs/eval-reports/) (git). Raw detections for the viewer: gitignored [`predictions/`](predictions/).
|
|
128
130
|
|
|
129
131
|
## Important notes
|
|
130
132
|
|
|
@@ -134,9 +136,14 @@ DOTA configs: per-model `dota_le90_1x.json` / `dota_le90_3x.json` under [configs
|
|
|
134
136
|
|
|
135
137
|
## Roadmap
|
|
136
138
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
- **
|
|
139
|
+
See **[docs/roadmap.md](docs/roadmap.md)** for the full public plan. Summary:
|
|
140
|
+
|
|
141
|
+
- **v0.1** (shipped): Geometry, IoU/NMS, DOTA, three ResNet-FPN detectors, config training, Hub pretrained weights
|
|
142
|
+
- **v0.1.1** (shipped): ProbIoU Faster R-CNN 1×/3× on Hub
|
|
143
|
+
- **v0.2** (shipped): Rotated FCOS (anchor-free single-stage); Hub `rotated_fcos_dota_le90_3x_riou` (81.58% eval-val mAP50)
|
|
144
|
+
- **v0.3**: HRSC2016 and FAIR1M dataset support
|
|
145
|
+
- **v0.4**: RTMDet-R and native YOLO-OBB (AGPL-free production tier)
|
|
146
|
+
- **v0.5+**: Swin-FPN backbone; optional fused CUDA kernels; hosted docs
|
|
140
147
|
|
|
141
148
|
## Contributing
|
|
142
149
|
|
|
@@ -144,7 +151,7 @@ Contributions are welcome. Run tests with `pytest`, format with `black` and `ruf
|
|
|
144
151
|
|
|
145
152
|
## Publishing to PyPI
|
|
146
153
|
|
|
147
|
-
Version **0.
|
|
154
|
+
Version **0.2.0** — tag releases as **`v0.2.0`** (git) matching `version` in `pyproject.toml`.
|
|
148
155
|
|
|
149
156
|
Configs: edit **`configs/`** at the repo root, then **`make sync-configs`** so **`oriented_det/configs/`** stays in sync (see **`oriented_det/configs/vendored_manifest.txt`**). CI runs **`make check-configs`**.
|
|
150
157
|
|
|
@@ -229,7 +236,7 @@ Create a [GitHub Release](https://github.com/DL4EO/oriented-det/releases) from t
|
|
|
229
236
|
|
|
230
237
|
#### 6. After publish
|
|
231
238
|
|
|
232
|
-
-
|
|
239
|
+
- Verify `pip install oriented-det` in a clean environment.
|
|
233
240
|
- Users still install **PyTorch** separately for their CUDA/CPU platform.
|
|
234
241
|
|
|
235
242
|
### Makefile targets
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"description": "Inference export contract for oriented-det (ONNX + TensorFlow/Keras detect bundle).",
|
|
4
|
+
"input": {
|
|
5
|
+
"name": "images",
|
|
6
|
+
"dtype": "float32",
|
|
7
|
+
"layout": "NCHW",
|
|
8
|
+
"value_range": "[0, 1] RGB matching training preprocess (see TrainingExperimentConfig.preprocessing)",
|
|
9
|
+
"spatial": "Fixed H×W at export time; batch size 1 for pre-NMS detect modes."
|
|
10
|
+
},
|
|
11
|
+
"export_modes": {
|
|
12
|
+
"backbone": {
|
|
13
|
+
"models": ["rotated_retinanet", "oriented_rcnn", "rotated_faster_rcnn", "rotated_fcos"],
|
|
14
|
+
"onnx_outputs": "Tuple of FPN feature maps in stable key order (see BackboneExportWrapper).",
|
|
15
|
+
"postprocess": "None in ONNX; heads and decoding remain PyTorch or separate TF code."
|
|
16
|
+
},
|
|
17
|
+
"retinanet_heads": {
|
|
18
|
+
"models": ["rotated_retinanet"],
|
|
19
|
+
"onnx_outputs": "Interleaved per level: level{i}_cls_logits, level{i}_bbox_pred (i from 0).",
|
|
20
|
+
"postprocess": "Anchor grid, decode_oriented_boxes, score filter, rotated NMS — not in this ONNX."
|
|
21
|
+
},
|
|
22
|
+
"faster_rcnn_pre_nms": {
|
|
23
|
+
"models": ["rotated_faster_rcnn"],
|
|
24
|
+
"onnx_outputs": {
|
|
25
|
+
"pre_nms_boxes": "[P, 5] oriented boxes (cx,cy,w,h,angle), P = max_pre_nms_candidates",
|
|
26
|
+
"pre_nms_scores": "[P]",
|
|
27
|
+
"pre_nms_labels": "[P] 1-based foreground ids",
|
|
28
|
+
"pre_nms_count": "scalar int64 valid count <= P"
|
|
29
|
+
},
|
|
30
|
+
"postprocess": "Exact CPU rotated NMS + production score_threshold in TF/Keras bundle (export/scripts/build_faster_rcnn_savedmodel.py)."
|
|
31
|
+
},
|
|
32
|
+
"oriented_rcnn_pre_nms": {
|
|
33
|
+
"models": ["oriented_rcnn"],
|
|
34
|
+
"onnx_outputs": {
|
|
35
|
+
"pre_nms_boxes": "[P, 5] oriented boxes (cx,cy,w,h,angle), P = max_pre_nms_candidates",
|
|
36
|
+
"pre_nms_scores": "[P]",
|
|
37
|
+
"pre_nms_labels": "[P] 1-based foreground ids",
|
|
38
|
+
"pre_nms_count": "scalar int64 valid count <= P"
|
|
39
|
+
},
|
|
40
|
+
"postprocess": "Same Keras detect bundle as faster_rcnn_pre_nms (ORT core + exact rotated NMS)."
|
|
41
|
+
},
|
|
42
|
+
"rotated_fcos_pre_nms": {
|
|
43
|
+
"models": ["rotated_fcos"],
|
|
44
|
+
"onnx_outputs": {
|
|
45
|
+
"pre_nms_boxes": "[P, 5] oriented boxes (cx,cy,w,h,angle), P = max_pre_nms_candidates",
|
|
46
|
+
"pre_nms_scores": "[P]",
|
|
47
|
+
"pre_nms_labels": "[P] 1-based foreground ids",
|
|
48
|
+
"pre_nms_count": "scalar int64 valid count <= P"
|
|
49
|
+
},
|
|
50
|
+
"postprocess": "Same Keras detect bundle as faster_rcnn_pre_nms (ORT core + exact rotated NMS)."
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"detect_bundle": {
|
|
54
|
+
"files": ["keras_model.keras", "model.onnx", "export_meta.json"],
|
|
55
|
+
"outputs": {
|
|
56
|
+
"detections": "[max_detections, 7] as (cx,cy,w,h,angle,score,label)",
|
|
57
|
+
"num_detections": "scalar int32"
|
|
58
|
+
},
|
|
59
|
+
"load": "export.tf_serving_model.load_keras_detect_model(bundle_dir_or_keras_path)"
|
|
60
|
+
},
|
|
61
|
+
"nms": {
|
|
62
|
+
"in_onnx": false,
|
|
63
|
+
"in_keras_bundle": true,
|
|
64
|
+
"pytorch_reference": "oriented_det.ops.rotated_ops rotated_nms (force_cpu for deploy parity)"
|
|
65
|
+
},
|
|
66
|
+
"notes": [
|
|
67
|
+
"faster_rcnn_pre_nms and oriented_rcnn_pre_nms pad RPN proposals to fixed P before ROI align for traceable ONNX.",
|
|
68
|
+
"oriented_rcnn_pre_nms uses midpoint RPN + OrientedROIAlign (masked all-N grid_sample under ONNX export).",
|
|
69
|
+
"rotated_fcos_pre_nms decodes DistanceAnglePointCoder + per-level topk, then pads to nms_pre × FPN levels. No ROI.",
|
|
70
|
+
"onnx2tf SavedModel for this graph may fail on ScatterND; the detect bundle uses ONNX Runtime inside Keras.",
|
|
71
|
+
"TFLite full detect is not supported while NMS remains in Python."
|
|
72
|
+
]
|
|
73
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""ONNX Runtime device selection and session cache for TF export inference."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
|
|
7
|
+
|
|
8
|
+
_ORT_DEVICE_OVERRIDE: Optional[str] = None
|
|
9
|
+
_SESSION_CACHE: Dict[Tuple[str, Tuple[str, ...]], object] = {}
|
|
10
|
+
_TF_GPUS_HIDDEN: bool = False
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def set_ort_device(device: Optional[str]) -> None:
|
|
14
|
+
"""Set runtime ORT device for this process (``cpu``, ``cuda``, ``auto``)."""
|
|
15
|
+
global _ORT_DEVICE_OVERRIDE
|
|
16
|
+
_ORT_DEVICE_OVERRIDE = device.lower().strip() if device else None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_ort_device() -> str:
|
|
20
|
+
"""Resolved ORT device string (override, env, or default ``cpu``)."""
|
|
21
|
+
if _ORT_DEVICE_OVERRIDE:
|
|
22
|
+
return _ORT_DEVICE_OVERRIDE
|
|
23
|
+
return (os.environ.get("ORIENTED_DET_ORT_DEVICE") or "cpu").lower().strip()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def ort_providers_for_device(device: Optional[str] = None) -> List[str]:
|
|
27
|
+
"""Map device string to ONNX Runtime ``providers`` list."""
|
|
28
|
+
import onnxruntime as ort
|
|
29
|
+
|
|
30
|
+
d = (device if device is not None else get_ort_device()).lower().strip()
|
|
31
|
+
if d in ("cuda", "gpu"):
|
|
32
|
+
if "CUDAExecutionProvider" not in ort.get_available_providers():
|
|
33
|
+
raise RuntimeError(
|
|
34
|
+
"ORT device=cuda requested but CUDAExecutionProvider is not available. "
|
|
35
|
+
"Install onnxruntime-gpu matching your CUDA driver "
|
|
36
|
+
'(e.g. pip install "oriented-det[export]" / onnxruntime-gpu[cuda,cudnn]).'
|
|
37
|
+
)
|
|
38
|
+
return ["CUDAExecutionProvider", "CPUExecutionProvider"]
|
|
39
|
+
if d == "auto":
|
|
40
|
+
if "CUDAExecutionProvider" in ort.get_available_providers():
|
|
41
|
+
return ["CUDAExecutionProvider", "CPUExecutionProvider"]
|
|
42
|
+
return ["CPUExecutionProvider"]
|
|
43
|
+
if d != "cpu":
|
|
44
|
+
raise ValueError(f"Unknown ORT device {device!r}; use cpu, cuda, or auto.")
|
|
45
|
+
return ["CPUExecutionProvider"]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def hide_tensorflow_gpus() -> bool:
|
|
49
|
+
"""Hide all GPUs from TensorFlow so ORT can own CUDA memory.
|
|
50
|
+
|
|
51
|
+
Call **before** TF creates CUDA contexts (ideally before ``import tensorflow``
|
|
52
|
+
finishes initializing devices). When ORT uses ``CUDAExecutionProvider``, TF
|
|
53
|
+
otherwise claims every visible GPU and ORT then OOMs on ROI Align temps
|
|
54
|
+
(e.g. ``/roi_align/Transpose_2`` ~287 MB that should fit on an A100).
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
True if GPUs are hidden from TF (or none were visible).
|
|
58
|
+
"""
|
|
59
|
+
global _TF_GPUS_HIDDEN
|
|
60
|
+
if _TF_GPUS_HIDDEN:
|
|
61
|
+
return True
|
|
62
|
+
try:
|
|
63
|
+
import tensorflow as tf
|
|
64
|
+
|
|
65
|
+
gpus = tf.config.list_physical_devices("GPU")
|
|
66
|
+
if gpus:
|
|
67
|
+
tf.config.set_visible_devices([], "GPU")
|
|
68
|
+
_TF_GPUS_HIDDEN = True
|
|
69
|
+
return True
|
|
70
|
+
except Exception as exc: # pragma: no cover - depends on TF init order
|
|
71
|
+
print(
|
|
72
|
+
f"Warning: could not hide GPUs from TensorFlow ({exc}). "
|
|
73
|
+
"ORT CUDA may OOM if TF already initialized CUDA. "
|
|
74
|
+
"Configure ORT device before importing tensorflow / tf_serving_model."
|
|
75
|
+
)
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def prepare_tensorflow_for_ort(providers: Sequence[str]) -> None:
|
|
80
|
+
"""If ORT will use CUDA, keep TensorFlow on CPU only."""
|
|
81
|
+
if "CUDAExecutionProvider" in providers:
|
|
82
|
+
hide_tensorflow_gpus()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _cuda_provider_options() -> Dict[str, Any]:
|
|
86
|
+
"""ORT CUDA EP options (device id, arena, optional mem cap)."""
|
|
87
|
+
opts: Dict[str, Any] = {
|
|
88
|
+
"device_id": int(os.environ.get("ORIENTED_DET_ORT_CUDA_DEVICE_ID", "0")),
|
|
89
|
+
"arena_extend_strategy": "kSameAsRequested",
|
|
90
|
+
"cudnn_conv_algo_search": os.environ.get(
|
|
91
|
+
"ORIENTED_DET_ORT_CUDNN_CONV_ALGO", "HEURISTIC"
|
|
92
|
+
),
|
|
93
|
+
}
|
|
94
|
+
mem = os.environ.get("ORIENTED_DET_ORT_GPU_MEM_LIMIT")
|
|
95
|
+
if mem:
|
|
96
|
+
opts["gpu_mem_limit"] = int(mem)
|
|
97
|
+
return opts
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _session_providers(
|
|
101
|
+
providers: Sequence[str],
|
|
102
|
+
) -> List[Union[str, Tuple[str, Dict[str, Any]]]]:
|
|
103
|
+
"""Expand provider names into ORT session provider list (with CUDA options)."""
|
|
104
|
+
out: List[Union[str, Tuple[str, Dict[str, Any]]]] = []
|
|
105
|
+
for p in providers:
|
|
106
|
+
if p == "CUDAExecutionProvider":
|
|
107
|
+
out.append((p, _cuda_provider_options()))
|
|
108
|
+
else:
|
|
109
|
+
out.append(p)
|
|
110
|
+
return out
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def configure_ort_device(device: Optional[str] = None) -> List[str]:
|
|
114
|
+
"""Apply device override, hide TF GPUs when needed, return provider names."""
|
|
115
|
+
if device is not None:
|
|
116
|
+
set_ort_device(device)
|
|
117
|
+
providers = ort_providers_for_device()
|
|
118
|
+
prepare_tensorflow_for_ort(providers)
|
|
119
|
+
return providers
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def clear_ort_session_cache() -> None:
|
|
123
|
+
"""Drop cached ORT sessions (tests)."""
|
|
124
|
+
_SESSION_CACHE.clear()
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def get_ort_session(onnx_path: str, device: Optional[str] = None):
|
|
128
|
+
"""Return a cached ``onnxruntime.InferenceSession`` for ``onnx_path``."""
|
|
129
|
+
import onnxruntime as ort
|
|
130
|
+
|
|
131
|
+
providers = ort_providers_for_device(device)
|
|
132
|
+
prepare_tensorflow_for_ort(providers)
|
|
133
|
+
session_providers = _session_providers(providers)
|
|
134
|
+
# Cache key uses provider *names* only (options are env-stable per process).
|
|
135
|
+
key = (str(onnx_path), tuple(providers))
|
|
136
|
+
if key not in _SESSION_CACHE:
|
|
137
|
+
so = ort.SessionOptions()
|
|
138
|
+
so.enable_mem_pattern = True
|
|
139
|
+
_SESSION_CACHE[key] = ort.InferenceSession(
|
|
140
|
+
str(onnx_path),
|
|
141
|
+
sess_options=so,
|
|
142
|
+
providers=session_providers,
|
|
143
|
+
)
|
|
144
|
+
return _SESSION_CACHE[key]
|