megadetector 5.0.28__py3-none-any.whl → 5.0.29__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 (176) hide show
  1. megadetector/api/batch_processing/api_core/batch_service/score.py +4 -5
  2. megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +1 -1
  3. megadetector/api/batch_processing/api_support/summarize_daily_activity.py +1 -1
  4. megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
  5. megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
  6. megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
  7. megadetector/api/synchronous/api_core/tests/load_test.py +2 -3
  8. megadetector/classification/aggregate_classifier_probs.py +3 -3
  9. megadetector/classification/analyze_failed_images.py +5 -5
  10. megadetector/classification/cache_batchapi_outputs.py +5 -5
  11. megadetector/classification/create_classification_dataset.py +11 -12
  12. megadetector/classification/crop_detections.py +10 -10
  13. megadetector/classification/csv_to_json.py +8 -8
  14. megadetector/classification/detect_and_crop.py +13 -15
  15. megadetector/classification/evaluate_model.py +7 -7
  16. megadetector/classification/identify_mislabeled_candidates.py +6 -6
  17. megadetector/classification/json_to_azcopy_list.py +1 -1
  18. megadetector/classification/json_validator.py +29 -32
  19. megadetector/classification/map_classification_categories.py +9 -9
  20. megadetector/classification/merge_classification_detection_output.py +12 -9
  21. megadetector/classification/prepare_classification_script.py +19 -19
  22. megadetector/classification/prepare_classification_script_mc.py +23 -23
  23. megadetector/classification/run_classifier.py +4 -4
  24. megadetector/classification/save_mislabeled.py +6 -6
  25. megadetector/classification/train_classifier.py +1 -1
  26. megadetector/classification/train_classifier_tf.py +9 -9
  27. megadetector/classification/train_utils.py +10 -10
  28. megadetector/data_management/annotations/annotation_constants.py +1 -1
  29. megadetector/data_management/camtrap_dp_to_coco.py +45 -45
  30. megadetector/data_management/cct_json_utils.py +101 -101
  31. megadetector/data_management/cct_to_md.py +49 -49
  32. megadetector/data_management/cct_to_wi.py +33 -33
  33. megadetector/data_management/coco_to_labelme.py +75 -75
  34. megadetector/data_management/coco_to_yolo.py +189 -189
  35. megadetector/data_management/databases/add_width_and_height_to_db.py +3 -2
  36. megadetector/data_management/databases/combine_coco_camera_traps_files.py +38 -38
  37. megadetector/data_management/databases/integrity_check_json_db.py +202 -188
  38. megadetector/data_management/databases/subset_json_db.py +33 -33
  39. megadetector/data_management/generate_crops_from_cct.py +38 -38
  40. megadetector/data_management/get_image_sizes.py +54 -49
  41. megadetector/data_management/labelme_to_coco.py +130 -124
  42. megadetector/data_management/labelme_to_yolo.py +78 -72
  43. megadetector/data_management/lila/create_lila_blank_set.py +81 -83
  44. megadetector/data_management/lila/create_lila_test_set.py +32 -31
  45. megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
  46. megadetector/data_management/lila/download_lila_subset.py +21 -24
  47. megadetector/data_management/lila/generate_lila_per_image_labels.py +91 -91
  48. megadetector/data_management/lila/get_lila_annotation_counts.py +30 -30
  49. megadetector/data_management/lila/get_lila_image_counts.py +22 -22
  50. megadetector/data_management/lila/lila_common.py +70 -70
  51. megadetector/data_management/lila/test_lila_metadata_urls.py +13 -14
  52. megadetector/data_management/mewc_to_md.py +339 -340
  53. megadetector/data_management/ocr_tools.py +258 -252
  54. megadetector/data_management/read_exif.py +231 -224
  55. megadetector/data_management/remap_coco_categories.py +26 -26
  56. megadetector/data_management/remove_exif.py +31 -20
  57. megadetector/data_management/rename_images.py +187 -187
  58. megadetector/data_management/resize_coco_dataset.py +41 -41
  59. megadetector/data_management/speciesnet_to_md.py +41 -41
  60. megadetector/data_management/wi_download_csv_to_coco.py +55 -55
  61. megadetector/data_management/yolo_output_to_md_output.py +117 -120
  62. megadetector/data_management/yolo_to_coco.py +195 -188
  63. megadetector/detection/change_detection.py +831 -0
  64. megadetector/detection/process_video.py +340 -337
  65. megadetector/detection/pytorch_detector.py +304 -262
  66. megadetector/detection/run_detector.py +177 -164
  67. megadetector/detection/run_detector_batch.py +364 -363
  68. megadetector/detection/run_inference_with_yolov5_val.py +328 -325
  69. megadetector/detection/run_tiled_inference.py +256 -249
  70. megadetector/detection/tf_detector.py +24 -24
  71. megadetector/detection/video_utils.py +290 -282
  72. megadetector/postprocessing/add_max_conf.py +15 -11
  73. megadetector/postprocessing/categorize_detections_by_size.py +44 -44
  74. megadetector/postprocessing/classification_postprocessing.py +415 -415
  75. megadetector/postprocessing/combine_batch_outputs.py +20 -21
  76. megadetector/postprocessing/compare_batch_results.py +528 -517
  77. megadetector/postprocessing/convert_output_format.py +97 -97
  78. megadetector/postprocessing/create_crop_folder.py +219 -146
  79. megadetector/postprocessing/detector_calibration.py +173 -168
  80. megadetector/postprocessing/generate_csv_report.py +508 -499
  81. megadetector/postprocessing/load_api_results.py +23 -20
  82. megadetector/postprocessing/md_to_coco.py +129 -98
  83. megadetector/postprocessing/md_to_labelme.py +89 -83
  84. megadetector/postprocessing/md_to_wi.py +40 -40
  85. megadetector/postprocessing/merge_detections.py +87 -114
  86. megadetector/postprocessing/postprocess_batch_results.py +313 -298
  87. megadetector/postprocessing/remap_detection_categories.py +36 -36
  88. megadetector/postprocessing/render_detection_confusion_matrix.py +205 -199
  89. megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
  90. megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +27 -28
  91. megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +702 -677
  92. megadetector/postprocessing/separate_detections_into_folders.py +226 -211
  93. megadetector/postprocessing/subset_json_detector_output.py +265 -262
  94. megadetector/postprocessing/top_folders_to_bottom.py +45 -45
  95. megadetector/postprocessing/validate_batch_results.py +70 -70
  96. megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
  97. megadetector/taxonomy_mapping/map_new_lila_datasets.py +15 -15
  98. megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +14 -14
  99. megadetector/taxonomy_mapping/preview_lila_taxonomy.py +66 -66
  100. megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
  101. megadetector/taxonomy_mapping/simple_image_download.py +8 -8
  102. megadetector/taxonomy_mapping/species_lookup.py +33 -33
  103. megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
  104. megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
  105. megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
  106. megadetector/utils/azure_utils.py +22 -22
  107. megadetector/utils/ct_utils.py +1018 -200
  108. megadetector/utils/directory_listing.py +21 -77
  109. megadetector/utils/gpu_test.py +22 -22
  110. megadetector/utils/md_tests.py +541 -518
  111. megadetector/utils/path_utils.py +1457 -398
  112. megadetector/utils/process_utils.py +41 -41
  113. megadetector/utils/sas_blob_utils.py +53 -49
  114. megadetector/utils/split_locations_into_train_val.py +61 -61
  115. megadetector/utils/string_utils.py +147 -26
  116. megadetector/utils/url_utils.py +463 -173
  117. megadetector/utils/wi_utils.py +2629 -2526
  118. megadetector/utils/write_html_image_list.py +137 -137
  119. megadetector/visualization/plot_utils.py +21 -21
  120. megadetector/visualization/render_images_with_thumbnails.py +37 -73
  121. megadetector/visualization/visualization_utils.py +401 -397
  122. megadetector/visualization/visualize_db.py +197 -190
  123. megadetector/visualization/visualize_detector_output.py +79 -73
  124. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/METADATA +135 -132
  125. megadetector-5.0.29.dist-info/RECORD +163 -0
  126. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/WHEEL +1 -1
  127. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/licenses/LICENSE +0 -0
  128. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/top_level.txt +0 -0
  129. megadetector/data_management/importers/add_nacti_sizes.py +0 -52
  130. megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
  131. megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
  132. megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
  133. megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
  134. megadetector/data_management/importers/awc_to_json.py +0 -191
  135. megadetector/data_management/importers/bellevue_to_json.py +0 -272
  136. megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
  137. megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
  138. megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
  139. megadetector/data_management/importers/cct_field_adjustments.py +0 -58
  140. megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
  141. megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  142. megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
  143. megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
  144. megadetector/data_management/importers/ena24_to_json.py +0 -276
  145. megadetector/data_management/importers/filenames_to_json.py +0 -386
  146. megadetector/data_management/importers/helena_to_cct.py +0 -283
  147. megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
  148. megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  149. megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
  150. megadetector/data_management/importers/jb_csv_to_json.py +0 -150
  151. megadetector/data_management/importers/mcgill_to_json.py +0 -250
  152. megadetector/data_management/importers/missouri_to_json.py +0 -490
  153. megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
  154. megadetector/data_management/importers/noaa_seals_2019.py +0 -181
  155. megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
  156. megadetector/data_management/importers/pc_to_json.py +0 -365
  157. megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
  158. megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
  159. megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
  160. megadetector/data_management/importers/rspb_to_json.py +0 -356
  161. megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
  162. megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
  163. megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
  164. megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
  165. megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  166. megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  167. megadetector/data_management/importers/sulross_get_exif.py +0 -65
  168. megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
  169. megadetector/data_management/importers/ubc_to_json.py +0 -399
  170. megadetector/data_management/importers/umn_to_json.py +0 -507
  171. megadetector/data_management/importers/wellington_to_json.py +0 -263
  172. megadetector/data_management/importers/wi_to_json.py +0 -442
  173. megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
  174. megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
  175. megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
  176. megadetector-5.0.28.dist-info/RECORD +0 -209
