megadetector 5.0.10__py3-none-any.whl → 5.0.11__py3-none-any.whl

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.

Potentially problematic release.


This version of megadetector might be problematic. Click here for more details.

Files changed (226) hide show
  1. {megadetector-5.0.10.dist-info → megadetector-5.0.11.dist-info}/LICENSE +0 -0
  2. {megadetector-5.0.10.dist-info → megadetector-5.0.11.dist-info}/METADATA +12 -11
  3. megadetector-5.0.11.dist-info/RECORD +5 -0
  4. megadetector-5.0.11.dist-info/top_level.txt +1 -0
  5. api/__init__.py +0 -0
  6. api/batch_processing/__init__.py +0 -0
  7. api/batch_processing/api_core/__init__.py +0 -0
  8. api/batch_processing/api_core/batch_service/__init__.py +0 -0
  9. api/batch_processing/api_core/batch_service/score.py +0 -439
  10. api/batch_processing/api_core/server.py +0 -294
  11. api/batch_processing/api_core/server_api_config.py +0 -98
  12. api/batch_processing/api_core/server_app_config.py +0 -55
  13. api/batch_processing/api_core/server_batch_job_manager.py +0 -220
  14. api/batch_processing/api_core/server_job_status_table.py +0 -152
  15. api/batch_processing/api_core/server_orchestration.py +0 -360
  16. api/batch_processing/api_core/server_utils.py +0 -92
  17. api/batch_processing/api_core_support/__init__.py +0 -0
  18. api/batch_processing/api_core_support/aggregate_results_manually.py +0 -46
  19. api/batch_processing/api_support/__init__.py +0 -0
  20. api/batch_processing/api_support/summarize_daily_activity.py +0 -152
  21. api/batch_processing/data_preparation/__init__.py +0 -0
  22. api/batch_processing/data_preparation/manage_local_batch.py +0 -2391
  23. api/batch_processing/data_preparation/manage_video_batch.py +0 -327
  24. api/batch_processing/integration/digiKam/setup.py +0 -6
  25. api/batch_processing/integration/digiKam/xmp_integration.py +0 -465
  26. api/batch_processing/integration/eMammal/test_scripts/config_template.py +0 -5
  27. api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +0 -126
  28. api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +0 -55
  29. api/batch_processing/postprocessing/__init__.py +0 -0
  30. api/batch_processing/postprocessing/add_max_conf.py +0 -64
  31. api/batch_processing/postprocessing/categorize_detections_by_size.py +0 -163
  32. api/batch_processing/postprocessing/combine_api_outputs.py +0 -249
  33. api/batch_processing/postprocessing/compare_batch_results.py +0 -958
  34. api/batch_processing/postprocessing/convert_output_format.py +0 -397
  35. api/batch_processing/postprocessing/load_api_results.py +0 -195
  36. api/batch_processing/postprocessing/md_to_coco.py +0 -310
  37. api/batch_processing/postprocessing/md_to_labelme.py +0 -330
  38. api/batch_processing/postprocessing/merge_detections.py +0 -401
  39. api/batch_processing/postprocessing/postprocess_batch_results.py +0 -1904
  40. api/batch_processing/postprocessing/remap_detection_categories.py +0 -170
  41. api/batch_processing/postprocessing/render_detection_confusion_matrix.py +0 -661
  42. api/batch_processing/postprocessing/repeat_detection_elimination/find_repeat_detections.py +0 -211
  43. api/batch_processing/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +0 -82
  44. api/batch_processing/postprocessing/repeat_detection_elimination/repeat_detections_core.py +0 -1631
  45. api/batch_processing/postprocessing/separate_detections_into_folders.py +0 -731
  46. api/batch_processing/postprocessing/subset_json_detector_output.py +0 -696
  47. api/batch_processing/postprocessing/top_folders_to_bottom.py +0 -223
  48. api/synchronous/__init__.py +0 -0
  49. api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
  50. api/synchronous/api_core/animal_detection_api/api_backend.py +0 -152
  51. api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -266
  52. api/synchronous/api_core/animal_detection_api/config.py +0 -35
  53. api/synchronous/api_core/animal_detection_api/data_management/annotations/annotation_constants.py +0 -47
  54. api/synchronous/api_core/animal_detection_api/detection/detector_training/copy_checkpoints.py +0 -43
  55. api/synchronous/api_core/animal_detection_api/detection/detector_training/model_main_tf2.py +0 -114
  56. api/synchronous/api_core/animal_detection_api/detection/process_video.py +0 -543
  57. api/synchronous/api_core/animal_detection_api/detection/pytorch_detector.py +0 -304
  58. api/synchronous/api_core/animal_detection_api/detection/run_detector.py +0 -627
  59. api/synchronous/api_core/animal_detection_api/detection/run_detector_batch.py +0 -1029
  60. api/synchronous/api_core/animal_detection_api/detection/run_inference_with_yolov5_val.py +0 -581
  61. api/synchronous/api_core/animal_detection_api/detection/run_tiled_inference.py +0 -754
  62. api/synchronous/api_core/animal_detection_api/detection/tf_detector.py +0 -165
  63. api/synchronous/api_core/animal_detection_api/detection/video_utils.py +0 -495
  64. api/synchronous/api_core/animal_detection_api/md_utils/azure_utils.py +0 -174
  65. api/synchronous/api_core/animal_detection_api/md_utils/ct_utils.py +0 -262
  66. api/synchronous/api_core/animal_detection_api/md_utils/directory_listing.py +0 -251
  67. api/synchronous/api_core/animal_detection_api/md_utils/matlab_porting_tools.py +0 -97
  68. api/synchronous/api_core/animal_detection_api/md_utils/path_utils.py +0 -416
  69. api/synchronous/api_core/animal_detection_api/md_utils/process_utils.py +0 -110
  70. api/synchronous/api_core/animal_detection_api/md_utils/sas_blob_utils.py +0 -509
  71. api/synchronous/api_core/animal_detection_api/md_utils/string_utils.py +0 -59
  72. api/synchronous/api_core/animal_detection_api/md_utils/url_utils.py +0 -144
  73. api/synchronous/api_core/animal_detection_api/md_utils/write_html_image_list.py +0 -226
  74. api/synchronous/api_core/animal_detection_api/md_visualization/visualization_utils.py +0 -841
  75. api/synchronous/api_core/tests/__init__.py +0 -0
  76. api/synchronous/api_core/tests/load_test.py +0 -110
  77. classification/__init__.py +0 -0
  78. classification/aggregate_classifier_probs.py +0 -108
  79. classification/analyze_failed_images.py +0 -227
  80. classification/cache_batchapi_outputs.py +0 -198
  81. classification/create_classification_dataset.py +0 -627
  82. classification/crop_detections.py +0 -516
  83. classification/csv_to_json.py +0 -226
  84. classification/detect_and_crop.py +0 -855
  85. classification/efficientnet/__init__.py +0 -9
  86. classification/efficientnet/model.py +0 -415
  87. classification/efficientnet/utils.py +0 -610
  88. classification/evaluate_model.py +0 -520
  89. classification/identify_mislabeled_candidates.py +0 -152
  90. classification/json_to_azcopy_list.py +0 -63
  91. classification/json_validator.py +0 -695
  92. classification/map_classification_categories.py +0 -276
  93. classification/merge_classification_detection_output.py +0 -506
  94. classification/prepare_classification_script.py +0 -194
  95. classification/prepare_classification_script_mc.py +0 -228
  96. classification/run_classifier.py +0 -286
  97. classification/save_mislabeled.py +0 -110
  98. classification/train_classifier.py +0 -825
  99. classification/train_classifier_tf.py +0 -724
  100. classification/train_utils.py +0 -322
  101. data_management/__init__.py +0 -0
  102. data_management/annotations/__init__.py +0 -0
  103. data_management/annotations/annotation_constants.py +0 -34
  104. data_management/camtrap_dp_to_coco.py +0 -238
  105. data_management/cct_json_utils.py +0 -395
  106. data_management/cct_to_md.py +0 -176
  107. data_management/cct_to_wi.py +0 -289
  108. data_management/coco_to_labelme.py +0 -272
  109. data_management/coco_to_yolo.py +0 -662
  110. data_management/databases/__init__.py +0 -0
  111. data_management/databases/add_width_and_height_to_db.py +0 -33
  112. data_management/databases/combine_coco_camera_traps_files.py +0 -206
  113. data_management/databases/integrity_check_json_db.py +0 -477
  114. data_management/databases/subset_json_db.py +0 -115
  115. data_management/generate_crops_from_cct.py +0 -149
  116. data_management/get_image_sizes.py +0 -188
  117. data_management/importers/add_nacti_sizes.py +0 -52
  118. data_management/importers/add_timestamps_to_icct.py +0 -79
  119. data_management/importers/animl_results_to_md_results.py +0 -158
  120. data_management/importers/auckland_doc_test_to_json.py +0 -372
  121. data_management/importers/auckland_doc_to_json.py +0 -200
  122. data_management/importers/awc_to_json.py +0 -189
  123. data_management/importers/bellevue_to_json.py +0 -273
  124. data_management/importers/cacophony-thermal-importer.py +0 -796
  125. data_management/importers/carrizo_shrubfree_2018.py +0 -268
  126. data_management/importers/carrizo_trail_cam_2017.py +0 -287
  127. data_management/importers/cct_field_adjustments.py +0 -57
  128. data_management/importers/channel_islands_to_cct.py +0 -913
  129. data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  130. data_management/importers/eMammal/eMammal_helpers.py +0 -249
  131. data_management/importers/eMammal/make_eMammal_json.py +0 -223
  132. data_management/importers/ena24_to_json.py +0 -275
  133. data_management/importers/filenames_to_json.py +0 -385
  134. data_management/importers/helena_to_cct.py +0 -282
  135. data_management/importers/idaho-camera-traps.py +0 -1407
  136. data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  137. data_management/importers/jb_csv_to_json.py +0 -150
  138. data_management/importers/mcgill_to_json.py +0 -250
  139. data_management/importers/missouri_to_json.py +0 -489
  140. data_management/importers/nacti_fieldname_adjustments.py +0 -79
  141. data_management/importers/noaa_seals_2019.py +0 -181
  142. data_management/importers/pc_to_json.py +0 -365
  143. data_management/importers/plot_wni_giraffes.py +0 -123
  144. data_management/importers/prepare-noaa-fish-data-for-lila.py +0 -359
  145. data_management/importers/prepare_zsl_imerit.py +0 -131
  146. data_management/importers/rspb_to_json.py +0 -356
  147. data_management/importers/save_the_elephants_survey_A.py +0 -320
  148. data_management/importers/save_the_elephants_survey_B.py +0 -332
  149. data_management/importers/snapshot_safari_importer.py +0 -758
  150. data_management/importers/snapshot_safari_importer_reprise.py +0 -665
  151. data_management/importers/snapshot_serengeti_lila.py +0 -1067
  152. data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  153. data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  154. data_management/importers/sulross_get_exif.py +0 -65
  155. data_management/importers/timelapse_csv_set_to_json.py +0 -490
  156. data_management/importers/ubc_to_json.py +0 -399
  157. data_management/importers/umn_to_json.py +0 -507
  158. data_management/importers/wellington_to_json.py +0 -263
  159. data_management/importers/wi_to_json.py +0 -441
  160. data_management/importers/zamba_results_to_md_results.py +0 -181
  161. data_management/labelme_to_coco.py +0 -548
  162. data_management/labelme_to_yolo.py +0 -272
  163. data_management/lila/__init__.py +0 -0
  164. data_management/lila/add_locations_to_island_camera_traps.py +0 -97
  165. data_management/lila/add_locations_to_nacti.py +0 -147
  166. data_management/lila/create_lila_blank_set.py +0 -557
  167. data_management/lila/create_lila_test_set.py +0 -151
  168. data_management/lila/create_links_to_md_results_files.py +0 -106
  169. data_management/lila/download_lila_subset.py +0 -177
  170. data_management/lila/generate_lila_per_image_labels.py +0 -515
  171. data_management/lila/get_lila_annotation_counts.py +0 -170
  172. data_management/lila/get_lila_image_counts.py +0 -111
  173. data_management/lila/lila_common.py +0 -300
  174. data_management/lila/test_lila_metadata_urls.py +0 -132
  175. data_management/ocr_tools.py +0 -874
  176. data_management/read_exif.py +0 -681
  177. data_management/remap_coco_categories.py +0 -84
  178. data_management/remove_exif.py +0 -66
  179. data_management/resize_coco_dataset.py +0 -189
  180. data_management/wi_download_csv_to_coco.py +0 -246
  181. data_management/yolo_output_to_md_output.py +0 -441
  182. data_management/yolo_to_coco.py +0 -676
  183. detection/__init__.py +0 -0
  184. detection/detector_training/__init__.py +0 -0
  185. detection/detector_training/model_main_tf2.py +0 -114
  186. detection/process_video.py +0 -703
  187. detection/pytorch_detector.py +0 -337
  188. detection/run_detector.py +0 -779
  189. detection/run_detector_batch.py +0 -1219
  190. detection/run_inference_with_yolov5_val.py +0 -917
  191. detection/run_tiled_inference.py +0 -935
  192. detection/tf_detector.py +0 -188
  193. detection/video_utils.py +0 -606
  194. docs/source/conf.py +0 -43
  195. md_utils/__init__.py +0 -0
  196. md_utils/azure_utils.py +0 -174
  197. md_utils/ct_utils.py +0 -612
  198. md_utils/directory_listing.py +0 -246
  199. md_utils/md_tests.py +0 -968
  200. md_utils/path_utils.py +0 -1044
  201. md_utils/process_utils.py +0 -157
  202. md_utils/sas_blob_utils.py +0 -509
  203. md_utils/split_locations_into_train_val.py +0 -228
  204. md_utils/string_utils.py +0 -92
  205. md_utils/url_utils.py +0 -323
  206. md_utils/write_html_image_list.py +0 -225
  207. md_visualization/__init__.py +0 -0
  208. md_visualization/plot_utils.py +0 -293
  209. md_visualization/render_images_with_thumbnails.py +0 -275
  210. md_visualization/visualization_utils.py +0 -1537
  211. md_visualization/visualize_db.py +0 -551
  212. md_visualization/visualize_detector_output.py +0 -406
  213. megadetector-5.0.10.dist-info/RECORD +0 -224
  214. megadetector-5.0.10.dist-info/top_level.txt +0 -8
  215. taxonomy_mapping/__init__.py +0 -0
  216. taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +0 -491
  217. taxonomy_mapping/map_new_lila_datasets.py +0 -154
  218. taxonomy_mapping/prepare_lila_taxonomy_release.py +0 -142
  219. taxonomy_mapping/preview_lila_taxonomy.py +0 -591
  220. taxonomy_mapping/retrieve_sample_image.py +0 -71
  221. taxonomy_mapping/simple_image_download.py +0 -218
  222. taxonomy_mapping/species_lookup.py +0 -834
  223. taxonomy_mapping/taxonomy_csv_checker.py +0 -159
  224. taxonomy_mapping/taxonomy_graph.py +0 -346
  225. taxonomy_mapping/validate_lila_category_mappings.py +0 -83
  226. {megadetector-5.0.10.dist-info → megadetector-5.0.11.dist-info}/WHEEL +0 -0
