megadetector 5.0.28__tar.gz → 5.0.29__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.

Potentially problematic release.


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

Files changed (221) hide show
  1. {megadetector-5.0.28 → megadetector-5.0.29}/LICENSE +0 -0
  2. {megadetector-5.0.28/megadetector.egg-info → megadetector-5.0.29}/PKG-INFO +135 -132
  3. {megadetector-5.0.28 → megadetector-5.0.29}/README-package.md +0 -0
  4. {megadetector-5.0.28 → megadetector-5.0.29}/README.md +2 -0
  5. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/__init__.py +0 -0
  6. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/__init__.py +0 -0
  7. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/__init__.py +0 -0
  8. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/batch_service/__init__.py +0 -0
  9. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/batch_service/score.py +4 -5
  10. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/server.py +0 -0
  11. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/server_api_config.py +0 -0
  12. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/server_app_config.py +0 -0
  13. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/server_batch_job_manager.py +0 -0
  14. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/server_job_status_table.py +0 -0
  15. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/server_orchestration.py +0 -0
  16. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core/server_utils.py +0 -0
  17. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core_support/__init__.py +0 -0
  18. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +1 -1
  19. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_support/__init__.py +0 -0
  20. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/api_support/summarize_daily_activity.py +1 -1
  21. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/data_preparation/__init__.py +0 -0
  22. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/integration/digiKam/setup.py +0 -0
  23. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
  24. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/integration/eMammal/test_scripts/config_template.py +0 -0
  25. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
  26. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
  27. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/synchronous/__init__.py +0 -0
  28. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
  29. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/synchronous/api_core/animal_detection_api/api_backend.py +0 -0
  30. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -0
  31. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/synchronous/api_core/animal_detection_api/config.py +0 -0
  32. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/synchronous/api_core/tests/__init__.py +0 -0
  33. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/api/synchronous/api_core/tests/load_test.py +2 -3
  34. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/__init__.py +0 -0
  35. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/aggregate_classifier_probs.py +3 -3
  36. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/analyze_failed_images.py +5 -5
  37. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/cache_batchapi_outputs.py +5 -5
  38. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/create_classification_dataset.py +11 -12
  39. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/crop_detections.py +10 -10
  40. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/csv_to_json.py +8 -8
  41. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/detect_and_crop.py +13 -15
  42. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/efficientnet/__init__.py +0 -0
  43. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/efficientnet/model.py +0 -0
  44. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/efficientnet/utils.py +0 -0
  45. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/evaluate_model.py +7 -7
  46. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/identify_mislabeled_candidates.py +6 -6
  47. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/json_to_azcopy_list.py +1 -1
  48. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/json_validator.py +29 -32
  49. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/map_classification_categories.py +9 -9
  50. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/merge_classification_detection_output.py +12 -9
  51. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/prepare_classification_script.py +19 -19
  52. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/prepare_classification_script_mc.py +23 -23
  53. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/run_classifier.py +4 -4
  54. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/save_mislabeled.py +6 -6
  55. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/train_classifier.py +1 -1
  56. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/train_classifier_tf.py +9 -9
  57. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/classification/train_utils.py +10 -10
  58. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/__init__.py +0 -0
  59. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/annotations/__init__.py +0 -0
  60. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/annotations/annotation_constants.py +1 -1
  61. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/camtrap_dp_to_coco.py +45 -45
  62. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/cct_json_utils.py +101 -101
  63. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/cct_to_md.py +49 -49
  64. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/cct_to_wi.py +33 -33
  65. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/coco_to_labelme.py +75 -75
  66. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/coco_to_yolo.py +189 -189
  67. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/databases/__init__.py +0 -0
  68. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/databases/add_width_and_height_to_db.py +3 -2
  69. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/databases/combine_coco_camera_traps_files.py +38 -38
  70. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/databases/integrity_check_json_db.py +202 -188
  71. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/databases/subset_json_db.py +33 -33
  72. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/generate_crops_from_cct.py +38 -38
  73. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/get_image_sizes.py +54 -49
  74. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/labelme_to_coco.py +130 -124
  75. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/labelme_to_yolo.py +78 -72
  76. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/__init__.py +0 -0
  77. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/create_lila_blank_set.py +81 -83
  78. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/create_lila_test_set.py +32 -31
  79. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
  80. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/download_lila_subset.py +21 -24
  81. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/generate_lila_per_image_labels.py +91 -91
  82. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/get_lila_annotation_counts.py +30 -30
  83. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/get_lila_image_counts.py +22 -22
  84. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/lila_common.py +70 -70
  85. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/lila/test_lila_metadata_urls.py +13 -14
  86. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/mewc_to_md.py +339 -340
  87. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/ocr_tools.py +258 -252
  88. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/read_exif.py +231 -224
  89. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/remap_coco_categories.py +26 -26
  90. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/remove_exif.py +31 -20
  91. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/rename_images.py +187 -187
  92. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/resize_coco_dataset.py +41 -41
  93. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/speciesnet_to_md.py +41 -41
  94. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/wi_download_csv_to_coco.py +55 -55
  95. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/yolo_output_to_md_output.py +117 -120
  96. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/data_management/yolo_to_coco.py +195 -188
  97. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/__init__.py +0 -0
  98. megadetector-5.0.29/megadetector/detection/change_detection.py +831 -0
  99. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/process_video.py +340 -337
  100. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/pytorch_detector.py +304 -262
  101. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/run_detector.py +177 -164
  102. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/run_detector_batch.py +364 -363
  103. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/run_inference_with_yolov5_val.py +328 -325
  104. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/run_tiled_inference.py +256 -249
  105. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/tf_detector.py +24 -24
  106. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/detection/video_utils.py +290 -282
  107. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/__init__.py +0 -0
  108. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/add_max_conf.py +15 -11
  109. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/categorize_detections_by_size.py +44 -44
  110. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/classification_postprocessing.py +415 -415
  111. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/combine_batch_outputs.py +20 -21
  112. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/compare_batch_results.py +528 -517
  113. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/convert_output_format.py +97 -97
  114. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/create_crop_folder.py +219 -146
  115. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/detector_calibration.py +173 -168
  116. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/generate_csv_report.py +508 -499
  117. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/load_api_results.py +23 -20
  118. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/md_to_coco.py +129 -98
  119. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/md_to_labelme.py +89 -83
  120. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/md_to_wi.py +40 -40
  121. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/merge_detections.py +87 -114
  122. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/postprocess_batch_results.py +313 -298
  123. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/remap_detection_categories.py +36 -36
  124. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/render_detection_confusion_matrix.py +205 -199
  125. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
  126. megadetector-5.0.29/megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +82 -0
  127. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +702 -677
  128. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/separate_detections_into_folders.py +226 -211
  129. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/subset_json_detector_output.py +265 -262
  130. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/top_folders_to_bottom.py +45 -45
  131. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/postprocessing/validate_batch_results.py +70 -70
  132. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/__init__.py +0 -0
  133. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
  134. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/map_new_lila_datasets.py +15 -15
  135. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +14 -14
  136. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/preview_lila_taxonomy.py +66 -66
  137. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
  138. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/simple_image_download.py +8 -8
  139. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/species_lookup.py +33 -33
  140. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
  141. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
  142. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
  143. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/__init__.py +0 -0
  144. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/azure_utils.py +22 -22
  145. megadetector-5.0.29/megadetector/utils/ct_utils.py +1750 -0
  146. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/directory_listing.py +21 -77
  147. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/gpu_test.py +22 -22
  148. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/md_tests.py +541 -518
  149. megadetector-5.0.29/megadetector/utils/path_utils.py +2628 -0
  150. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/process_utils.py +41 -41
  151. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/sas_blob_utils.py +53 -49
  152. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/split_locations_into_train_val.py +61 -61
  153. megadetector-5.0.29/megadetector/utils/string_utils.py +213 -0
  154. megadetector-5.0.29/megadetector/utils/url_utils.py +710 -0
  155. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/wi_utils.py +2629 -2526
  156. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/utils/write_html_image_list.py +137 -137
  157. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/visualization/__init__.py +0 -0
  158. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/visualization/plot_utils.py +21 -21
  159. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/visualization/render_images_with_thumbnails.py +37 -73
  160. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/visualization/visualization_utils.py +401 -397
  161. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/visualization/visualize_db.py +197 -190
  162. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector/visualization/visualize_detector_output.py +79 -73
  163. {megadetector-5.0.28 → megadetector-5.0.29/megadetector.egg-info}/PKG-INFO +135 -132
  164. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector.egg-info/SOURCES.txt +1 -47
  165. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector.egg-info/dependency_links.txt +0 -0
  166. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector.egg-info/requires.txt +4 -1
  167. {megadetector-5.0.28 → megadetector-5.0.29}/megadetector.egg-info/top_level.txt +0 -0
  168. {megadetector-5.0.28 → megadetector-5.0.29}/pyproject.toml +163 -86
  169. {megadetector-5.0.28 → megadetector-5.0.29}/setup.cfg +4 -4
  170. megadetector-5.0.28/megadetector/data_management/importers/add_nacti_sizes.py +0 -52
  171. megadetector-5.0.28/megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
  172. megadetector-5.0.28/megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
  173. megadetector-5.0.28/megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
  174. megadetector-5.0.28/megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
  175. megadetector-5.0.28/megadetector/data_management/importers/awc_to_json.py +0 -191
  176. megadetector-5.0.28/megadetector/data_management/importers/bellevue_to_json.py +0 -272
  177. megadetector-5.0.28/megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
  178. megadetector-5.0.28/megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
  179. megadetector-5.0.28/megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
  180. megadetector-5.0.28/megadetector/data_management/importers/cct_field_adjustments.py +0 -58
  181. megadetector-5.0.28/megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
  182. megadetector-5.0.28/megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  183. megadetector-5.0.28/megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
  184. megadetector-5.0.28/megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
  185. megadetector-5.0.28/megadetector/data_management/importers/ena24_to_json.py +0 -276
  186. megadetector-5.0.28/megadetector/data_management/importers/filenames_to_json.py +0 -386
  187. megadetector-5.0.28/megadetector/data_management/importers/helena_to_cct.py +0 -283
  188. megadetector-5.0.28/megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
  189. megadetector-5.0.28/megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  190. megadetector-5.0.28/megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
  191. megadetector-5.0.28/megadetector/data_management/importers/jb_csv_to_json.py +0 -150
  192. megadetector-5.0.28/megadetector/data_management/importers/mcgill_to_json.py +0 -250
  193. megadetector-5.0.28/megadetector/data_management/importers/missouri_to_json.py +0 -490
  194. megadetector-5.0.28/megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
  195. megadetector-5.0.28/megadetector/data_management/importers/noaa_seals_2019.py +0 -181
  196. megadetector-5.0.28/megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
  197. megadetector-5.0.28/megadetector/data_management/importers/pc_to_json.py +0 -365
  198. megadetector-5.0.28/megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
  199. megadetector-5.0.28/megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
  200. megadetector-5.0.28/megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
  201. megadetector-5.0.28/megadetector/data_management/importers/rspb_to_json.py +0 -356
  202. megadetector-5.0.28/megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
  203. megadetector-5.0.28/megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
  204. megadetector-5.0.28/megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
  205. megadetector-5.0.28/megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
  206. megadetector-5.0.28/megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  207. megadetector-5.0.28/megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  208. megadetector-5.0.28/megadetector/data_management/importers/sulross_get_exif.py +0 -65
  209. megadetector-5.0.28/megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
  210. megadetector-5.0.28/megadetector/data_management/importers/ubc_to_json.py +0 -399
  211. megadetector-5.0.28/megadetector/data_management/importers/umn_to_json.py +0 -507
  212. megadetector-5.0.28/megadetector/data_management/importers/wellington_to_json.py +0 -263
  213. megadetector-5.0.28/megadetector/data_management/importers/wi_to_json.py +0 -442
  214. megadetector-5.0.28/megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
  215. megadetector-5.0.28/megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
  216. megadetector-5.0.28/megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
  217. megadetector-5.0.28/megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +0 -83
  218. megadetector-5.0.28/megadetector/utils/ct_utils.py +0 -932
  219. megadetector-5.0.28/megadetector/utils/path_utils.py +0 -1569
  220. megadetector-5.0.28/megadetector/utils/string_utils.py +0 -92
  221. megadetector-5.0.28/megadetector/utils/url_utils.py +0 -420
