megadetector 5.0.19__tar.gz → 5.0.20__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.
- {megadetector-5.0.19/megadetector.egg-info → megadetector-5.0.20}/PKG-INFO +2 -2
- {megadetector-5.0.19 → megadetector-5.0.20}/README.md +3 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/bellevue_to_json.py +0 -1
- megadetector-5.0.20/megadetector/data_management/importers/osu-small-animals-to-json.py +364 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/generate_lila_per_image_labels.py +1 -1
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/get_lila_annotation_counts.py +2 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/lila_common.py +28 -12
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/test_lila_metadata_urls.py +17 -8
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/read_exif.py +73 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/process_video.py +84 -16
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/run_detector.py +36 -13
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/run_detector_batch.py +104 -15
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/run_inference_with_yolov5_val.py +20 -23
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/video_utils.py +60 -37
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/map_new_lila_datasets.py +8 -3
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +3 -2
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/preview_lila_taxonomy.py +3 -1
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/ct_utils.py +20 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/md_tests.py +50 -6
- {megadetector-5.0.19 → megadetector-5.0.20/megadetector.egg-info}/PKG-INFO +2 -2
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector.egg-info/SOURCES.txt +1 -1
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector.egg-info/requires.txt +1 -1
- {megadetector-5.0.19 → megadetector-5.0.20}/pyproject.toml +2 -2
- megadetector-5.0.19/megadetector/data_management/importers/snapshot_safari_importer_reprise.py +0 -677
- {megadetector-5.0.19 → megadetector-5.0.20}/LICENSE +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/README-package.md +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/batch_service/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/batch_service/score.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/server.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/server_api_config.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/server_app_config.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/server_batch_job_manager.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/server_job_status_table.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/server_orchestration.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core/server_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core_support/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_support/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/api_support/summarize_daily_activity.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/data_preparation/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/integration/digiKam/setup.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/integration/eMammal/test_scripts/config_template.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/synchronous/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/synchronous/api_core/animal_detection_api/api_backend.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/synchronous/api_core/animal_detection_api/config.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/synchronous/api_core/tests/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/api/synchronous/api_core/tests/load_test.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/aggregate_classifier_probs.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/analyze_failed_images.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/cache_batchapi_outputs.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/create_classification_dataset.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/crop_detections.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/csv_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/detect_and_crop.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/efficientnet/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/efficientnet/model.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/efficientnet/utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/evaluate_model.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/identify_mislabeled_candidates.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/json_to_azcopy_list.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/json_validator.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/map_classification_categories.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/merge_classification_detection_output.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/prepare_classification_script.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/prepare_classification_script_mc.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/run_classifier.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/save_mislabeled.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/train_classifier.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/train_classifier_tf.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/classification/train_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/annotations/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/annotations/annotation_constants.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/camtrap_dp_to_coco.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/cct_json_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/cct_to_md.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/cct_to_wi.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/coco_to_labelme.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/coco_to_yolo.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/databases/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/databases/add_width_and_height_to_db.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/databases/combine_coco_camera_traps_files.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/databases/integrity_check_json_db.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/databases/subset_json_db.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/generate_crops_from_cct.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/get_image_sizes.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/add_nacti_sizes.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/add_timestamps_to_icct.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/animl_results_to_md_results.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/auckland_doc_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/awc_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/cacophony-thermal-importer.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/cct_field_adjustments.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/channel_islands_to_cct.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/ena24_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/filenames_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/helena_to_cct.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/idaho-camera-traps.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/jb_csv_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/mcgill_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/missouri_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/noaa_seals_2019.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/pc_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/plot_wni_giraffes.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/prepare-noaa-fish-data-for-lila.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/prepare_zsl_imerit.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/rspb_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/snapshot_safari_importer.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/sulross_get_exif.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/ubc_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/umn_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/wellington_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/wi_to_json.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/importers/zamba_results_to_md_results.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/labelme_to_coco.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/labelme_to_yolo.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/add_locations_to_nacti.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/create_lila_blank_set.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/create_lila_test_set.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/create_links_to_md_results_files.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/download_lila_subset.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/get_lila_image_counts.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/ocr_tools.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/remap_coco_categories.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/remove_exif.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/rename_images.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/resize_coco_dataset.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/wi_download_csv_to_coco.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/yolo_output_to_md_output.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/yolo_to_coco.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/detector_training/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/detector_training/model_main_tf2.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/pytorch_detector.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/run_tiled_inference.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/detection/tf_detector.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/add_max_conf.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/categorize_detections_by_size.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/classification_postprocessing.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/combine_api_outputs.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/compare_batch_results.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/convert_output_format.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/load_api_results.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/md_to_coco.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/md_to_labelme.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/merge_detections.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/postprocess_batch_results.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/remap_detection_categories.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/render_detection_confusion_matrix.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/separate_detections_into_folders.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/subset_json_detector_output.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/top_folders_to_bottom.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/postprocessing/validate_batch_results.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/retrieve_sample_image.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/simple_image_download.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/species_lookup.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/taxonomy_csv_checker.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/taxonomy_graph.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/taxonomy_mapping/validate_lila_category_mappings.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/azure_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/directory_listing.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/path_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/process_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/sas_blob_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/split_locations_into_train_val.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/string_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/torch_test.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/url_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/utils/write_html_image_list.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/visualization/__init__.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/visualization/plot_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/visualization/render_images_with_thumbnails.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/visualization/visualization_utils.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/visualization/visualize_db.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector/visualization/visualize_detector_output.py +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector.egg-info/dependency_links.txt +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/megadetector.egg-info/top_level.txt +0 -0
- {megadetector-5.0.19 → megadetector-5.0.20}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: megadetector
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.20
|
|
4
4
|
Summary: MegaDetector is an AI model that helps conservation folks spend less time doing boring things with camera trap images.
|
|
5
5
|
Author-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
|
|
6
6
|
Maintainer-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
|
|
@@ -39,7 +39,7 @@ Requires-Dist: Pillow>=9.5
|
|
|
39
39
|
Requires-Dist: tqdm>=4.64.0
|
|
40
40
|
Requires-Dist: jsonpickle>=3.0.2
|
|
41
41
|
Requires-Dist: humanfriendly>=10.0
|
|
42
|
-
Requires-Dist: numpy
|
|
42
|
+
Requires-Dist: numpy<1.24,>=1.22
|
|
43
43
|
Requires-Dist: matplotlib>=3.8.0
|
|
44
44
|
Requires-Dist: opencv-python>=4.8.0
|
|
45
45
|
Requires-Dist: requests>=2.31.0
|
|
@@ -68,6 +68,8 @@ Here are a few of the organizations that have used MegaDetector... we're only li
|
|
|
68
68
|
* [New Zealand Department of Conservation](https://www.doc.govt.nz)
|
|
69
69
|
* [Habitat NZ](https://habitatnz.co.nz/)
|
|
70
70
|
* [Research Institute of Organic Agriculture](https://www.fibl.org/en/) (FiBL)
|
|
71
|
+
* [A/Vian Ecological Consulting](https://avianeco.com/)
|
|
72
|
+
* [Wildlife Insights](https://www.wildlifeinsights.org/)
|
|
71
73
|
|
|
72
74
|
* [Applied Conservation Macro Ecology Lab](http://www.acmelab.ca/), University of Victoria
|
|
73
75
|
* [Banff National Park Resource Conservation](https://www.pc.gc.ca/en/pn-np/ab/banff/nature/conservation), Parks Canada
|
|
@@ -96,6 +98,7 @@ Here are a few of the organizations that have used MegaDetector... we're only li
|
|
|
96
98
|
* [Northern Great Plains Program](https://nationalzoo.si.edu/news/restoring-americas-prairie), Smithsonian
|
|
97
99
|
* [Polar Ecology Group](https://polarecologygroup.wordpress.com), University of Gdansk
|
|
98
100
|
* [Quantitative Ecology Lab](https://depts.washington.edu/sefsqel/), University of Washington
|
|
101
|
+
* [San Diego Field Station](https://www.usgs.gov/centers/werc/science/san-diego-field-station), U.S. Geological Survey
|
|
99
102
|
* [Santa Monica Mountains Recreation Area](https://www.nps.gov/samo/index.htm), National Park Service
|
|
100
103
|
* [Seattle Urban Carnivore Project](https://www.zoo.org/seattlecarnivores), Woodland Park Zoo
|
|
101
104
|
* [Serra dos Órgãos National Park](https://www.icmbio.gov.br/parnaserradosorgaos/), ICMBio
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
Prepare the OSU Small Animals dataset for LILA release:
|
|
4
|
+
|
|
5
|
+
1. Convert metadata to COCO
|
|
6
|
+
2. Extract location, datestamp, and sequence information
|
|
7
|
+
3. Remove redundant or excluded images
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
#%% Imports and constants
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
input_folder = r'G:\temp\osu-small-animals'
|
|
16
|
+
assert os.path.isdir(input_folder)
|
|
17
|
+
|
|
18
|
+
output_folder = r'G:\temp\osu-small-animals-lila'
|
|
19
|
+
os.makedirs(output_folder,exist_ok=True)
|
|
20
|
+
output_file = os.path.join(output_folder,'osu-small-animals.json')
|
|
21
|
+
|
|
22
|
+
preview_folder = r'G:\temp\osu-small-animals-preview'
|
|
23
|
+
os.makedirs(preview_folder,exist_ok=True)
|
|
24
|
+
|
|
25
|
+
common_to_latin_file = r'c:\git\agentmorrisprivate\camera-traps\osu-small-animals-common-to-latin.txt'
|
|
26
|
+
assert os.path.isfile(common_to_latin_file)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
#%% Support functions
|
|
30
|
+
|
|
31
|
+
def custom_relative_path_to_location(relative_path):
|
|
32
|
+
|
|
33
|
+
bn = os.path.basename(relative_path).upper()
|
|
34
|
+
|
|
35
|
+
# This only impacted six images
|
|
36
|
+
if bn.startswith('RCNX'):
|
|
37
|
+
site = 'OSTN'
|
|
38
|
+
return site
|
|
39
|
+
|
|
40
|
+
# FCS1__2019-07-08__10-37-46(1).JPG
|
|
41
|
+
# BIWA4S2020-06-25_16-19-56.JPG
|
|
42
|
+
# GRN3c__2019-05-05__01-39-23(1).JPG
|
|
43
|
+
|
|
44
|
+
tokens = bn.split('_')
|
|
45
|
+
site = tokens[0]
|
|
46
|
+
if '2020' in site:
|
|
47
|
+
site = site.split('2020')[0]
|
|
48
|
+
|
|
49
|
+
assert len(site) <= 8
|
|
50
|
+
assert site.isalnum()
|
|
51
|
+
|
|
52
|
+
return site
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
#%% Read EXIF data from all images
|
|
56
|
+
|
|
57
|
+
from megadetector.data_management.read_exif import \
|
|
58
|
+
ReadExifOptions, read_exif_from_folder
|
|
59
|
+
import json
|
|
60
|
+
|
|
61
|
+
exif_cache_file = os.path.join(input_folder,'exif_info.json')
|
|
62
|
+
|
|
63
|
+
if os.path.isfile(exif_cache_file):
|
|
64
|
+
|
|
65
|
+
print('Reading EXIF data from cache')
|
|
66
|
+
with open(exif_cache_file,'r') as f:
|
|
67
|
+
exif_info = json.load(f)
|
|
68
|
+
|
|
69
|
+
else:
|
|
70
|
+
|
|
71
|
+
read_exif_options = ReadExifOptions()
|
|
72
|
+
read_exif_options.n_workers = 8
|
|
73
|
+
|
|
74
|
+
exif_info = read_exif_from_folder(input_folder=input_folder,
|
|
75
|
+
output_file=exif_cache_file,
|
|
76
|
+
options=read_exif_options,
|
|
77
|
+
filenames=None,
|
|
78
|
+
recursive=True)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
#%% Verify that no GPS data is present
|
|
82
|
+
|
|
83
|
+
from megadetector.data_management.read_exif import has_gps_info
|
|
84
|
+
|
|
85
|
+
missing_exif_tags = []
|
|
86
|
+
|
|
87
|
+
# im = exif_info[0]
|
|
88
|
+
for im in exif_info:
|
|
89
|
+
if im['exif_tags'] is None:
|
|
90
|
+
missing_exif_tags.append(im['file_name'])
|
|
91
|
+
continue
|
|
92
|
+
else:
|
|
93
|
+
assert not has_gps_info(im)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
#%% Read common --> latin mapping
|
|
97
|
+
|
|
98
|
+
with open(common_to_latin_file,'r') as f:
|
|
99
|
+
lines = f.readlines()
|
|
100
|
+
|
|
101
|
+
common_to_latin = {}
|
|
102
|
+
|
|
103
|
+
# s = lines[0]
|
|
104
|
+
for s in lines:
|
|
105
|
+
s = s.strip()
|
|
106
|
+
tokens = s.split('\t')
|
|
107
|
+
assert len(tokens) == 2
|
|
108
|
+
common = tokens[0].lower().replace(' ','_')
|
|
109
|
+
latin = tokens[1].replace('_',' ').lower()
|
|
110
|
+
assert common not in common_to_latin.keys()
|
|
111
|
+
assert latin not in common_to_latin.values()
|
|
112
|
+
common_to_latin[common] = latin
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
#%% Convert non-excluded, non-split images to COCO format
|
|
116
|
+
|
|
117
|
+
from datetime import datetime
|
|
118
|
+
|
|
119
|
+
from tqdm import tqdm
|
|
120
|
+
|
|
121
|
+
# One-off typo fix
|
|
122
|
+
name_replacements = \
|
|
123
|
+
{
|
|
124
|
+
'common_five-linked_skink':'common_five-lined_skink'
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
category_name_to_category = {}
|
|
128
|
+
# Force the empty category to be ID 0
|
|
129
|
+
empty_category = {}
|
|
130
|
+
empty_category['id'] = 0
|
|
131
|
+
empty_category['name'] = 'empty'
|
|
132
|
+
category_name_to_category['empty'] = empty_category
|
|
133
|
+
next_category_id = 1
|
|
134
|
+
|
|
135
|
+
images = []
|
|
136
|
+
annotations = []
|
|
137
|
+
|
|
138
|
+
error_images = []
|
|
139
|
+
excluded_images = []
|
|
140
|
+
|
|
141
|
+
# exif_im = exif_info[0]
|
|
142
|
+
for exif_im in tqdm(exif_info):
|
|
143
|
+
|
|
144
|
+
fn_relative = exif_im['file_name']
|
|
145
|
+
assert '\\' not in fn_relative
|
|
146
|
+
|
|
147
|
+
if 'Split_images' in fn_relative or 'Exclusions' in fn_relative:
|
|
148
|
+
excluded_images.append(fn_relative)
|
|
149
|
+
continue
|
|
150
|
+
|
|
151
|
+
if 'error' in exif_im:
|
|
152
|
+
assert exif_im['error'] is not None
|
|
153
|
+
error_images.append(fn_relative)
|
|
154
|
+
continue
|
|
155
|
+
|
|
156
|
+
location_name = custom_relative_path_to_location(fn_relative)
|
|
157
|
+
|
|
158
|
+
exif_tags = exif_im['exif_tags']
|
|
159
|
+
|
|
160
|
+
# Convert '2021:05:27 14:42:00' to '2021-05-27 14:42:00'
|
|
161
|
+
datestamp = exif_tags['DateTime']
|
|
162
|
+
datestamp_tokens = datestamp.split(' ')
|
|
163
|
+
assert len(datestamp_tokens) == 2
|
|
164
|
+
date_string = datestamp_tokens[0]
|
|
165
|
+
time_string = datestamp_tokens[1]
|
|
166
|
+
assert len(date_string) == 10 and len(date_string.split(':')) == 3
|
|
167
|
+
date_string = date_string.replace(':','-')
|
|
168
|
+
assert len(time_string) == 8 and len(time_string.split(':')) == 3
|
|
169
|
+
datestamp_string = date_string + ' ' + time_string
|
|
170
|
+
datestamp_object = datetime.strptime(datestamp_string, '%Y-%m-%d %H:%M:%S')
|
|
171
|
+
assert str(datestamp_object) == datestamp_string
|
|
172
|
+
|
|
173
|
+
# E.g.:
|
|
174
|
+
#
|
|
175
|
+
# Images/Sorted_by_species/Testudines/Snapping Turtle/CBG10__2021-05-27__14-42-00(1).JPG'
|
|
176
|
+
common_name = os.path.basename(os.path.dirname(fn_relative)).lower().replace(' ','_')
|
|
177
|
+
|
|
178
|
+
if common_name in name_replacements:
|
|
179
|
+
common_name = name_replacements[common_name]
|
|
180
|
+
|
|
181
|
+
if common_name == 'blanks':
|
|
182
|
+
common_name = 'empty'
|
|
183
|
+
else:
|
|
184
|
+
assert common_name in common_to_latin
|
|
185
|
+
|
|
186
|
+
if common_name in category_name_to_category:
|
|
187
|
+
|
|
188
|
+
category = category_name_to_category[common_name]
|
|
189
|
+
|
|
190
|
+
else:
|
|
191
|
+
|
|
192
|
+
category = {}
|
|
193
|
+
category['name'] = common_name
|
|
194
|
+
category['latin_name'] = common_to_latin[common_name]
|
|
195
|
+
category['id'] = next_category_id
|
|
196
|
+
next_category_id += 1
|
|
197
|
+
category_name_to_category[common_name] = category
|
|
198
|
+
|
|
199
|
+
im = {}
|
|
200
|
+
im['id'] = fn_relative
|
|
201
|
+
im['file_name'] = fn_relative
|
|
202
|
+
im['datetime'] = datestamp_object
|
|
203
|
+
im['location'] = location_name
|
|
204
|
+
|
|
205
|
+
annotation = {}
|
|
206
|
+
annotation['id'] = 'ann_' + fn_relative
|
|
207
|
+
annotation['image_id'] = im['id']
|
|
208
|
+
annotation['category_id'] = category['id']
|
|
209
|
+
annotation['sequence_level_annotation'] = False
|
|
210
|
+
|
|
211
|
+
images.append(im)
|
|
212
|
+
annotations.append(annotation)
|
|
213
|
+
|
|
214
|
+
# ...for each image
|
|
215
|
+
|
|
216
|
+
cct_dict = {}
|
|
217
|
+
cct_dict['images'] = images
|
|
218
|
+
cct_dict['annotations'] = annotations
|
|
219
|
+
cct_dict['categories'] = list(category_name_to_category.values())
|
|
220
|
+
|
|
221
|
+
cct_dict['info'] = {}
|
|
222
|
+
cct_dict['info']['version'] = '2024.10.03'
|
|
223
|
+
cct_dict['info']['description'] = 'OSU small animals dataset'
|
|
224
|
+
|
|
225
|
+
print('\nExcluded {} of {} images ({} errors)'.format(
|
|
226
|
+
len(excluded_images),
|
|
227
|
+
len(exif_info),
|
|
228
|
+
len(error_images)))
|
|
229
|
+
|
|
230
|
+
assert len(images) == len(exif_info) - (len(error_images) + len(excluded_images))
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
#%% Create sequences from timestamps
|
|
234
|
+
|
|
235
|
+
from megadetector.data_management import cct_json_utils
|
|
236
|
+
|
|
237
|
+
print('Assembling images into sequences')
|
|
238
|
+
cct_json_utils.create_sequences(cct_dict)
|
|
239
|
+
|
|
240
|
+
# Convert datetimes to strings so we can serialize to json
|
|
241
|
+
for im in cct_dict['images']:
|
|
242
|
+
im['datetime'] = str(im['datetime'])
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
#%% Write COCO data
|
|
246
|
+
|
|
247
|
+
with open(output_file,'w') as f:
|
|
248
|
+
json.dump(cct_dict,f,indent=1)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
#%% Copy images (prep)
|
|
252
|
+
|
|
253
|
+
from megadetector.utils.path_utils import parallel_copy_files
|
|
254
|
+
|
|
255
|
+
input_file_to_output_file = {}
|
|
256
|
+
|
|
257
|
+
# im = cct_dict['images'][0]
|
|
258
|
+
for im in tqdm(cct_dict['images']):
|
|
259
|
+
fn_relative = im['file_name']
|
|
260
|
+
fn_source_abs = os.path.join(input_folder,fn_relative)
|
|
261
|
+
assert os.path.isfile(fn_source_abs)
|
|
262
|
+
fn_dest_abs = os.path.join(output_folder,fn_relative)
|
|
263
|
+
assert fn_source_abs not in input_file_to_output_file
|
|
264
|
+
input_file_to_output_file[fn_source_abs] = fn_dest_abs
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
#%% Copy images (execution)
|
|
268
|
+
|
|
269
|
+
parallel_copy_files(input_file_to_output_file, max_workers=10,
|
|
270
|
+
use_threads=True, overwrite=False, verbose=False)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
#%% Validate .json file
|
|
274
|
+
|
|
275
|
+
from megadetector.data_management.databases import integrity_check_json_db
|
|
276
|
+
|
|
277
|
+
options = integrity_check_json_db.IntegrityCheckOptions()
|
|
278
|
+
options.baseDir = input_folder
|
|
279
|
+
options.bCheckImageSizes = False
|
|
280
|
+
options.bCheckImageExistence = True
|
|
281
|
+
options.bFindUnusedImages = True
|
|
282
|
+
options.bRequireLocation = True
|
|
283
|
+
|
|
284
|
+
sorted_categories, data, _ = integrity_check_json_db.integrity_check_json_db(output_file, options)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
#%% Preview labels
|
|
288
|
+
|
|
289
|
+
from megadetector.visualization import visualize_db
|
|
290
|
+
|
|
291
|
+
viz_options = visualize_db.DbVizOptions()
|
|
292
|
+
viz_options.num_to_visualize = 5000
|
|
293
|
+
viz_options.parallelize_rendering = True
|
|
294
|
+
viz_options.htmlOptions['maxFiguresPerHtmlFile'] = 2500
|
|
295
|
+
viz_options.parallelize_rendering_with_threads = True
|
|
296
|
+
|
|
297
|
+
html_output_file, image_db = visualize_db.visualize_db(db_path=output_file,
|
|
298
|
+
output_dir=preview_folder,
|
|
299
|
+
image_base_dir=input_folder,
|
|
300
|
+
options=viz_options)
|
|
301
|
+
|
|
302
|
+
os.startfile(html_output_file)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
#%% Print unique locations
|
|
306
|
+
|
|
307
|
+
all_locations = set()
|
|
308
|
+
|
|
309
|
+
for im in cct_dict['images']:
|
|
310
|
+
all_locations.add(im['location'])
|
|
311
|
+
|
|
312
|
+
all_locations = sorted(list(all_locations))
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
#%% Notes
|
|
316
|
+
|
|
317
|
+
"""
|
|
318
|
+
31899 eastern_gartersnake
|
|
319
|
+
14567 song_sparrow
|
|
320
|
+
14169 meadow_vole
|
|
321
|
+
11448 empty
|
|
322
|
+
10548 white-footed_mouse
|
|
323
|
+
5934 northern_house_wren
|
|
324
|
+
5075 invertebrate
|
|
325
|
+
5045 common_five-lined_skink
|
|
326
|
+
4242 masked_shrew
|
|
327
|
+
3263 eastern_cottontail
|
|
328
|
+
2325 long-tailed_weasel
|
|
329
|
+
1510 woodland_jumping_mouse
|
|
330
|
+
1272 plains_gartersnake
|
|
331
|
+
1189 eastern_massasauga
|
|
332
|
+
985 virginia_opossum
|
|
333
|
+
802 common_yellowthroat
|
|
334
|
+
746 n._short-tailed_shrew
|
|
335
|
+
529 dekay's_brownsnake
|
|
336
|
+
425 american_mink
|
|
337
|
+
340 american_toad
|
|
338
|
+
293 eastern_racer_snake
|
|
339
|
+
264 smooth_greensnake
|
|
340
|
+
198 eastern_chipmunk
|
|
341
|
+
193 northern_leopard_frog
|
|
342
|
+
160 meadow_jumping_mouse
|
|
343
|
+
155 butler's_gartersnake
|
|
344
|
+
133 eastern_ribbonsnake
|
|
345
|
+
121 northern_watersnake
|
|
346
|
+
111 star-nosed_mole
|
|
347
|
+
104 striped_skunk
|
|
348
|
+
72 eastern_milksnake
|
|
349
|
+
68 gray_ratsnake
|
|
350
|
+
67 eastern_hog-nosed_snake
|
|
351
|
+
62 raccoon
|
|
352
|
+
47 green_frog
|
|
353
|
+
44 woodchuck
|
|
354
|
+
44 kirtland's_snake
|
|
355
|
+
23 indigo_bunting
|
|
356
|
+
23 painted_turtle
|
|
357
|
+
13 sora
|
|
358
|
+
12 american_bullfrog
|
|
359
|
+
10 gray_catbird
|
|
360
|
+
9 red-bellied_snake
|
|
361
|
+
8 brown_rat
|
|
362
|
+
6 snapping_turtle
|
|
363
|
+
1 eastern_bluebird
|
|
364
|
+
"""
|
|
@@ -511,6 +511,6 @@ open_file(html_filename)
|
|
|
511
511
|
|
|
512
512
|
#%% Zip output file
|
|
513
513
|
|
|
514
|
-
zipped_output_file = zip_file(output_file,verbose=True)
|
|
514
|
+
zipped_output_file = zip_file(output_file,verbose=True,overwrite=True)
|
|
515
515
|
|
|
516
516
|
print('Zipped {} to {}'.format(output_file,zipped_output_file))
|
{megadetector-5.0.19 → megadetector-5.0.20}/megadetector/data_management/lila/lila_common.py
RENAMED
|
@@ -50,12 +50,14 @@ for url in lila_base_urls.values():
|
|
|
50
50
|
|
|
51
51
|
#%% Common functions
|
|
52
52
|
|
|
53
|
-
def read_wildlife_insights_taxonomy_mapping(metadata_dir):
|
|
53
|
+
def read_wildlife_insights_taxonomy_mapping(metadata_dir, force_download=False):
|
|
54
54
|
"""
|
|
55
55
|
Reads the WI taxonomy mapping file, downloading the .json data (and writing to .csv) if necessary.
|
|
56
56
|
|
|
57
57
|
Args:
|
|
58
58
|
metadata_dir (str): folder to use for temporary LILA metadata files
|
|
59
|
+
force_download (bool, optional): download the taxonomy mapping file
|
|
60
|
+
even if the local file exists.
|
|
59
61
|
|
|
60
62
|
Returns:
|
|
61
63
|
pd.dataframe: A DataFrame with taxonomy information
|
|
@@ -67,7 +69,8 @@ def read_wildlife_insights_taxonomy_mapping(metadata_dir):
|
|
|
67
69
|
df = pd.read_csv(wi_taxonomy_csv_path)
|
|
68
70
|
else:
|
|
69
71
|
wi_taxonomy_json_path = os.path.join(metadata_dir,wildlife_insights_taxonomy_local_json_filename)
|
|
70
|
-
download_url(wildlife_insights_taxonomy_url, wi_taxonomy_json_path
|
|
72
|
+
download_url(wildlife_insights_taxonomy_url, wi_taxonomy_json_path,
|
|
73
|
+
force_download=force_download)
|
|
71
74
|
with open(wi_taxonomy_json_path,'r') as f:
|
|
72
75
|
d = json.load(f)
|
|
73
76
|
|
|
@@ -93,12 +96,14 @@ def read_wildlife_insights_taxonomy_mapping(metadata_dir):
|
|
|
93
96
|
return df
|
|
94
97
|
|
|
95
98
|
|
|
96
|
-
def read_lila_taxonomy_mapping(metadata_dir):
|
|
99
|
+
def read_lila_taxonomy_mapping(metadata_dir, force_download=False):
|
|
97
100
|
"""
|
|
98
101
|
Reads the LILA taxonomy mapping file, downloading the .csv file if necessary.
|
|
99
102
|
|
|
100
103
|
Args:
|
|
101
104
|
metadata_dir (str): folder to use for temporary LILA metadata files
|
|
105
|
+
force_download (bool, optional): download the taxonomy mapping file
|
|
106
|
+
even if the local file exists.
|
|
102
107
|
|
|
103
108
|
Returns:
|
|
104
109
|
pd.DataFrame: a DataFrame with one row per identification
|
|
@@ -106,19 +111,22 @@ def read_lila_taxonomy_mapping(metadata_dir):
|
|
|
106
111
|
|
|
107
112
|
p = urlparse(lila_taxonomy_mapping_url)
|
|
108
113
|
taxonomy_filename = os.path.join(metadata_dir,os.path.basename(p.path))
|
|
109
|
-
download_url(lila_taxonomy_mapping_url, taxonomy_filename
|
|
114
|
+
download_url(lila_taxonomy_mapping_url, taxonomy_filename,
|
|
115
|
+
force_download=force_download)
|
|
110
116
|
|
|
111
117
|
df = pd.read_csv(lila_taxonomy_mapping_url)
|
|
112
118
|
|
|
113
119
|
return df
|
|
114
120
|
|
|
115
121
|
|
|
116
|
-
def read_lila_metadata(metadata_dir):
|
|
122
|
+
def read_lila_metadata(metadata_dir, force_download=False):
|
|
117
123
|
"""
|
|
118
124
|
Reads LILA metadata (URLs to each dataset), downloading the .csv file if necessary.
|
|
119
125
|
|
|
120
126
|
Args:
|
|
121
127
|
metadata_dir (str): folder to use for temporary LILA metadata files
|
|
128
|
+
force_download (bool, optional): download the metadata file even if
|
|
129
|
+
the local file exists.
|
|
122
130
|
|
|
123
131
|
Returns:
|
|
124
132
|
dict: a dict mapping dataset names (e.g. "Caltech Camera Traps") to dicts
|
|
@@ -130,7 +138,6 @@ def read_lila_metadata(metadata_dir):
|
|
|
130
138
|
- country
|
|
131
139
|
- region
|
|
132
140
|
- image_base_url_relative
|
|
133
|
-
- metadata_url_relative
|
|
134
141
|
- bbox_url_relative
|
|
135
142
|
- image_base_url_gcp
|
|
136
143
|
- metadata_url_gcp
|
|
@@ -150,7 +157,7 @@ def read_lila_metadata(metadata_dir):
|
|
|
150
157
|
# Put the master metadata file in the same folder where we're putting images
|
|
151
158
|
p = urlparse(lila_metadata_url)
|
|
152
159
|
metadata_filename = os.path.join(metadata_dir,os.path.basename(p.path))
|
|
153
|
-
download_url(lila_metadata_url, metadata_filename)
|
|
160
|
+
download_url(lila_metadata_url, metadata_filename, force_download=force_download)
|
|
154
161
|
|
|
155
162
|
df = pd.read_csv(metadata_filename)
|
|
156
163
|
|
|
@@ -174,13 +181,15 @@ def read_lila_metadata(metadata_dir):
|
|
|
174
181
|
return metadata_table
|
|
175
182
|
|
|
176
183
|
|
|
177
|
-
def read_lila_all_images_file(metadata_dir):
|
|
184
|
+
def read_lila_all_images_file(metadata_dir, force_download=False):
|
|
178
185
|
"""
|
|
179
186
|
Downloads if necessary - then unzips if necessary - the .csv file with label mappings for
|
|
180
187
|
all LILA files, and opens the resulting .csv file as a Pandas DataFrame.
|
|
181
188
|
|
|
182
189
|
Args:
|
|
183
190
|
metadata_dir (str): folder to use for temporary LILA metadata files
|
|
191
|
+
force_download (bool, optional): download the metadata file even if
|
|
192
|
+
the local file exists.
|
|
184
193
|
|
|
185
194
|
Returns:
|
|
186
195
|
pd.DataFrame: a DataFrame containing one row per identification in a LILA camera trap image
|
|
@@ -188,7 +197,8 @@ def read_lila_all_images_file(metadata_dir):
|
|
|
188
197
|
|
|
189
198
|
p = urlparse(lila_all_images_url)
|
|
190
199
|
lila_all_images_zip_filename = os.path.join(metadata_dir,os.path.basename(p.path))
|
|
191
|
-
download_url(lila_all_images_url, lila_all_images_zip_filename
|
|
200
|
+
download_url(lila_all_images_url, lila_all_images_zip_filename,
|
|
201
|
+
force_download=force_download)
|
|
192
202
|
|
|
193
203
|
with zipfile.ZipFile(lila_all_images_zip_filename,'r') as z:
|
|
194
204
|
files = z.namelist()
|
|
@@ -209,7 +219,8 @@ def read_metadata_file_for_dataset(ds_name,
|
|
|
209
219
|
metadata_dir,
|
|
210
220
|
metadata_table=None,
|
|
211
221
|
json_url=None,
|
|
212
|
-
preferred_cloud='gcp'
|
|
222
|
+
preferred_cloud='gcp',
|
|
223
|
+
force_download=False):
|
|
213
224
|
"""
|
|
214
225
|
Downloads if necessary - then unzips if necessary - the .json file for a specific dataset.
|
|
215
226
|
|
|
@@ -222,6 +233,8 @@ def read_metadata_file_for_dataset(ds_name,
|
|
|
222
233
|
json_url (str, optional): the URL of the metadata file, if None will be retrieved
|
|
223
234
|
via read_lila_metadata()
|
|
224
235
|
preferred_cloud (str, optional): 'gcp' (default), 'azure', or 'aws'
|
|
236
|
+
force_download (bool, optional): download the metadata file even if
|
|
237
|
+
the local file exists.
|
|
225
238
|
|
|
226
239
|
Returns:
|
|
227
240
|
str: the .json filename on the local disk
|
|
@@ -239,7 +252,7 @@ def read_metadata_file_for_dataset(ds_name,
|
|
|
239
252
|
|
|
240
253
|
p = urlparse(json_url)
|
|
241
254
|
json_filename = os.path.join(metadata_dir,os.path.basename(p.path))
|
|
242
|
-
download_url(json_url, json_filename)
|
|
255
|
+
download_url(json_url, json_filename, force_download=force_download)
|
|
243
256
|
|
|
244
257
|
# Unzip if necessary
|
|
245
258
|
if json_filename.endswith('.zip'):
|
|
@@ -266,7 +279,10 @@ if False:
|
|
|
266
279
|
#%% Verify that all base URLs exist
|
|
267
280
|
|
|
268
281
|
# LILA camera trap primary metadata file
|
|
269
|
-
urls = (lila_metadata_url,
|
|
282
|
+
urls = (lila_metadata_url,
|
|
283
|
+
lila_taxonomy_mapping_url,
|
|
284
|
+
lila_all_images_url,
|
|
285
|
+
wildlife_insights_taxonomy_url)
|
|
270
286
|
|
|
271
287
|
from megadetector.utils import url_utils
|
|
272
288
|
|
|
@@ -35,15 +35,17 @@ md_results_keys = ['mdv4_results_raw','mdv5a_results_raw','mdv5b_results_raw','m
|
|
|
35
35
|
|
|
36
36
|
preferred_cloud = 'gcp' # 'azure', 'aws'
|
|
37
37
|
|
|
38
|
+
force_download = True
|
|
39
|
+
|
|
38
40
|
|
|
39
41
|
#%% Load category and taxonomy files
|
|
40
42
|
|
|
41
|
-
taxonomy_df = read_lila_taxonomy_mapping(metadata_dir)
|
|
43
|
+
taxonomy_df = read_lila_taxonomy_mapping(metadata_dir, force_download=force_download)
|
|
42
44
|
|
|
43
45
|
|
|
44
46
|
#%% Download and parse the metadata file
|
|
45
47
|
|
|
46
|
-
metadata_table = read_lila_metadata(metadata_dir)
|
|
48
|
+
metadata_table = read_lila_metadata(metadata_dir, force_download=force_download)
|
|
47
49
|
|
|
48
50
|
print('Loaded metadata URLs for {} datasets'.format(len(metadata_table)))
|
|
49
51
|
|
|
@@ -52,17 +54,24 @@ print('Loaded metadata URLs for {} datasets'.format(len(metadata_table)))
|
|
|
52
54
|
|
|
53
55
|
for ds_name in metadata_table.keys():
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
# Download the main metadata file for this dataset
|
|
58
|
+
metadata_table[ds_name]['json_filename'] = \
|
|
59
|
+
read_metadata_file_for_dataset(ds_name=ds_name,
|
|
60
|
+
metadata_dir=metadata_dir,
|
|
61
|
+
metadata_table=metadata_table,
|
|
62
|
+
force_download=force_download)
|
|
63
|
+
|
|
64
|
+
# Download MD results for this dataset
|
|
58
65
|
for k in md_results_keys:
|
|
59
66
|
md_results_url = metadata_table[ds_name][k]
|
|
60
67
|
if md_results_url is None:
|
|
61
68
|
metadata_table[ds_name][k + '_filename'] = None
|
|
62
69
|
else:
|
|
63
|
-
metadata_table[ds_name][k + '_filename'] =
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
metadata_table[ds_name][k + '_filename'] = \
|
|
71
|
+
read_metadata_file_for_dataset(ds_name=ds_name,
|
|
72
|
+
metadata_dir=md_results_dir,
|
|
73
|
+
json_url=md_results_url,
|
|
74
|
+
force_download=force_download)
|
|
66
75
|
|
|
67
76
|
|
|
68
77
|
#%% Build up a list of URLs to test
|