@@ -1,337 +0,0 @@
1
- """
2
-
3
- pytorch_detector.py
4
-
5
- Module to run MegaDetector v5, a PyTorch YOLOv5 animal detection model.
6
-
7
- """
8
-
9
- #%% Imports and constants
10
-
11
- import torch
12
- import numpy as np
13
- import traceback
14
-
15
- from detection.run_detector import CONF_DIGITS, COORD_DIGITS, FAILURE_INFER
16
- from md_utils import ct_utils
17
-
18
- # We support a few ways of accessing the YOLOv5 dependencies:
19
- #
20
- # * The standard configuration as of 2023.09 expects that the YOLOv5 repo is checked
21
- # out and on the PYTHONPATH (import utils)
22
- #
23
- # * Supported but non-default (used for PyPI packaging):
24
- #
25
- # pip install ultralytics-yolov5
26
- #
27
- # * Works, but not supported:
28
- #
29
- # pip install yolov5
30
- #
31
- # * Unfinished:
32
- #
33
- # pip install ultralytics
34
- #
35
- # If try_ultralytics_import is True, we'll try to import all YOLOv5 dependencies from
36
- # ultralytics.utils and ultralytics.data. But as of 2023.11, this results in a "No
37
- # module named 'models'" error when running MDv5, and there's no upside to this approach
38
- # compared to using either of the YOLOv5 PyPI packages, so... punting on this for now.
39
-
40
- utils_imported = False
41
- try_yolov5_import = True
42
-
43
- # See above; this should remain as "False" unless we update the MegaDetector .pt file
44
- # to use more recent YOLOv5 namespace conventions.
45
- try_ultralytics_import = False
46
-
47
- # First try importing from the yolov5 package
48
- if try_yolov5_import and not utils_imported:
49
-
50
- try:
51
- from yolov5.utils.general import non_max_suppression, xyxy2xywh # noqa
52
- from yolov5.utils.augmentations import letterbox # noqa
53
- from yolov5.utils.general import scale_boxes as scale_coords # noqa
54
- utils_imported = True
55
- print('Imported YOLOv5 from YOLOv5 package')
56
- except Exception:
57
- # print('YOLOv5 module import failed, falling back to path-based import')
58
- pass
59
-
60
- # If we haven't succeeded yet, import from the ultralytics package
61
- if try_ultralytics_import and not utils_imported:
62
-
63
- try:
64
- from ultralytics.utils.ops import non_max_suppression # noqa
65
- from ultralytics.utils.ops import xyxy2xywh # noqa
66
- from ultralytics.utils.ops import scale_coords # noqa
67
- from ultralytics.data.augment import LetterBox
68
-
69
- # letterbox() became a LetterBox class in the ultralytics package
70
- def letterbox(img,new_shape,stride,auto=True): # noqa
71
- L = LetterBox(new_shape,stride=stride,auto=auto)
72
- letterbox_result = L(image=img)
73
- return [letterbox_result]
74
- utils_imported = True
75
- print('Imported YOLOv5 from ultralytics package')
76
- except Exception:
77
- # print('Ultralytics module import failed, falling back to yolov5 import')
78
- pass
79
-
80
- # If we haven't succeeded yet, import from the YOLOv5 repo
81
- if not utils_imported:
82
-
83
- try:
84
- # import pre- and post-processing functions from the YOLOv5 repo
85
- from utils.general import non_max_suppression, xyxy2xywh # noqa
86
- from utils.augmentations import letterbox # noqa
87
-
88
- # scale_coords() became scale_boxes() in later YOLOv5 versions
89
- try:
90
- from utils.general import scale_coords # noqa
91
- except ImportError:
92
- from utils.general import scale_boxes as scale_coords
93
- utils_imported = True
94
- print('Imported YOLOv5 as utils.*')
95
- except ModuleNotFoundError:
96
- raise ModuleNotFoundError('Could not import YOLOv5 functions.')
97
-
98
- assert utils_imported, 'YOLOv5 import error'
99
-
100
- print(f'Using PyTorch version {torch.__version__}')
101
-
102
-
103
- #%% Classes
104
-
105
- class PTDetector:
106
-
107
- #: Image size passed to YOLOv5's letterbox() function; 1280 means "1280 on the long side, preserving
108
- #: aspect ratio"
109
- #:
110
- #: :meta private:
111
- IMAGE_SIZE = 1280
112
-
113
- #: Stride size passed to YOLOv5's letterbox() function
114
- #:
115
- #: :meta private:
116
- STRIDE = 64
117
-
118
- def __init__(self, model_path, force_cpu=False, use_model_native_classes= False):
119
-
120
- self.device = 'cpu'
121
- if not force_cpu:
122
- if torch.cuda.is_available():
123
- self.device = torch.device('cuda:0')
124
- try:
125
- if torch.backends.mps.is_built and torch.backends.mps.is_available():
126
- self.device = 'mps'
127
- except AttributeError:
128
- pass
129
- self.model = PTDetector._load_model(model_path, self.device)
130
- if (self.device != 'cpu'):
131
- print('Sending model to GPU')
132
- self.model.to(self.device)
133
-
134
- self.printed_image_size_warning = False
135
- self.use_model_native_classes = use_model_native_classes
136
-
137
-
138
- @staticmethod
139
- def _load_model(model_pt_path, device):
140
-
141
- # There are two very slightly different ways to load the model, (1) using the
142
- # map_location=device parameter to torch.load and (2) calling .to(device) after
143
- # loading the model. The former is what we did for a zillion years, but is not
144
- # supported on Apple silicon at of 2029.09. Switching to the latter causes
145
- # very slight changes to the output, which always make me nervous, so I'm not
146
- # doing a wholesale swap just yet. Instead, we'll just do this on M1 hardware.
147
- use_map_location = (device != 'mps')
148
-
149
- if use_map_location:
150
- checkpoint = torch.load(model_pt_path, map_location=device)
151
- else:
152
- checkpoint = torch.load(model_pt_path)
153
-
154
- # Compatibility fix that allows us to load older YOLOv5 models with
155
- # newer versions of YOLOv5/PT
156
- for m in checkpoint['model'].modules():
157
- t = type(m)
158
- if t is torch.nn.Upsample and not hasattr(m, 'recompute_scale_factor'):
159
- m.recompute_scale_factor = None
160
-
161
- if use_map_location:
162
- model = checkpoint['model'].float().fuse().eval()
163
- else:
164
- model = checkpoint['model'].float().fuse().eval().to(device)
165
-
166
- return model
167
-
168
- def generate_detections_one_image(self, img_original, image_id='unknown',
169
- detection_threshold=0.00001, image_size=None,
170
- skip_image_resizing=False):
171
- """
172
- Applies the detector to an image.
173
-
174
- Args:
175
- img_original (Image): the PIL Image object with EXIF rotation taken into account
176
- image_id (str, optional): a path to identify the image; will be in the "file" field
177
- of the output object
178
- detection_threshold (float, optional): only detections above this confidence threshold
179
- will be included in the return value
180
- image_size (tuple, optional): image size to use for inference, only mess with this
181
- if (a) you're using a model other than MegaDetector or (b) you know what you're
182
- doing
183
- skip_image_resizing (bool, optional): whether to skip internal image resizing (and rely on external
184
- resizing)
185
-
186
- Returns:
187
- dict: a dictionary with the following fields:
188
- - 'file' (filename, always present)
189
- - 'max_detection_conf' (removed from MegaDetector output files by default, but generated here)
190
- - 'detections' (a list of detection objects containing keys 'category', 'conf', and 'bbox')
191
- - 'failure' (a failure string, or None if everything went fine)
192
- """
193
-
194
- result = {
195
- 'file': image_id
196
- }
197
- detections = []
198
- max_conf = 0.0
199
-
200
- try:
201
-
202
- img_original = np.asarray(img_original)
203
-
204
- # padded resize
205
- target_size = PTDetector.IMAGE_SIZE
206
-
207
- # Image size can be an int (which translates to a square target size) or (h,w)
208
- if image_size is not None:
209
-
210
- assert isinstance(image_size,int) or (len(image_size)==2)
211
-
212
- if not self.printed_image_size_warning:
213
- print('Warning: using user-supplied image size {}'.format(image_size))
214
- self.printed_image_size_warning = True
215
-
216
- target_size = image_size
217
-
218
- else:
219
-
220
- self.printed_image_size_warning = False
221
-
222
- # ...if the caller has specified an image size
223
-
224
- if skip_image_resizing:
225
- img = img_original
226
- else:
227
- letterbox_result = letterbox(img_original, new_shape=target_size,
228
- stride=PTDetector.STRIDE, auto=True)
229
- img = letterbox_result[0]
230
-
231
- # HWC to CHW; PIL Image is RGB already
232
- img = img.transpose((2, 0, 1))
233
- img = np.ascontiguousarray(img)
234
- img = torch.from_numpy(img)
235
- img = img.to(self.device)
236
- img = img.float()
237
- img /= 255
238
-
239
- # In practice this is always true
240
- if len(img.shape) == 3:
241
- img = torch.unsqueeze(img, 0)
242
-
243
- pred: list = self.model(img)[0]
244
-
245
- # NMS
246
- if self.device == 'mps':
247
- # As of v1.13.0.dev20220824, nms is not implemented for MPS.
248
- #
249
- # Send prediction back to the CPU to fix.
250
- pred = non_max_suppression(prediction=pred.cpu(), conf_thres=detection_threshold)
251
- else:
252
- pred = non_max_suppression(prediction=pred, conf_thres=detection_threshold)
253
-
254
- # format detections/bounding boxes
255
- #
256
- # normalization gain whwh
257
- gn = torch.tensor(img_original.shape)[[1, 0, 1, 0]]
258
-
259
- # This is a loop over detection batches, which will always be length 1 in our case,
260
- # since we're not doing batch inference.
261
- for det in pred:
262
-
263
- if len(det):
264
-
265
- # Rescale boxes from img_size to im0 size
266
- det[:, :4] = scale_coords(img.shape[2:], det[:, :4], img_original.shape).round()
267
-
268
- for *xyxy, conf, cls in reversed(det):
269
-
270
- # normalized center-x, center-y, width and height
271
- xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()
272
-
273
- api_box = ct_utils.convert_yolo_to_xywh(xywh)
274
-
275
- conf = ct_utils.truncate_float(conf.tolist(), precision=CONF_DIGITS)
276
-
277
- if not self.use_model_native_classes:
278
- # MegaDetector output format's categories start at 1, but the MD
279
- # model's categories start at 0.
280
- cls = int(cls.tolist()) + 1
281
- if cls not in (1, 2, 3):
282
- raise KeyError(f'{cls} is not a valid class.')
283
- else:
284
- cls = int(cls.tolist())
285
-
286
- detections.append({
287
- 'category': str(cls),
288
- 'conf': conf,
289
- 'bbox': ct_utils.truncate_float_array(api_box, precision=COORD_DIGITS)
290
- })
291
- max_conf = max(max_conf, conf)
292
-
293
- # ...for each detection in this batch
294
-
295
- # ...if this is a non-empty batch
296
-
297
- # ...for each detection batch
298
-
299
- # ...try
300
-
301
- except Exception as e:
302
-
303
- result['failure'] = FAILURE_INFER
304
- print('PTDetector: image {} failed during inference: {}\n'.format(image_id, str(e)))
305
- traceback.print_exc(e)
306
-
307
- result['max_detection_conf'] = max_conf
308
- result['detections'] = detections
309
-
310
- return result
311
-
312
- # ...def generate_detections_one_image(...)
313
-
314
- # ...class PTDetector
315
-
316
-
317
- #%% Command-line driver
318
-
319
- # For testing only... you don't really want to run this module directly.
320
-
321
- if __name__ == '__main__':
322
-
323
- pass
324
-
325
- #%%
326
-
327
- import md_visualization.visualization_utils as vis_utils
328
- import os
329
-
330
- model_file = 'MDV5A'
331
- im_file = os.path.expanduser('~/git/MegaDetector/images/nacti.jpg')
332
-
333
- detector = PTDetector(model_file)
334
- image = vis_utils.load_image(im_file)
335
-
336
- res = detector.generate_detections_one_image(image, im_file, detection_threshold=0.00001)
337
- print(res)