File without changes
@@ -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.
@@ -269,3 +269,5 @@ Code written on or before April 28, 2023 is [copyright Microsoft](https://github
269
269
  This project welcomes contributions, as pull requests, issues, or suggestions by [email](mailto:cameratraps@lila.science). We have a [list](https://github.com/agentmorris/MegaDetector/issues/84) of issues that we're hoping to address, many of which would be good starting points for new contributors. We also depend on other open-source tools that help users run MegaDetector (particularly [AddaxAI](https://github.com/PetervanLunteren/AddaxAI) (formerly EcoAssist), and open-source tools that help users work with MegaDetector results (particularly [Timelapse](https://github.com/saulgreenberg/Timelapse)). If you are looking to get involved in GUI development, reach out to the developers of those tools as well!
270
270
 
271
271
  If you are interesting in getting involved in the conservation technology space, and MegaDetector just happens to be the first page you landed on, and none of our open issues are getting you fired up, don't fret! Head over to the [WILDLABS discussion forums](https://wildlabs.net/discussions) and let the community know you're a developer looking to get involved. Someone needs your help!
272
+
273
+ Information about the coding conventions, linting, testing, and documentation tools used by this repo are available in [developers.md](developers.md).
@@ -1,6 +1,7 @@
1
1
  import io
2
2
  import json
3
3
  import math
4
+ from megadetector.utils import ct_utils
4
5
  import os
5
6
  import sys
6
7
  from datetime import datetime
@@ -353,7 +354,7 @@ class BatchScorer:
353
354
  return detections
354
355
 
355
356
 
356
- def main():
357
+ def main(): # noqa
357
358
  print('score.py, main()')
358
359
 
359
360
  # information to determine input and output locations
@@ -387,8 +388,7 @@ def main():
387
388
  task_output_path = os.path.join(task_out_dir, f'job_{job_id}_task_{task_id}.json')
388
389
 
389
390
  # test that we can write to output path; also in case there is no image to process
390
- with open(task_output_path, 'w') as f:
391
- json.dump([], f)
391
+ ct_utils.write_json(task_output_path, [])
392
392
 
393
393
  # list images to process
394
394
  list_images_path = os.path.join(job_folder_mounted, f'{job_id}_images.json')
@@ -432,8 +432,7 @@ def main():
432
432
  except Exception as e:
433
433
  raise RuntimeError(f'score.py, main(), exception in score_images(): {e}')
434
434
 
435
- with open(task_output_path, 'w', encoding='utf-8') as f:
436
- json.dump(detections, f, ensure_ascii=False)
435
+ ct_utils.write_json(task_output_path, detections, ensure_ascii=False)
437
436
 
438
437
  if __name__ == '__main__':
439
438
  main()
@@ -22,7 +22,7 @@ import json
22
22
  from api.batch_processing.api_core.orchestrator_api.orchestrator import AMLMonitor
23
23
 
24
24
 
25
- def main():
25
+ def main(): # noqa
26
26
  parser = argparse.ArgumentParser()
27
27
  parser.add_argument('shortened_request_id', type=str,
28
28
  help='the request ID to restart monitoring')
@@ -124,7 +124,7 @@ def send_message():
124
124
  print('')
125
125
 
126
126
 
127
- def main():
127
+ def main(): # noqa
128
128
  """
129
129
  Wake up at 5 minutes past midnight UTC to send a summary of yesterday's activities if there were any.
130
130
  Then goes in a loop to wake up and send a summary every 24 hours.
@@ -17,7 +17,7 @@ import inspect
17
17
  import os
18
18
  import sys
19
19
  import json
20
- import pyexiv2
20
+ import pyexiv2 # type: ignore
21
21
  import ntpath
22
22
  import threading
23
23
  import traceback
@@ -432,7 +432,7 @@ def args_to_object(args,obj):
432
432
  setattr(obj, n, v)
433
433
 
434
434
 
435
- def main():
435
+ def main(): # noqa
436
436
 
437
437
  parser = argparse.ArgumentParser()
438
438
  parser.add_argument('--input_file', help = 'Path to the MegaDetector .json file', default=None)
@@ -51,7 +51,7 @@ def format_data_print_deployments(rows):
51
51
 
52
52
  #%% Command-line driver
53
53
 
54
- def main():
54
+ def main(): # noqa
55
55
 
56
56
  parser = argparse.ArgumentParser()
57
57
  parser.add_argument('input_file', type=str, help='Input .json filename')
@@ -10,7 +10,7 @@ from tqdm import tqdm
10
10
 
11
11
  #%% Main function
12
12
 
13
- def main():
13
+ def main(): # noqa
14
14
 
15
15
  parser = argparse.ArgumentParser()
16
16
  parser.add_argument('input_file', type=str, help='Input .json filename')
@@ -1,4 +1,3 @@
1
-
2
1
  import os
3
2
  import json
4
3
  import io
@@ -47,7 +46,7 @@ def get_detections(response):
47
46
  print(text_result)
48
47
 
49
48
 
50
- def test_load(num_requests, params, max_images=1):
49
+ def load_test(num_requests, params, max_images=1):
51
50
  requests = []
52
51
 
53
52
  # read the images anew for each request
@@ -104,7 +103,7 @@ if __name__ == "__main__":
104
103
  max_images = 1
105
104
 
106
105
  start = datetime.now()
107
- responses = test_load(num_requests, params, max_images=max_images)
106
+ responses = load_test(num_requests, params, max_images=max_images)
108
107
  end = datetime.now()
109
108
  total_time = end - start
110
109
  print('Total time for {} requests: {}'.format(num_requests, total_time))
@@ -44,7 +44,7 @@ def main(classifier_results_csv_path: str,
44
44
  Because the output CSV is often very large, we process it in chunks of 1000
45
45
  rows at a time.
46
46
  """
47
-
47
+
48
48
  chunked_df_iterator = pd.read_csv(
49
49
  classifier_results_csv_path, chunksize=1000, float_precision='high',
50
50
  index_col='path')
@@ -80,7 +80,7 @@ def main(classifier_results_csv_path: str,
80
80
  #%% Command-line driver
81
81
 
82
82
  def _parse_args() -> argparse.Namespace:
83
-
83
+
84
84
  parser = argparse.ArgumentParser(
85
85
  formatter_class=argparse.ArgumentDefaultsHelpFormatter,
86
86
  description='Aggregate classifier probabilities to target classes.')
@@ -100,7 +100,7 @@ def _parse_args() -> argparse.Namespace:
100
100
 
101
101
 
102
102
  if __name__ == '__main__':
103
-
103
+
104
104
  args = _parse_args()
105
105
  main(classifier_results_csv_path=args.classifier_results_csv,
106
106
  target_mapping_json_path=args.target_mapping,
@@ -62,7 +62,7 @@ def check_image_condition(img_path: str,
62
62
  'bad': image exists, but cannot be opened even when setting
63
63
  ImageFile.LOAD_TRUNCATED_IMAGES=True
64
64
  """
65
-
65
+
66
66
  if (account is None) or (container is None) or (datasets_table is not None):
67
67
  assert account is None
68
68
  assert container is None
@@ -133,7 +133,7 @@ def analyze_images(url_or_path: str, json_keys: Optional[Sequence[str]] = None,
133
133
  sas_token: str, optional SAS token (without leading '?') if the
134
134
  container is not publicly accessible
135
135
  """
136
-
136
+
137
137
  datasets_table = None
138
138
  if (account is None) or (container is None):
139
139
  assert account is None
@@ -190,8 +190,8 @@ def analyze_images(url_or_path: str, json_keys: Optional[Sequence[str]] = None,
190
190
 
191
191
  #%% Command-line driver
192
192
 
193
- def _parse_args() -> argparse.Namespace:
194
-
193
+ def _parse_args() -> argparse.Namespace:
194
+
195
195
  parser = argparse.ArgumentParser(
196
196
  description='Analyze a list of images that failed to download or crop.')
197
197
  parser.add_argument(
@@ -220,7 +220,7 @@ def _parse_args() -> argparse.Namespace:
220
220
 
221
221
 
222
222
  if __name__ == '__main__':
223
-
223
+
224
224
  args = _parse_args()
225
225
  analyze_images(url_or_path=args.failed_images, json_keys=args.json_keys,
226
226
  account=args.account, container=args.container,
@@ -66,6 +66,7 @@ from api.batch_processing.data_preparation.prepare_api_submission import (
66
66
  TaskStatus, Task)
67
67
  from api.batch_processing.postprocessing.combine_api_outputs import (
68
68
  combine_api_output_dictionaries)
69
+ from megadetector.utils import ct_utils
69
70
 
70
71
 
71
72
  #%% Support functions
@@ -84,7 +85,7 @@ def cache_json(json_path: str,
84
85
  detector_output_cache_base_dir: str
85
86
  detector_version: str
86
87
  """
87
-
88
+
88
89
  with open(json_path, 'r') as f:
89
90
  js = json.load(f)
90
91
 
@@ -138,7 +139,7 @@ def cache_detections(detections: Mapping[str, Any], dataset: str,
138
139
 
139
140
  Returns: str, message
140
141
  """
141
-
142
+
142
143
  # combine detections with cache
143
144
  dataset_cache_path = os.path.join(
144
145
  detector_output_cache_dir, f'{dataset}.json')
@@ -155,8 +156,7 @@ def cache_detections(detections: Mapping[str, Any], dataset: str,
155
156
  f'{dataset_cache_path}')
156
157
 
157
158
  # write combined detections back out to cache
158
- with open(dataset_cache_path, 'w') as f:
159
- json.dump(merged_dataset_cache, f, indent=1)
159
+ ct_utils.write_json(dataset_cache_path, merged_dataset_cache)
160
160
  return msg
161
161
 
162
162
 
@@ -188,7 +188,7 @@ def _parse_args() -> argparse.Namespace:
188
188
 
189
189
 
190
190
  if __name__ == '__main__':
191
-
191
+
192
192
  args = _parse_args()
193
193
  cache_json(
194
194
  json_path=args.json_file,