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.
Files changed (193) hide show
  1. {oriented_det-0.1.0 → oriented_det-0.2.0}/PKG-INFO +27 -17
  2. {oriented_det-0.1.0 → oriented_det-0.2.0}/README.md +21 -14
  3. oriented_det-0.2.0/export/contract.json +73 -0
  4. oriented_det-0.2.0/export/ort_runtime.py +144 -0
  5. oriented_det-0.2.0/export/postprocess.py +228 -0
  6. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/build_faster_rcnn_savedmodel.py +40 -10
  7. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/export_onnx.py +55 -12
  8. oriented_det-0.2.0/export/scripts/export_tf.py +187 -0
  9. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/predict_savedmodel.py +17 -12
  10. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/save_predictions_tf.py +14 -4
  11. oriented_det-0.2.0/export/tests/test_export_cli.py +201 -0
  12. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/tests/test_export_wrappers.py +63 -3
  13. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/tests/test_faster_rcnn_export_parity.py +13 -9
  14. oriented_det-0.2.0/export/tests/test_keras_detect_bundle.py +130 -0
  15. oriented_det-0.2.0/export/tests/test_oriented_rcnn_export_parity.py +312 -0
  16. oriented_det-0.2.0/export/tests/test_ort_runtime.py +101 -0
  17. oriented_det-0.2.0/export/tests/test_postprocess.py +50 -0
  18. oriented_det-0.2.0/export/tests/test_rotated_fcos_export_parity.py +220 -0
  19. oriented_det-0.2.0/export/tf_serving_model.py +176 -0
  20. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/wrappers.py +102 -7
  21. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/__init__.py +5 -1
  22. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/cli/__init__.py +19 -23
  23. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/models/rotated_faster_rcnn_r50.json +1 -0
  24. oriented_det-0.2.0/oriented_det/configs/_base_/models/rotated_fcos_r50.json +35 -0
  25. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/config.schema.json +57 -3
  26. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/oriented_rcnn/dota_le90_1x.json +1 -1
  27. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_faster_rcnn/dota_le90_1x.json +6 -4
  28. oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_1x.json +107 -0
  29. oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_1x_kfiou_aux.json +10 -0
  30. oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_1x_riou.json +11 -0
  31. oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_3x.json +27 -0
  32. oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_3x_kfiou_aux.json +15 -0
  33. oriented_det-0.2.0/oriented_det/configs/rotated_fcos/dota_le90_3x_riou.json +15 -0
  34. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_retinanet/dota_le90_1x.json +2 -2
  35. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/__init__.py +12 -2
  36. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/airbus_playground.py +8 -1
  37. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/evaluation.py +284 -0
  38. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/__init__.py +9 -1
  39. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/backbones/resnet_fpn.py +8 -0
  40. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/bbox_coder.py +127 -0
  41. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/faster_rcnn_inference.py +48 -37
  42. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/horizontal_roi_coder.py +47 -7
  43. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/oriented_rcnn.py +30 -5
  44. oriented_det-0.2.0/oriented_det/models/oriented_rcnn_inference.py +242 -0
  45. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/oriented_roi.py +270 -98
  46. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/oriented_rpn.py +20 -4
  47. oriented_det-0.2.0/oriented_det/models/rotated_fcos.py +1086 -0
  48. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/rotated_retinanet.py +293 -148
  49. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/utils.py +33 -9
  50. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/__init__.py +5 -0
  51. oriented_det-0.2.0/oriented_det/ops/diff_iou_rotated.py +196 -0
  52. oriented_det-0.2.0/oriented_det/ops/gaussian_angle.py +60 -0
  53. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/pretrained/__init__.py +4 -0
  54. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/pretrained/hub.py +39 -0
  55. oriented_det-0.2.0/oriented_det/pretrained/manifest.json +78 -0
  56. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/checkpoint.py +183 -18
  57. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/config.py +43 -1
  58. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/engine.py +28 -2
  59. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/utils.py +68 -0
  60. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/PKG-INFO +27 -17
  61. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/SOURCES.txt +29 -1
  62. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/requires.txt +5 -1
  63. {oriented_det-0.1.0 → oriented_det-0.2.0}/pyproject.toml +11 -5
  64. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_airbus_playground.py +31 -0
  65. oriented_det-0.2.0/tests/test_annotation_csv.py +87 -0
  66. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_bbox_coder.py +42 -0
  67. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_config_behavior.py +1 -14
  68. oriented_det-0.2.0/tests/test_config_model_wiring.py +477 -0
  69. oriented_det-0.2.0/tests/test_diff_iou_rotated.py +103 -0
  70. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_evaluation.py +30 -0
  71. oriented_det-0.2.0/tests/test_gaussian_angle.py +66 -0
  72. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_models.py +558 -0
  73. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_pretrained_hub.py +56 -6
  74. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_roi.py +263 -6
  75. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_rpn.py +38 -0
  76. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_score_thresholds.py +4 -0
  77. oriented_det-0.2.0/tests/test_source_provenance.py +28 -0
  78. oriented_det-0.2.0/tests/test_viewer_gradio_compat.py +9 -0
  79. oriented_det-0.2.0/tools/annotation_csv.py +167 -0
  80. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/app.py +110 -15
  81. oriented_det-0.2.0/tools/compare_hbb_obb_counts.py +63 -0
  82. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/dataset_stats.py +3 -0
  83. oriented_det-0.2.0/tools/filter_predictions_by_gt.py +58 -0
  84. oriented_det-0.2.0/tools/generate_oriented_annotations.py +96 -0
  85. oriented_det-0.2.0/tools/hbb_to_obb.py +563 -0
  86. oriented_det-0.2.0/tools/image_demo.py +614 -0
  87. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/lr_finder.py +12 -3
  88. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/preview_augmentation.py +5 -2
  89. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/save_predictions.py +83 -0
  90. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/train.py +196 -51
  91. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/train_multi_gpu.py +3 -3
  92. oriented_det-0.2.0/tools/viewer_annotations.py +681 -0
  93. oriented_det-0.1.0/export/ort_runtime.py +0 -67
  94. oriented_det-0.1.0/export/postprocess.py +0 -151
  95. oriented_det-0.1.0/export/tests/test_ort_runtime.py +0 -41
  96. oriented_det-0.1.0/export/tf_serving_model.py +0 -96
  97. oriented_det-0.1.0/oriented_det/pretrained/manifest.json +0 -46
  98. oriented_det-0.1.0/tests/test_config_model_wiring.py +0 -195
  99. oriented_det-0.1.0/tools/image_demo.py +0 -200
  100. oriented_det-0.1.0/tools/visualize_boxes.py +0 -183
  101. {oriented_det-0.1.0 → oriented_det-0.2.0}/LICENSE +0 -0
  102. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/__init__.py +0 -0
  103. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/__init__.py +0 -0
  104. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/onnx_to_savedmodel.py +0 -0
  105. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/scripts/to_tflite.py +0 -0
  106. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/tests/test_export_onnx_optional.py +0 -0
  107. {oriented_det-0.1.0 → oriented_det-0.2.0}/export/val_dataset.py +0 -0
  108. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/cli/train.py +0 -0
  109. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/augmentation.json +0 -0
  110. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/datasets/dota_le90.json +0 -0
  111. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/fp16.json +0 -0
  112. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/models/oriented_rcnn_r50.json +0 -0
  113. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/models/rotated_retinanet_r50.json +0 -0
  114. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/preprocessing.json +0 -0
  115. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/_base_/schedules/1x.json +0 -0
  116. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/oriented_rcnn/dota_le90_3x.json +0 -0
  117. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_faster_rcnn/dota_le90_3x.json +0 -0
  118. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/configs/rotated_retinanet/dota_le90_3x.json +0 -0
  119. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/dota.py +0 -0
  120. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/dota_classes.py +0 -0
  121. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/flips.py +0 -0
  122. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/preprocessing.py +0 -0
  123. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/tiling.py +0 -0
  124. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/data/transforms.py +0 -0
  125. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/__init__.py +0 -0
  126. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/poly.py +0 -0
  127. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/qbox.py +0 -0
  128. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/rbox.py +0 -0
  129. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/geometry/transforms.py +0 -0
  130. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/backbones/__init__.py +0 -0
  131. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/models/backbones/utils.py +0 -0
  132. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/gpu_ops.py +0 -0
  133. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/iou.py +0 -0
  134. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/kfiou.py +0 -0
  135. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/nms.py +0 -0
  136. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/probiou.py +0 -0
  137. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/rotated_ops.py +0 -0
  138. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/ops/utils.py +0 -0
  139. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/__init__.py +0 -0
  140. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/collate.py +0 -0
  141. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/runtime/inference.py +0 -0
  142. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/__init__.py +0 -0
  143. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/grouped_ce.py +0 -0
  144. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/piecewise_schedule.py +0 -0
  145. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/train/profiler.py +0 -0
  146. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/__init__.py +0 -0
  147. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/config.py +0 -0
  148. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/device.py +0 -0
  149. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/logging.py +0 -0
  150. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/progress.py +0 -0
  151. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det/utils/viz.py +0 -0
  152. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/dependency_links.txt +0 -0
  153. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/entry_points.txt +0 -0
  154. {oriented_det-0.1.0 → oriented_det-0.2.0}/oriented_det.egg-info/top_level.txt +0 -0
  155. {oriented_det-0.1.0 → oriented_det-0.2.0}/setup.cfg +0 -0
  156. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_cosine_tail_scheduler.py +0 -0
  157. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_deploy_generate_description.py +0 -0
  158. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_dota.py +0 -0
  159. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_dota_tile_roots.py +0 -0
  160. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_exact_rotated_iou.py +0 -0
  161. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_geometry.py +0 -0
  162. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_geometry_transforms.py +0 -0
  163. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_gpu_ops.py +0 -0
  164. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_grouped_ce.py +0 -0
  165. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_iou.py +0 -0
  166. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_kfiou.py +0 -0
  167. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_metrics_margin_filter.py +0 -0
  168. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_nms.py +0 -0
  169. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_ops_utils.py +0 -0
  170. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_optimizer_param_groups.py +0 -0
  171. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_piecewise_schedule.py +0 -0
  172. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_preprocessing.py +0 -0
  173. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_probiou.py +0 -0
  174. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_sliding_window_margin.py +0 -0
  175. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_tiling.py +0 -0
  176. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_train.py +0 -0
  177. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_train_flips.py +0 -0
  178. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_training_config_strict.py +0 -0
  179. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_transforms.py +0 -0
  180. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_utils_config.py +0 -0
  181. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_utils_viz.py +0 -0
  182. {oriented_det-0.1.0 → oriented_det-0.2.0}/tests/test_vendored_configs_sync.py +0 -0
  183. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/__init__.py +0 -0
  184. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/dota_labels_to_comma.py +0 -0
  185. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/free_gpu.py +0 -0
  186. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/generate_airbus_playground_csv.py +0 -0
  187. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/measure_sampled_riou_error.py +0 -0
  188. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/playground_to_dota.py +0 -0
  189. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/pretrained_download.py +0 -0
  190. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/publish_checkpoint.py +0 -0
  191. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/sync_vendored_configs.py +0 -0
  192. {oriented_det-0.1.0 → oriented_det-0.2.0}/tools/tile_dota.py +0 -0
  193. {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.1.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.com/DL4EO/oriented-det#readme
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** (oriented RPN + oriented ROI), **Rotated RetinaNet** (oriented anchors, focal loss); ResNet + FPN backbones; selective loading of external checkpoints where configs wire `checkpoint.load_from_checkpoint`
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
- - From PyPI (when published): `pip install oriented-det`
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/rotated_faster_rcnn/dota_le90_3x.json
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 3× recipe: `configs/rotated_faster_rcnn/dota_le90_3x.json` (see [configs/rotated_faster_rcnn/README.md](configs/rotated_faster_rcnn/README.md)). 1× baseline: `dota_le90_1x.json`.
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/visualization.md).
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/rotated_faster_rcnn/dota_le90_3x.json` or `make train` |
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/rotated_faster_rcnn/<timestamp>` or `make preds` |
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` (or `odet preds` / `odet preds --metrics-from-json`). Large images use sliding-window inference when they exceed the model canvas; thresholds and overlap come from **`production.*`** in the experiment config.
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
- - **v0.1** (current): Geometry, IoU/NMS, DOTA loader + tiler, three baseline detectors, config-based training, Hub pretrained weights
196
- - **Next**: HRSC2016 dataset support, expanded tutorials, hosted docs
197
- - **Future**: Additional oriented detectors (e.g. FAIR1M), optional fused CUDA kernels
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.1.0** — tag releases as **`v0.1.0`** (git) matching `version` in `pyproject.toml`.
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
- - Change install docs from “when published” to `pip install oriented-det`.
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** (oriented RPN + oriented ROI), **Rotated RetinaNet** (oriented anchors, focal loss); ResNet + FPN backbones; selective loading of external checkpoints where configs wire `checkpoint.load_from_checkpoint`
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
- - From PyPI (when published): `pip install oriented-det`
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/rotated_faster_rcnn/dota_le90_3x.json
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 3× recipe: `configs/rotated_faster_rcnn/dota_le90_3x.json` (see [configs/rotated_faster_rcnn/README.md](configs/rotated_faster_rcnn/README.md)). 1× baseline: `dota_le90_1x.json`.
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/visualization.md).
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/rotated_faster_rcnn/dota_le90_3x.json` or `make train` |
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/rotated_faster_rcnn/<timestamp>` or `make preds` |
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` (or `odet preds` / `odet preds --metrics-from-json`). Large images use sliding-window inference when they exceed the model canvas; thresholds and overlap come from **`production.*`** in the experiment config.
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
- - **v0.1** (current): Geometry, IoU/NMS, DOTA loader + tiler, three baseline detectors, config-based training, Hub pretrained weights
138
- - **Next**: HRSC2016 dataset support, expanded tutorials, hosted docs
139
- - **Future**: Additional oriented detectors (e.g. FAIR1M), optional fused CUDA kernels
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.1.0** — tag releases as **`v0.1.0`** (git) matching `version` in `pyproject.toml`.
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
- - Change install docs from “when published” to `pip install oriented-det`.
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]