@@ -54,11 +54,11 @@ def _render_image(entry,
54
54
  """
55
55
  Internal function for rendering a single image.
56
56
  """
57
-
57
+
58
58
  rendering_result = {'failed_image':False,'missing_image':False,
59
59
  'skipped_image':False,'annotated_image_path':None,
60
60
  'max_conf':None,'file':entry['file']}
61
-
61
+
62
62
  image_id = entry['file']
63
63
 
64
64
  if 'failure' in entry and entry['failure'] is not None:
@@ -66,14 +66,14 @@ def _render_image(entry,
66
66
  return rendering_result
67
67
 
68
68
  assert 'detections' in entry and entry['detections'] is not None
69
-
69
+
70
70
  max_conf = get_max_conf(entry)
71
71
  rendering_result['max_conf'] = max_conf
72
-
72
+
73
73
  if (max_conf < confidence_threshold) and render_detections_only:
74
74
  rendering_result['skipped_image'] = True
75
75
  return rendering_result
76
-
76
+
77
77
  if images_dir is None:
78
78
  image_filename_in_abs = image_id
79
79
  assert path_is_abs(image_filename_in_abs), \
@@ -89,7 +89,7 @@ def _render_image(entry,
89
89
 
90
90
  # Load the image
91
91
  image = vis_utils.open_image(image_filename_in_abs)
92
-
92
+
93
93
  # Find categories we're supposed to blur
94
94
  category_ids_to_blur = []
95
95
  if category_names_to_blur is not None:
@@ -98,21 +98,21 @@ def _render_image(entry,
98
98
  for category_id in detector_label_map:
99
99
  if detector_label_map[category_id] in category_names_to_blur:
100
100
  category_ids_to_blur.append(category_id)
101
-
101
+
102
102
  detections_to_blur = []
103
103
  for d in entry['detections']:
104
104
  if d['conf'] >= confidence_threshold and d['category'] in category_ids_to_blur:
105
105
  detections_to_blur.append(d)
106
106
  if len(detections_to_blur) > 0:
107
107
  blur_detections(image,detections_to_blur)
108
-
108
+
109
109
  # Resize if necessary
110
110
  #
111
111
  # If output_image_width is -1 or None, this will just return the original image
112
112
  image = vis_utils.resize_image(image, output_image_width)
113
113
 
114
114
  vis_utils.render_detection_bounding_boxes(
115
- entry['detections'], image,
115
+ entry['detections'], image,
116
116
  label_map=detector_label_map,
117
117
  classification_label_map=classification_label_map,
118
118
  confidence_threshold=confidence_threshold,
@@ -127,9 +127,9 @@ def _render_image(entry,
127
127
  assert not os.path.isabs(image_id), "Can't preserve paths when operating on absolute paths"
128
128
  annotated_img_path = os.path.join(out_dir, image_id)
129
129
  os.makedirs(os.path.dirname(annotated_img_path),exist_ok=True)
130
-
130
+
131
131
  image.save(annotated_img_path)
132
- rendering_result['annotated_image_path'] = annotated_img_path
132
+ rendering_result['annotated_image_path'] = annotated_img_path
133
133
 
134
134
  return rendering_result
135
135
 
@@ -155,14 +155,13 @@ def visualize_detector_output(detector_output_path,
155
155
  parallelize_rendering_with_threads=True,
156
156
  box_sort_order=None,
157
157
  category_names_to_blur=None):
158
-
159
158
  """
160
159
  Draws bounding boxes on images given the output of a detector.
161
160
 
162
161
  Args:
163
162
  detector_output_path (str): path to detector output .json file
164
163
  out_dir (str): path to directory for saving annotated images
165
- images_dir (str): folder where the images live; filenames in
164
+ images_dir (str): folder where the images live; filenames in
166
165
  [detector_output_path] should be relative to [image_dir]. Can be None if paths are
167
166
  absolute.
168
167
  confidence_threshold (float, optional): threshold above which detections will be rendered
@@ -178,17 +177,17 @@ def visualize_detector_output(detector_output_path,
178
177
  classification labels (not detection categories) are displayed
179
178
  html_output_file (str, optional): output path for an HTML index file (not written
180
179
  if None)
181
- html_output_options (dict, optional): HTML formatting options; see write_html_image_list
182
- for details. The most common option you may want to supply here is
180
+ html_output_options (dict, optional): HTML formatting options; see write_html_image_list
181
+ for details. The most common option you may want to supply here is
183
182
  'maxFiguresPerHtmlFile'.
184
183
  preserve_path_structure (bool, optional): if False (default), writes images to unique
185
184
  names in a flat structure in the output folder; if True, preserves relative paths
186
185
  within the output folder
187
186
  parallelize_rendering (bool, optional): whether to use concurrent workers for rendering
188
- parallelize_rendering_n_cores (int, optional): number of concurrent workers to use
187
+ parallelize_rendering_n_cores (int, optional): number of concurrent workers to use
189
188
  (ignored if parallelize_rendering is False)
190
189
  parallelize_rendering_with_threads (bool, optional): determines whether we use
191
- threads (True) or processes (False) for parallelization (ignored if parallelize_rendering
190
+ threads (True) or processes (False) for parallelization (ignored if parallelize_rendering
192
191
  is False)
193
192
  box_sort_order (str, optional): sorting scheme for detection boxes, can be None, "confidence", or
194
193
  "reverse_confidence"
@@ -198,11 +197,11 @@ def visualize_detector_output(detector_output_path,
198
197
  Returns:
199
198
  list: list of paths to annotated images
200
199
  """
201
-
200
+
202
201
  assert os.path.exists(detector_output_path), \
203
202
  'Detector output file does not exist at {}'.format(detector_output_path)
204
203
 
205
- if images_dir is not None:
204
+ if images_dir is not None:
206
205
  assert os.path.isdir(images_dir), \
207
206
  'Image folder {} is not available'.format(images_dir)
208
207
 
@@ -212,15 +211,15 @@ def visualize_detector_output(detector_output_path,
212
211
  ##%% Load detector output
213
212
 
214
213
  detector_output = load_md_or_speciesnet_file(detector_output_path)
215
-
214
+
216
215
  images = detector_output['images']
217
-
216
+
218
217
  if confidence_threshold is None:
219
218
  confidence_threshold = get_typical_confidence_threshold_from_results(detector_output)
220
-
219
+
221
220
  assert confidence_threshold >= 0 and confidence_threshold <= 1, \
222
221
  f'Confidence threshold {confidence_threshold} is invalid, must be in (0, 1).'
223
-
222
+
224
223
  if 'detection_categories' in detector_output:
225
224
  detector_label_map = detector_output['detection_categories']
226
225
  else:
@@ -244,77 +243,84 @@ def visualize_detector_output(detector_output_path,
244
243
 
245
244
  print('Rendering detections above a confidence threshold of {}'.format(
246
245
  confidence_threshold))
247
-
246
+
248
247
  classification_label_map = None
249
-
248
+
250
249
  if 'classification_categories' in detector_output:
251
250
  classification_label_map = detector_output['classification_categories']
252
-
251
+
253
252
  rendering_results = []
254
-
253
+
255
254
  if parallelize_rendering:
256
-
255
+
257
256
  if parallelize_rendering_with_threads:
258
257
  worker_string = 'threads'
259
258
  else:
260
259
  worker_string = 'processes'
261
-
262
- if parallelize_rendering_n_cores is None:
263
- if parallelize_rendering_with_threads:
264
- pool = ThreadPool()
265
- else:
266
- pool = Pool()
267
- else:
268
- if parallelize_rendering_with_threads:
269
- pool = ThreadPool(parallelize_rendering_n_cores)
260
+
261
+ pool = None
262
+ try:
263
+ if parallelize_rendering_n_cores is None:
264
+ if parallelize_rendering_with_threads:
265
+ pool = ThreadPool()
266
+ else:
267
+ pool = Pool()
270
268
  else:
271
- pool = Pool(parallelize_rendering_n_cores)
272
- print('Rendering images with {} {}'.format(parallelize_rendering_n_cores,
273
- worker_string))
274
- rendering_results = list(tqdm(pool.imap(
275
- partial(_render_image,detector_label_map=detector_label_map,
276
- classification_label_map=classification_label_map,
277
- confidence_threshold=confidence_threshold,
278
- classification_confidence_threshold=classification_confidence_threshold,
279
- render_detections_only=render_detections_only,
280
- preserve_path_structure=preserve_path_structure,
281
- out_dir=out_dir,
282
- images_dir=images_dir,
283
- output_image_width=output_image_width,
284
- box_sort_order=box_sort_order,
285
- category_names_to_blur=category_names_to_blur),
286
- images), total=len(images)))
287
-
269
+ if parallelize_rendering_with_threads:
270
+ pool = ThreadPool(parallelize_rendering_n_cores)
271
+ else:
272
+ pool = Pool(parallelize_rendering_n_cores)
273
+ print('Rendering images with {} {}'.format(parallelize_rendering_n_cores,
274
+ worker_string))
275
+ rendering_results = list(tqdm(pool.imap(
276
+ partial(_render_image,detector_label_map=detector_label_map,
277
+ classification_label_map=classification_label_map,
278
+ confidence_threshold=confidence_threshold,
279
+ classification_confidence_threshold=classification_confidence_threshold,
280
+ render_detections_only=render_detections_only,
281
+ preserve_path_structure=preserve_path_structure,
282
+ out_dir=out_dir,
283
+ images_dir=images_dir,
284
+ output_image_width=output_image_width,
285
+ box_sort_order=box_sort_order,
286
+ category_names_to_blur=category_names_to_blur),
287
+ images), total=len(images)))
288
+ finally:
289
+ if pool is not None:
290
+ pool.close()
291
+ pool.join()
292
+ print("Pool closed and joined for detector output visualization")
293
+
288
294
  else:
289
-
295
+
290
296
  for entry in tqdm(images):
291
-
297
+
292
298
  rendering_result = _render_image(entry,detector_label_map,classification_label_map,
293
299
  confidence_threshold,classification_confidence_threshold,
294
300
  render_detections_only,preserve_path_structure,out_dir,
295
301
  images_dir,output_image_width,box_sort_order,
296
302
  category_names_to_blur=category_names_to_blur)
297
303
  rendering_results.append(rendering_result)
298
-
304
+
299
305
  # ...for each image
300
-
306
+
301
307
  failed_images = [r for r in rendering_results if r['failed_image']]
302
308
  missing_images = [r for r in rendering_results if r['missing_image']]
303
309
  skipped_images = [r for r in rendering_results if r['skipped_image']]
304
-
310
+
305
311
  print('Skipped {} failed images (of {})'.format(len(failed_images),len(images)))
306
312
  print('Skipped {} missing images (of {})'.format(len(missing_images),len(images)))
307
313
  print('Skipped {} below-threshold images (of {})'.format(len(skipped_images),len(images)))
308
-
314
+
309
315
  print(f'Rendered detection results to {out_dir}')
310
316
 
311
317
  annotated_image_paths = [r['annotated_image_path'] for r in rendering_results if \
312
318
  r['annotated_image_path'] is not None]
313
-
319
+
314
320
  if html_output_file is not None:
315
-
321
+
316
322
  html_dir = os.path.dirname(html_output_file)
317
-
323
+
318
324
  html_image_info = []
319
325
 
320
326
  for r in rendering_results:
@@ -329,10 +335,10 @@ def visualize_detector_output(detector_output_path,
329
335
  'text-align:left;margin-top:20;margin-bottom:5'
330
336
  d['title'] = '{} (max conf: {})'.format(r['file'],r['max_conf'])
331
337
  html_image_info.append(d)
332
-
338
+
333
339
  _ = write_html_image_list.write_html_image_list(html_output_file,html_image_info,
334
340
  options=html_output_options)
335
-
341
+
336
342
  return annotated_image_paths
337
343
 
338
344
  # ...def visualize_detector_output(...)
@@ -340,8 +346,8 @@ def visualize_detector_output(detector_output_path,
340
346
 
341
347
  #%% Command-line driver
342
348
 
343
- def main():
344
-
349
+ def main(): # noqa
350
+
345
351
  parser = argparse.ArgumentParser(
346
352
  formatter_class=argparse.ArgumentDefaultsHelpFormatter,
347
353
  description='Annotate the bounding boxes predicted by a detector above '
@@ -399,11 +405,11 @@ def main():
399
405
  parser.exit()
400
406
 
401
407
  args = parser.parse_args()
402
-
408
+
403
409
  category_names_to_blur = args.category_names_to_blur
404
410
  if category_names_to_blur is not None:
405
411
  category_names_to_blur = category_names_to_blur.split(',')
406
-
412
+
407
413
  visualize_detector_output(
408
414
  detector_output_path=args.detector_output_path,
409
415
  out_dir=args.out_dir,
@@ -429,12 +435,12 @@ if __name__ == '__main__':
429
435
  #%% Interactive driver
430
436
 
431
437
  if False:
432
-
438
+
433
439
  pass
434
440
 
435
441
  #%%
436
-
437
- detector_output_path = os.path.expanduser('~/postprocessing/bellevue-camera-traps/bellevue-camera-traps-2023-12-05-v5a.0.0/combined_api_outputs/bellevue-camera-traps-2023-12-05-v5a.0.0_detections.json')
442
+
443
+ detector_output_path = os.path.expanduser('detections.json')
438
444
  out_dir = r'g:\temp\preview'
439
445
  images_dir = r'g:\camera_traps\camera_trap_images'
440
446
  confidence_threshold = 0.15
@@ -465,6 +471,6 @@ if False:
465
471
  parallelize_rendering,
466
472
  parallelize_rendering_n_cores,
467
473
  parallelize_rendering_with_threads)
468
-
474
+
469
475
  from megadetector.utils.path_utils import open_file
470
476
  open_file(html_output_file)
@@ -1,132 +1,135 @@
1
- Metadata-Version: 2.4
2
- Name: megadetector
3
- Version: 5.0.28
4
- Summary: MegaDetector is an AI model that helps conservation folks spend less time doing boring things with camera trap images.
5
- Author-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
6
- Maintainer-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
7
- License: MIT License
8
-
9
- Permission is hereby granted, free of charge, to any person obtaining a copy
10
- of this software and associated documentation files (the "Software"), to deal
11
- in the Software without restriction, including without limitation the rights
12
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
- copies of the Software, and to permit persons to whom the Software is
14
- furnished to do so, subject to the following conditions:
15
-
16
- The above copyright notice and this permission notice shall be included in all
17
- copies or substantial portions of the Software.
18
-
19
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
- SOFTWARE.
26
-
27
- Project-URL: Homepage, https://github.com/agentmorris/MegaDetector
28
- Project-URL: Documentation, https://megadetector.readthedocs.io
29
- Project-URL: Bug Reports, https://github.com/agentmorris/MegaDetector/issues
30
- Project-URL: Source, https://github.com/agentmorris/MegaDetector
31
- Keywords: camera traps,conservation,wildlife,ai,megadetector
32
- Classifier: Programming Language :: Python :: 3
33
- Requires-Python: <3.14,>=3.9
34
- Description-Content-Type: text/markdown
35
- License-File: LICENSE
36
- Requires-Dist: mkl==2024.0; sys_platform != "darwin"
37
- Requires-Dist: numpy>=1.26.4
38
- Requires-Dist: Pillow>=9.5
39
- Requires-Dist: tqdm>=4.64.0
40
- Requires-Dist: jsonpickle>=3.0.2
41
- Requires-Dist: humanfriendly>=10.0
42
- Requires-Dist: matplotlib>=3.8.0
43
- Requires-Dist: opencv-python>=4.8.0
44
- Requires-Dist: requests>=2.31.0
45
- Requires-Dist: pyqtree>=1.0.0
46
- Requires-Dist: scikit-learn>=1.3.1
47
- Requires-Dist: pandas>=2.1.1
48
- Requires-Dist: python-dateutil
49
- Requires-Dist: send2trash
50
- Requires-Dist: dill
51
- Requires-Dist: ultralytics-yolov5==0.1.1
52
- Requires-Dist: yolov9pip==0.0.4
53
- Requires-Dist: python-dateutil
54
- Dynamic: license-file
55
-
56
- # MegaDetector
57
-
58
- This package is a pip-installable version of the support/inference code for [MegaDetector](https://github.com/agentmorris/MegaDetector/?tab=readme-ov-file#megadetector), an object detection model that helps conservation biologists spend less time doing boring things with camera trap images. Complete documentation for this Python package is available at [megadetector.readthedocs.io](https://megadetector.readthedocs.io).
59
-
60
- If you aren't looking for the Python package specifically, and you just want to learn more about what MegaDetector is all about, head over to the [MegaDetector repo](https://github.com/agentmorris/MegaDetector/?tab=readme-ov-file#megadetector).
61
-
62
- If you don't want to run MegaDetector, and you just want to use the utilities in this package - postprocessing, manipulating large volumes of camera trap images, etc. - you may want to check out the [megadetector-utils](https://pypi.org/project/megadetector-utils/) package, which is identical to this one, but excludes all of the PyTorch/YOLO dependencies, and is thus approximately one zillion times smaller.
63
-
64
- ## Installation
65
-
66
- Install with:
67
-
68
- `pip install megadetector`
69
-
70
- MegaDetector model weights aren't downloaded at the time you install the package, but they will be (optionally) automatically downloaded the first time you run the model.
71
-
72
- ## Package reference
73
-
74
- See [megadetector.readthedocs.io](https://megadetector.readthedocs.io).
75
-
76
-
77
- ## Examples of things you can do with this package
78
-
79
- ### Run MegaDetector on one image and count the number of detections
80
-
81
- ```
82
- from megadetector.utils import url_utils
83
- from megadetector.visualization import visualization_utils as vis_utils
84
- from megadetector.detection import run_detector
85
-
86
- # This is the image at the bottom of this page, it has one animal in it
87
- image_url = 'https://github.com/agentmorris/MegaDetector/raw/main/images/orinoquia-thumb-web.jpg'
88
- temporary_filename = url_utils.download_url(image_url)
89
-
90
- image = vis_utils.load_image(temporary_filename)
91
-
92
- # This will automatically download MDv5a; you can also specify a filename.
93
- model = run_detector.load_detector('MDV5A')
94
-
95
- result = model.generate_detections_one_image(image)
96
-
97
- detections_above_threshold = [d for d in result['detections'] if d['conf'] > 0.2]
98
- print('Found {} detections above threshold'.format(len(detections_above_threshold)))
99
- ```
100
-
101
- ### Run MegaDetector on a folder of images
102
-
103
- ```
104
- from megadetector.detection.run_detector_batch import \
105
- load_and_run_detector_batch, write_results_to_file
106
- from megadetector.utils import path_utils
107
- import os
108
-
109
- # Pick a folder to run MD on recursively, and an output file
110
- image_folder = os.path.expanduser('~/megadetector_test_images')
111
- output_file = os.path.expanduser('~/megadetector_output_test.json')
112
-
113
- # Recursively find images
114
- image_file_names = path_utils.find_images(image_folder,recursive=True)
115
-
116
- # This will automatically download MDv5a; you can also specify a filename.
117
- results = load_and_run_detector_batch('MDV5A', image_file_names)
118
-
119
- # Write results to a format that Timelapse and other downstream tools like.
120
- write_results_to_file(results,
121
- output_file,
122
- relative_path_base=image_folder,
123
- detector_file=detector_filename)
124
- ```
125
-
126
- ## Contact
127
-
128
- Contact <a href="cameratraps@lila.science">cameratraps@lila.science</a> with questions.
129
-
130
- ## Gratuitous animal picture
131
-
132
- <img src="https://github.com/agentmorris/MegaDetector/raw/main/images/orinoquia-thumb-web_detections.jpg"><br/>Image credit University of Minnesota, from the [Orinoquía Camera Traps](http://lila.science/datasets/orinoquia-camera-traps/) data set.
1
+ Metadata-Version: 2.4
2
+ Name: megadetector
3
+ Version: 5.0.29
4
+ Summary: MegaDetector is an AI model that helps conservation folks spend less time doing boring things with camera trap images.
5
+ Author-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
6
+ Maintainer-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
7
+ License: MIT License
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Project-URL: Homepage, https://github.com/agentmorris/MegaDetector
28
+ Project-URL: Documentation, https://megadetector.readthedocs.io
29
+ Project-URL: Bug Reports, https://github.com/agentmorris/MegaDetector/issues
30
+ Project-URL: Source, https://github.com/agentmorris/MegaDetector
31
+ Keywords: camera traps,conservation,wildlife,ai,megadetector
32
+ Classifier: Programming Language :: Python :: 3
33
+ Requires-Python: <3.14,>=3.9
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: mkl==2024.0; sys_platform != "darwin"
37
+ Requires-Dist: numpy>=1.26.4
38
+ Requires-Dist: Pillow>=9.5
39
+ Requires-Dist: tqdm>=4.64.0
40
+ Requires-Dist: jsonpickle>=3.0.2
41
+ Requires-Dist: humanfriendly>=10.0
42
+ Requires-Dist: matplotlib>=3.8.0
43
+ Requires-Dist: opencv-python>=4.8.0
44
+ Requires-Dist: requests>=2.31.0
45
+ Requires-Dist: pyqtree>=1.0.0
46
+ Requires-Dist: scikit-learn>=1.3.1
47
+ Requires-Dist: pandas>=2.1.1
48
+ Requires-Dist: python-dateutil
49
+ Requires-Dist: send2trash
50
+ Requires-Dist: python-dateutil
51
+ Requires-Dist: clipboard
52
+ Requires-Dist: dill
53
+ Requires-Dist: ruff
54
+ Requires-Dist: pytest
55
+ Requires-Dist: ultralytics-yolov5==0.1.1
56
+ Requires-Dist: yolov9pip==0.0.4
57
+ Dynamic: license-file
58
+
59
+ # MegaDetector
60
+
61
+ This package is a pip-installable version of the support/inference code for [MegaDetector](https://github.com/agentmorris/MegaDetector/?tab=readme-ov-file#megadetector), an object detection model that helps conservation biologists spend less time doing boring things with camera trap images. Complete documentation for this Python package is available at [megadetector.readthedocs.io](https://megadetector.readthedocs.io).
62
+
63
+ If you aren't looking for the Python package specifically, and you just want to learn more about what MegaDetector is all about, head over to the [MegaDetector repo](https://github.com/agentmorris/MegaDetector/?tab=readme-ov-file#megadetector).
64
+
65
+ If you don't want to run MegaDetector, and you just want to use the utilities in this package - postprocessing, manipulating large volumes of camera trap images, etc. - you may want to check out the [megadetector-utils](https://pypi.org/project/megadetector-utils/) package, which is identical to this one, but excludes all of the PyTorch/YOLO dependencies, and is thus approximately one zillion times smaller.
66
+
67
+ ## Installation
68
+
69
+ Install with:
70
+
71
+ `pip install megadetector`
72
+
73
+ MegaDetector model weights aren't downloaded at the time you install the package, but they will be (optionally) automatically downloaded the first time you run the model.
74
+
75
+ ## Package reference
76
+
77
+ See [megadetector.readthedocs.io](https://megadetector.readthedocs.io).
78
+
79
+
80
+ ## Examples of things you can do with this package
81
+
82
+ ### Run MegaDetector on one image and count the number of detections
83
+
84
+ ```
85
+ from megadetector.utils import url_utils
86
+ from megadetector.visualization import visualization_utils as vis_utils
87
+ from megadetector.detection import run_detector
88
+
89
+ # This is the image at the bottom of this page, it has one animal in it
90
+ image_url = 'https://github.com/agentmorris/MegaDetector/raw/main/images/orinoquia-thumb-web.jpg'
91
+ temporary_filename = url_utils.download_url(image_url)
92
+
93
+ image = vis_utils.load_image(temporary_filename)
94
+
95
+ # This will automatically download MDv5a; you can also specify a filename.
96
+ model = run_detector.load_detector('MDV5A')
97
+
98
+ result = model.generate_detections_one_image(image)
99
+
100
+ detections_above_threshold = [d for d in result['detections'] if d['conf'] > 0.2]
101
+ print('Found {} detections above threshold'.format(len(detections_above_threshold)))
102
+ ```
103
+
104
+ ### Run MegaDetector on a folder of images
105
+
106
+ ```
107
+ from megadetector.detection.run_detector_batch import \
108
+ load_and_run_detector_batch, write_results_to_file
109
+ from megadetector.utils import path_utils
110
+ import os
111
+
112
+ # Pick a folder to run MD on recursively, and an output file
113
+ image_folder = os.path.expanduser('~/megadetector_test_images')
114
+ output_file = os.path.expanduser('~/megadetector_output_test.json')
115
+
116
+ # Recursively find images
117
+ image_file_names = path_utils.find_images(image_folder,recursive=True)
118
+
119
+ # This will automatically download MDv5a; you can also specify a filename.
120
+ results = load_and_run_detector_batch('MDV5A', image_file_names)
121
+
122
+ # Write results to a format that Timelapse and other downstream tools like.
123
+ write_results_to_file(results,
124
+ output_file,
125
+ relative_path_base=image_folder,
126
+ detector_file=detector_filename)
127
+ ```
128
+
129
+ ## Contact
130
+
131
+ Contact <a href="cameratraps@lila.science">cameratraps@lila.science</a> with questions.
132
+
133
+ ## Gratuitous animal picture
134
+
135
+ <img src="https://github.com/agentmorris/MegaDetector/raw/main/images/orinoquia-thumb-web_detections.jpg"><br/>Image credit University of Minnesota, from the [Orinoquía Camera Traps](http://lila.science/datasets/orinoquia-camera-traps/) data set.