megadetector 10.0.8__tar.gz → 10.0.10__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-10.0.8/megadetector.egg-info → megadetector-10.0.10}/PKG-INFO +1 -1
- {megadetector-10.0.8 → megadetector-10.0.10}/README.md +2 -2
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/read_exif.py +15 -2
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/pytorch_detector.py +3 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/run_detector.py +1 -2
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/run_detector_batch.py +84 -52
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/run_md_and_speciesnet.py +81 -23
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/run_tiled_inference.py +56 -15
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/tf_detector.py +3 -5
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/classification_postprocessing.py +12 -13
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/compare_batch_results.py +48 -28
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/postprocess_batch_results.py +1 -1
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/subset_json_detector_output.py +80 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/directory_listing.py +3 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/path_utils.py +67 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/string_utils.py +21 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/wi_platform_utils.py +168 -24
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/wi_taxonomy_utils.py +1 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/visualization/visualize_detector_output.py +1 -0
- {megadetector-10.0.8 → megadetector-10.0.10/megadetector.egg-info}/PKG-INFO +1 -1
- {megadetector-10.0.8 → megadetector-10.0.10}/pyproject.toml +3 -3
- {megadetector-10.0.8 → megadetector-10.0.10}/LICENSE +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/README-package.md +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/api/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/api/batch_processing/integration/digiKam/setup.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/api/batch_processing/integration/eMammal/test_scripts/config_template.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/aggregate_classifier_probs.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/analyze_failed_images.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/cache_batchapi_outputs.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/create_classification_dataset.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/crop_detections.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/csv_to_json.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/detect_and_crop.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/efficientnet/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/efficientnet/model.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/efficientnet/utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/evaluate_model.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/identify_mislabeled_candidates.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/json_to_azcopy_list.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/json_validator.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/map_classification_categories.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/merge_classification_detection_output.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/prepare_classification_script.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/prepare_classification_script_mc.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/run_classifier.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/save_mislabeled.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/train_classifier.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/train_classifier_tf.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/classification/train_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/animl_to_md.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/annotations/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/annotations/annotation_constants.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/camtrap_dp_to_coco.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/cct_json_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/cct_to_md.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/cct_to_wi.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/coco_to_labelme.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/coco_to_yolo.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/databases/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/databases/add_width_and_height_to_db.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/databases/combine_coco_camera_traps_files.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/databases/integrity_check_json_db.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/databases/subset_json_db.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/generate_crops_from_cct.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/get_image_sizes.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/labelme_to_coco.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/labelme_to_yolo.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/create_lila_blank_set.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/create_lila_test_set.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/create_links_to_md_results_files.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/download_lila_subset.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/generate_lila_per_image_labels.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/get_lila_annotation_counts.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/get_lila_image_counts.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/lila_common.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/lila/test_lila_metadata_urls.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/mewc_to_md.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/ocr_tools.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/remap_coco_categories.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/remove_exif.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/rename_images.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/resize_coco_dataset.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/speciesnet_to_md.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/wi_download_csv_to_coco.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/yolo_output_to_md_output.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/yolo_to_coco.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/data_management/zamba_to_md.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/change_detection.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/process_video.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/run_inference_with_yolov5_val.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/detection/video_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/add_max_conf.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/categorize_detections_by_size.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/combine_batch_outputs.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/convert_output_format.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/create_crop_folder.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/detector_calibration.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/generate_csv_report.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/load_api_results.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/md_to_coco.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/md_to_labelme.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/md_to_wi.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/merge_detections.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/remap_detection_categories.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/render_detection_confusion_matrix.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/separate_detections_into_folders.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/top_folders_to_bottom.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/postprocessing/validate_batch_results.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/map_new_lila_datasets.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/preview_lila_taxonomy.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/retrieve_sample_image.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/simple_image_download.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/species_lookup.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/taxonomy_csv_checker.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/taxonomy_graph.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/taxonomy_mapping/validate_lila_category_mappings.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/tests/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/tests/test_nms_synthetic.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/ct_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/extract_frames_from_video.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/gpu_test.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/md_tests.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/process_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/split_locations_into_train_val.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/url_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/utils/write_html_image_list.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/visualization/__init__.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/visualization/plot_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/visualization/render_images_with_thumbnails.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/visualization/visualization_utils.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/visualization/visualize_db.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector/visualization/visualize_video_output.py +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector.egg-info/SOURCES.txt +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector.egg-info/dependency_links.txt +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector.egg-info/requires.txt +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/megadetector.egg-info/top_level.txt +0 -0
- {megadetector-10.0.8 → megadetector-10.0.10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: megadetector
|
|
3
|
-
Version: 10.0.
|
|
3
|
+
Version: 10.0.10
|
|
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>
|
|
@@ -47,7 +47,6 @@ Here are a few of the organizations that have used MegaDetector... we're only li
|
|
|
47
47
|
* [Blackbird Environmental](https://blackbirdenv.com/)
|
|
48
48
|
* [Camelot](https://camelotproject.org/)
|
|
49
49
|
* [Canadian Parks and Wilderness Society (CPAWS) Northern Alberta Chapter](https://cpawsnab.org/)
|
|
50
|
-
* [Conservation X Labs](https://conservationxlabs.com/)
|
|
51
50
|
* [Czech University of Life Sciences Prague](https://www.czu.cz/en)
|
|
52
51
|
* [Dudek Camera Trap AI Image Toolkit (AIT)](https://ait.dudek.com/)
|
|
53
52
|
* [EcoLogic Consultants Ltd.](https://www.consult-ecologic.com/)
|
|
@@ -122,7 +121,6 @@ Here are a few of the organizations that have used MegaDetector... we're only li
|
|
|
122
121
|
|
|
123
122
|
* [School of Natural Sciences](https://www.utas.edu.au/natural-sciences), University of Tasmania ([story](https://www.utas.edu.au/about/news-and-stories/articles/2022/1204-innovative-camera-network-keeps-close-eye-on-tassie-wildlife))
|
|
124
123
|
* [Kenai National Wildlife Refuge](https://www.fws.gov/refuge/kenai), U.S. Fish & Wildlife Service ([story](https://www.peninsulaclarion.com/sports/refuge-notebook-new-technology-increases-efficiency-of-refuge-cameras/))
|
|
125
|
-
|
|
126
124
|
* [Idaho Department of Fish and Game](https://idfg.idaho.gov/) ([fancy PBS video](https://www.youtube.com/watch?v=uEsL8EZKpbA&t=261s&ab_channel=OutdoorIdaho))
|
|
127
125
|
* [Australian Wildlife Conservancy](https://www.australianwildlife.org/) (blog posts [1](https://www.australianwildlife.org/cutting-edge-technology-delivering-efficiency-gains-in-conservation/), [2](https://www.australianwildlife.org/efficiency-gains-at-the-cutting-edge-of-technology/), [3](https://www.australianwildlife.org/federal-grant-to-fund-ai-supported-wildlife-recognisers))
|
|
128
126
|
* [Bavarian Forest National Park](https://www.nationalpark-bayerischer-wald.bayern.de/english/index.htm) ([story](https://customers.microsoft.com/en-au/story/1667539539271247797-nationalparkbayerischerwald-azure-en))
|
|
@@ -148,6 +146,8 @@ Here are a few of the organizations that have used MegaDetector... we're only li
|
|
|
148
146
|
* [San Diego Zoo Wildlife Alliance](https://science.sandiegozoo.org/) ([Animl R package](https://github.com/conservationtechlab/animl))
|
|
149
147
|
* [TerrOïko](https://www.terroiko.fr/) ([OCAPI platform](https://www.terroiko.fr/ocapi))
|
|
150
148
|
* [Wildlife Division](https://www.michigan.gov/dnr/about/contact/wildlife), Michigan Department of Natural Resources ([blog post](https://www.michigan.gov/dnr/about/newsroom/releases/2025/08/18/dnr-researchers-to-test-trail-cameras-in-elk-survey))
|
|
149
|
+
* [Cleveland Metroparks](https://www.clevelandmetroparks.com/) ([presentation](https://www.clevelandmetroparks.com/getmedia/d4978f4b-5641-4e6b-ac16-b29e9e3d43d1/AI_8_21_25.pdf))
|
|
150
|
+
* [Conservation X Labs](https://conservationxlabs.com/) ([story](https://news.mongabay.com/2025/09/turning-camera-traps-into-real-time-sentinels-interview-with-conservation-x-labs-dante-wasmuht/))
|
|
151
151
|
|
|
152
152
|
Also see:
|
|
153
153
|
|
|
@@ -210,6 +210,8 @@ def read_pil_exif(im,options=None):
|
|
|
210
210
|
if exif_info is None:
|
|
211
211
|
return exif_tags
|
|
212
212
|
|
|
213
|
+
# Read all standard EXIF tags; if necessary, we'll filter later to a restricted
|
|
214
|
+
# list of tags.
|
|
213
215
|
for k, v in exif_info.items():
|
|
214
216
|
assert isinstance(k,str) or isinstance(k,int), \
|
|
215
217
|
'Invalid EXIF key {}'.format(str(k))
|
|
@@ -221,6 +223,7 @@ def read_pil_exif(im,options=None):
|
|
|
221
223
|
|
|
222
224
|
exif_ifd_tags = _get_exif_ifd(exif_info)
|
|
223
225
|
|
|
226
|
+
# Read tags that are only available via offset
|
|
224
227
|
for k in exif_ifd_tags.keys():
|
|
225
228
|
v = exif_ifd_tags[k]
|
|
226
229
|
if k in exif_tags:
|
|
@@ -266,7 +269,7 @@ def read_pil_exif(im,options=None):
|
|
|
266
269
|
|
|
267
270
|
# Convert to strings, e.g. 'GPSTimeStamp'
|
|
268
271
|
gps_info = {}
|
|
269
|
-
for int_tag,v in
|
|
272
|
+
for int_tag,v in gps_info_raw.items():
|
|
270
273
|
assert isinstance(int_tag,int)
|
|
271
274
|
if int_tag in ExifTags.GPSTAGS:
|
|
272
275
|
gps_info[ExifTags.GPSTAGS[int_tag]] = v
|
|
@@ -276,11 +279,15 @@ def read_pil_exif(im,options=None):
|
|
|
276
279
|
exif_tags['GPSInfo'] = gps_info
|
|
277
280
|
|
|
278
281
|
except Exception as e:
|
|
282
|
+
|
|
279
283
|
if options.verbose:
|
|
280
284
|
print('Warning: error reading GPS info: {}'.format(str(e)))
|
|
281
285
|
|
|
282
286
|
# ...if we think there might be GPS tags in this image
|
|
283
287
|
|
|
288
|
+
# Filter tags if necessary
|
|
289
|
+
exif_tags = _filter_tags(exif_tags,options)
|
|
290
|
+
|
|
284
291
|
return exif_tags
|
|
285
292
|
|
|
286
293
|
# ...read_pil_exif()
|
|
@@ -337,10 +344,16 @@ def _filter_tags(tags,options):
|
|
|
337
344
|
if options.tags_to_include is None and options.tags_to_exclude is None:
|
|
338
345
|
return tags
|
|
339
346
|
if options.tags_to_include is not None:
|
|
347
|
+
if isinstance(options.tags_to_include,str):
|
|
348
|
+
if options.tags_to_include == 'all':
|
|
349
|
+
return tags
|
|
340
350
|
assert options.tags_to_exclude is None, "tags_to_include and tags_to_exclude are incompatible"
|
|
351
|
+
tags_to_include = options.tags_to_include.split(',')
|
|
352
|
+
# Case-insensitive matching
|
|
353
|
+
tags_to_include = [s.lower() for s in tags_to_include]
|
|
341
354
|
tags_to_return = {}
|
|
342
355
|
for tag_name in tags.keys():
|
|
343
|
-
if tag_name in
|
|
356
|
+
if str(tag_name).lower() in tags_to_include:
|
|
344
357
|
tags_to_return[tag_name] = tags[tag_name]
|
|
345
358
|
return tags_to_return
|
|
346
359
|
if options.tags_to_exclude is not None:
|
|
@@ -859,6 +859,9 @@ class PTDetector:
|
|
|
859
859
|
except AttributeError:
|
|
860
860
|
pass
|
|
861
861
|
|
|
862
|
+
# AddaxAI depends on this printout, don't remove it
|
|
863
|
+
print('PTDetector using device {}'.format(str(self.device).lower()))
|
|
864
|
+
|
|
862
865
|
try:
|
|
863
866
|
self.model = PTDetector._load_model(model_path,
|
|
864
867
|
device=self.device,
|
|
@@ -596,8 +596,7 @@ def load_detector(model_file,
|
|
|
596
596
|
model_file = try_download_known_detector(model_file,
|
|
597
597
|
force_download=force_model_download)
|
|
598
598
|
|
|
599
|
-
|
|
600
|
-
print('GPU available: {}'.format(is_gpu_available(model_file)))
|
|
599
|
+
print('GPU available: {}'.format(is_gpu_available(model_file)))
|
|
601
600
|
|
|
602
601
|
start_time = time.time()
|
|
603
602
|
|
|
@@ -94,20 +94,29 @@ max_queue_size = 10
|
|
|
94
94
|
# How often should we print progress when using the image queue?
|
|
95
95
|
n_queue_print = 1000
|
|
96
96
|
|
|
97
|
-
#
|
|
97
|
+
# Only used if --include_exif_tags or --include_image_timestamp are supplied
|
|
98
|
+
exif_options_base = read_exif.ReadExifOptions()
|
|
99
|
+
exif_options_base.processing_library = 'pil'
|
|
100
|
+
exif_options_base.byte_handling = 'convert_to_string'
|
|
101
|
+
|
|
102
|
+
# Only relevant when we're running our test harness; because bugs in batch
|
|
103
|
+
# inference are dependent on batch grouping, we randomize batch grouping
|
|
104
|
+
# during testing to maximize the probability that latent bugs come up
|
|
105
|
+
# eventually.
|
|
106
|
+
randomize_batch_order_during_testing = True
|
|
107
|
+
|
|
108
|
+
# TODO: it's a little sloppy that the following are module-level globals, but in practice it
|
|
98
109
|
# doesn't really matter, so I'm not in a big rush to move these to options until I do
|
|
99
110
|
# a larger cleanup of all the long argument lists in this module.
|
|
100
|
-
|
|
111
|
+
|
|
101
112
|
# Should the consumer loop run on its own process, or here in the main process?
|
|
102
113
|
run_separate_consumer_process = False
|
|
103
|
-
use_threads_for_queue = False
|
|
104
|
-
verbose = False
|
|
105
114
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
exif_options.byte_handling = 'convert_to_string'
|
|
115
|
+
# Should we use threads (rather than processes) for the data loading workers?
|
|
116
|
+
use_threads_for_queue = False
|
|
109
117
|
|
|
110
|
-
|
|
118
|
+
# Enable additional debug output
|
|
119
|
+
verbose = False
|
|
111
120
|
|
|
112
121
|
|
|
113
122
|
#%% Support functions for multiprocessing
|
|
@@ -199,7 +208,7 @@ def _consumer_func(q,
|
|
|
199
208
|
image_size=None,
|
|
200
209
|
include_image_size=False,
|
|
201
210
|
include_image_timestamp=False,
|
|
202
|
-
|
|
211
|
+
include_exif_tags=None,
|
|
203
212
|
augment=False,
|
|
204
213
|
detector_options=None,
|
|
205
214
|
preprocess_on_image_queue=default_preprocess_on_image_queue,
|
|
@@ -223,7 +232,7 @@ def _consumer_func(q,
|
|
|
223
232
|
image_size (int, optional): image size to use for inference
|
|
224
233
|
include_image_size (bool, optional): include image dimensions in output
|
|
225
234
|
include_image_timestamp (bool, optional): include image timestamps in output
|
|
226
|
-
|
|
235
|
+
include_exif_tags (str, optional): comma-separated list of EXIF tags to include in output
|
|
227
236
|
augment (bool, optional): enable image augmentation
|
|
228
237
|
detector_options (dict, optional): key/value pairs that are interpreted differently
|
|
229
238
|
by different detectors
|
|
@@ -325,7 +334,7 @@ def _consumer_func(q,
|
|
|
325
334
|
image_size=image_size,
|
|
326
335
|
include_image_size=include_image_size,
|
|
327
336
|
include_image_timestamp=include_image_timestamp,
|
|
328
|
-
|
|
337
|
+
include_exif_tags=include_exif_tags,
|
|
329
338
|
augment=augment)
|
|
330
339
|
results.extend(batch_results)
|
|
331
340
|
|
|
@@ -402,7 +411,7 @@ def _consumer_func(q,
|
|
|
402
411
|
image_size=image_size,
|
|
403
412
|
include_image_size=include_image_size,
|
|
404
413
|
include_image_timestamp=include_image_timestamp,
|
|
405
|
-
|
|
414
|
+
include_exif_tags=include_exif_tags,
|
|
406
415
|
augment=augment)
|
|
407
416
|
results.extend(batch_results)
|
|
408
417
|
|
|
@@ -422,7 +431,7 @@ def _consumer_func(q,
|
|
|
422
431
|
image_size=image_size,
|
|
423
432
|
include_image_size=include_image_size,
|
|
424
433
|
include_image_timestamp=include_image_timestamp,
|
|
425
|
-
|
|
434
|
+
include_exif_tags=include_exif_tags,
|
|
426
435
|
augment=augment)
|
|
427
436
|
results.append(result)
|
|
428
437
|
n_images_processed += 1
|
|
@@ -455,7 +464,7 @@ def _run_detector_with_image_queue(image_files,
|
|
|
455
464
|
image_size=None,
|
|
456
465
|
include_image_size=False,
|
|
457
466
|
include_image_timestamp=False,
|
|
458
|
-
|
|
467
|
+
include_exif_tags=None,
|
|
459
468
|
augment=False,
|
|
460
469
|
detector_options=None,
|
|
461
470
|
loader_workers=default_loaders,
|
|
@@ -478,7 +487,7 @@ def _run_detector_with_image_queue(image_files,
|
|
|
478
487
|
doing
|
|
479
488
|
include_image_size (bool, optional): should we include image size in the output for each image?
|
|
480
489
|
include_image_timestamp (bool, optional): should we include image timestamps in the output for each image?
|
|
481
|
-
|
|
490
|
+
include_exif_tags (str, optional): comma-separated list of EXIF tags to include in output
|
|
482
491
|
augment (bool, optional): enable image augmentation
|
|
483
492
|
detector_options (dict, optional): key/value pairs that are interpreted differently
|
|
484
493
|
by different detectors
|
|
@@ -553,7 +562,7 @@ def _run_detector_with_image_queue(image_files,
|
|
|
553
562
|
image_size,
|
|
554
563
|
include_image_size,
|
|
555
564
|
include_image_timestamp,
|
|
556
|
-
|
|
565
|
+
include_exif_tags,
|
|
557
566
|
augment,
|
|
558
567
|
detector_options,
|
|
559
568
|
preprocess_on_image_queue,
|
|
@@ -570,7 +579,7 @@ def _run_detector_with_image_queue(image_files,
|
|
|
570
579
|
image_size,
|
|
571
580
|
include_image_size,
|
|
572
581
|
include_image_timestamp,
|
|
573
|
-
|
|
582
|
+
include_exif_tags,
|
|
574
583
|
augment,
|
|
575
584
|
detector_options,
|
|
576
585
|
preprocess_on_image_queue,
|
|
@@ -589,7 +598,7 @@ def _run_detector_with_image_queue(image_files,
|
|
|
589
598
|
image_size,
|
|
590
599
|
include_image_size,
|
|
591
600
|
include_image_timestamp,
|
|
592
|
-
|
|
601
|
+
include_exif_tags,
|
|
593
602
|
augment,
|
|
594
603
|
detector_options,
|
|
595
604
|
preprocess_on_image_queue,
|
|
@@ -671,7 +680,7 @@ def _process_batch(image_items_batch,
|
|
|
671
680
|
image_size=None,
|
|
672
681
|
include_image_size=False,
|
|
673
682
|
include_image_timestamp=False,
|
|
674
|
-
|
|
683
|
+
include_exif_tags=None,
|
|
675
684
|
augment=False):
|
|
676
685
|
"""
|
|
677
686
|
Process a batch of images using generate_detections_one_batch(). Does not necessarily return
|
|
@@ -686,7 +695,7 @@ def _process_batch(image_items_batch,
|
|
|
686
695
|
image_size (int, optional): image size override
|
|
687
696
|
include_image_size (bool, optional): include image dimensions in results
|
|
688
697
|
include_image_timestamp (bool, optional): include image timestamps in results
|
|
689
|
-
|
|
698
|
+
include_exif_tags (str, optional): comma-separated list of EXIF tags to include in output
|
|
690
699
|
augment (bool, optional): whether to use image augmentation
|
|
691
700
|
|
|
692
701
|
Returns:
|
|
@@ -736,7 +745,9 @@ def _process_batch(image_items_batch,
|
|
|
736
745
|
try:
|
|
737
746
|
|
|
738
747
|
batch_detections = \
|
|
739
|
-
detector.generate_detections_one_batch(valid_images,
|
|
748
|
+
detector.generate_detections_one_batch(valid_images,
|
|
749
|
+
valid_image_filenames,
|
|
750
|
+
verbose=verbose)
|
|
740
751
|
|
|
741
752
|
assert len(batch_detections) == len(valid_images)
|
|
742
753
|
|
|
@@ -751,12 +762,13 @@ def _process_batch(image_items_batch,
|
|
|
751
762
|
image_result['detections'] = \
|
|
752
763
|
[det for det in image_result['detections'] if det['conf'] >= confidence_threshold]
|
|
753
764
|
|
|
754
|
-
if include_image_size or include_image_timestamp or
|
|
765
|
+
if include_image_size or include_image_timestamp or (include_exif_tags is not None):
|
|
755
766
|
|
|
756
767
|
image = valid_images[i_valid_image]
|
|
757
768
|
|
|
758
769
|
# If this was preprocessed by the producer thread, pull out the PIL version
|
|
759
770
|
if isinstance(image,dict):
|
|
771
|
+
|
|
760
772
|
image = image['img_original_pil']
|
|
761
773
|
|
|
762
774
|
if include_image_size:
|
|
@@ -768,9 +780,12 @@ def _process_batch(image_items_batch,
|
|
|
768
780
|
|
|
769
781
|
image_result['datetime'] = get_image_datetime(image)
|
|
770
782
|
|
|
771
|
-
if
|
|
783
|
+
if include_exif_tags is not None:
|
|
772
784
|
|
|
773
|
-
|
|
785
|
+
exif_options = copy.copy(exif_options_base)
|
|
786
|
+
exif_options.tags_to_include = include_exif_tags
|
|
787
|
+
image_result['exif_metadata'] = read_exif.read_pil_exif(
|
|
788
|
+
image,exif_options)
|
|
774
789
|
|
|
775
790
|
# ...if we need to store metadata
|
|
776
791
|
|
|
@@ -823,7 +838,7 @@ def _process_images(im_files,
|
|
|
823
838
|
checkpoint_queue=None,
|
|
824
839
|
include_image_size=False,
|
|
825
840
|
include_image_timestamp=False,
|
|
826
|
-
|
|
841
|
+
include_exif_tags=None,
|
|
827
842
|
augment=False,
|
|
828
843
|
detector_options=None,
|
|
829
844
|
loader_workers=default_loaders,
|
|
@@ -845,7 +860,7 @@ def _process_images(im_files,
|
|
|
845
860
|
checkpoint_queue (Queue, optional): internal parameter used to pass image queues around
|
|
846
861
|
include_image_size (bool, optional): should we include image size in the output for each image?
|
|
847
862
|
include_image_timestamp (bool, optional): should we include image timestamps in the output for each image?
|
|
848
|
-
|
|
863
|
+
include_exif_tags (str, optional): comma-separated list of EXIF tags to include in output
|
|
849
864
|
augment (bool, optional): enable image augmentation
|
|
850
865
|
detector_options (dict, optional): key/value pairs that are interpreted differently
|
|
851
866
|
by different detectors
|
|
@@ -879,7 +894,7 @@ def _process_images(im_files,
|
|
|
879
894
|
image_size=image_size,
|
|
880
895
|
include_image_size=include_image_size,
|
|
881
896
|
include_image_timestamp=include_image_timestamp,
|
|
882
|
-
|
|
897
|
+
include_exif_tags=include_exif_tags,
|
|
883
898
|
augment=augment,
|
|
884
899
|
detector_options=detector_options,
|
|
885
900
|
loader_workers=loader_workers,
|
|
@@ -896,7 +911,7 @@ def _process_images(im_files,
|
|
|
896
911
|
image_size=image_size,
|
|
897
912
|
include_image_size=include_image_size,
|
|
898
913
|
include_image_timestamp=include_image_timestamp,
|
|
899
|
-
|
|
914
|
+
include_exif_tags=include_exif_tags,
|
|
900
915
|
augment=augment)
|
|
901
916
|
|
|
902
917
|
if checkpoint_queue is not None:
|
|
@@ -918,7 +933,7 @@ def _process_image(im_file,
|
|
|
918
933
|
image_size=None,
|
|
919
934
|
include_image_size=False,
|
|
920
935
|
include_image_timestamp=False,
|
|
921
|
-
|
|
936
|
+
include_exif_tags=False,
|
|
922
937
|
augment=False):
|
|
923
938
|
"""
|
|
924
939
|
Runs a detector (typically MegaDetector) on a single image file.
|
|
@@ -936,7 +951,7 @@ def _process_image(im_file,
|
|
|
936
951
|
doing
|
|
937
952
|
include_image_size (bool, optional): should we include image size in the output for each image?
|
|
938
953
|
include_image_timestamp (bool, optional): should we include image timestamps in the output for each image?
|
|
939
|
-
|
|
954
|
+
include_exif_tags (str, optional): comma-separated list of EXIF tags to include in output
|
|
940
955
|
augment (bool, optional): enable image augmentation
|
|
941
956
|
|
|
942
957
|
Returns:
|
|
@@ -989,7 +1004,9 @@ def _process_image(im_file,
|
|
|
989
1004
|
if include_image_timestamp:
|
|
990
1005
|
result['datetime'] = get_image_datetime(image)
|
|
991
1006
|
|
|
992
|
-
if
|
|
1007
|
+
if include_exif_tags is not None:
|
|
1008
|
+
exif_options = copy.copy(exif_options_base)
|
|
1009
|
+
exif_options.tags_to_include = include_exif_tags
|
|
993
1010
|
result['exif_metadata'] = read_exif.read_pil_exif(image,exif_options)
|
|
994
1011
|
|
|
995
1012
|
return result
|
|
@@ -1044,13 +1061,14 @@ def load_and_run_detector_batch(model_file,
|
|
|
1044
1061
|
class_mapping_filename=None,
|
|
1045
1062
|
include_image_size=False,
|
|
1046
1063
|
include_image_timestamp=False,
|
|
1047
|
-
|
|
1064
|
+
include_exif_tags=None,
|
|
1048
1065
|
augment=False,
|
|
1049
1066
|
force_model_download=False,
|
|
1050
1067
|
detector_options=None,
|
|
1051
1068
|
loader_workers=default_loaders,
|
|
1052
1069
|
preprocess_on_image_queue=default_preprocess_on_image_queue,
|
|
1053
|
-
batch_size=1
|
|
1070
|
+
batch_size=1,
|
|
1071
|
+
verbose_output=False):
|
|
1054
1072
|
"""
|
|
1055
1073
|
Load a model file and run it on a list of images.
|
|
1056
1074
|
|
|
@@ -1076,7 +1094,7 @@ def load_and_run_detector_batch(model_file,
|
|
|
1076
1094
|
file or YOLOv5 dataset.yaml file
|
|
1077
1095
|
include_image_size (bool, optional): should we include image size in the output for each image?
|
|
1078
1096
|
include_image_timestamp (bool, optional): should we include image timestamps in the output for each image?
|
|
1079
|
-
|
|
1097
|
+
include_exif_tags (str, optional): comma-separated list of EXIF tags to include in output
|
|
1080
1098
|
augment (bool, optional): enable image augmentation
|
|
1081
1099
|
force_model_download (bool, optional): force downloading the model file if
|
|
1082
1100
|
a named model (e.g. "MDV5A") is supplied, even if the local file already
|
|
@@ -1087,6 +1105,7 @@ def load_and_run_detector_batch(model_file,
|
|
|
1087
1105
|
preprocess_on_image_queue (bool, optional): if the image queue is enabled, should it handle
|
|
1088
1106
|
image loading and preprocessing (True), or just image loading (False)?
|
|
1089
1107
|
batch_size (int, optional): batch size for GPU processing, automatically set to 1 for CPU processing
|
|
1108
|
+
verbose_output (bool, optional): enable additional debug output
|
|
1090
1109
|
|
|
1091
1110
|
Returns:
|
|
1092
1111
|
results: list of dicts; each dict represents detections on one image
|
|
@@ -1109,6 +1128,11 @@ def load_and_run_detector_batch(model_file,
|
|
|
1109
1128
|
if class_mapping_filename is not None:
|
|
1110
1129
|
_load_custom_class_mapping(class_mapping_filename)
|
|
1111
1130
|
|
|
1131
|
+
global verbose
|
|
1132
|
+
if verbose_output:
|
|
1133
|
+
print('Enabling verbose output')
|
|
1134
|
+
verbose = True
|
|
1135
|
+
|
|
1112
1136
|
# Handle the case where image_file_names is not yet actually a list
|
|
1113
1137
|
if isinstance(image_file_names,str):
|
|
1114
1138
|
|
|
@@ -1189,7 +1213,7 @@ def load_and_run_detector_batch(model_file,
|
|
|
1189
1213
|
image_size=image_size,
|
|
1190
1214
|
include_image_size=include_image_size,
|
|
1191
1215
|
include_image_timestamp=include_image_timestamp,
|
|
1192
|
-
|
|
1216
|
+
include_exif_tags=include_exif_tags,
|
|
1193
1217
|
augment=augment,
|
|
1194
1218
|
detector_options=detector_options,
|
|
1195
1219
|
loader_workers=loader_workers,
|
|
@@ -1251,7 +1275,7 @@ def load_and_run_detector_batch(model_file,
|
|
|
1251
1275
|
image_size=image_size,
|
|
1252
1276
|
include_image_size=include_image_size,
|
|
1253
1277
|
include_image_timestamp=include_image_timestamp,
|
|
1254
|
-
|
|
1278
|
+
include_exif_tags=include_exif_tags,
|
|
1255
1279
|
augment=augment)
|
|
1256
1280
|
|
|
1257
1281
|
results.extend(batch_results)
|
|
@@ -1277,7 +1301,7 @@ def load_and_run_detector_batch(model_file,
|
|
|
1277
1301
|
image_size=image_size,
|
|
1278
1302
|
include_image_size=include_image_size,
|
|
1279
1303
|
include_image_timestamp=include_image_timestamp,
|
|
1280
|
-
|
|
1304
|
+
include_exif_tags=include_exif_tags,
|
|
1281
1305
|
augment=augment)
|
|
1282
1306
|
results.append(result)
|
|
1283
1307
|
|
|
@@ -1336,7 +1360,7 @@ def load_and_run_detector_batch(model_file,
|
|
|
1336
1360
|
checkpoint_queue=checkpoint_queue,
|
|
1337
1361
|
include_image_size=include_image_size,
|
|
1338
1362
|
include_image_timestamp=include_image_timestamp,
|
|
1339
|
-
|
|
1363
|
+
include_exif_tags=include_exif_tags,
|
|
1340
1364
|
augment=augment,
|
|
1341
1365
|
detector_options=detector_options),
|
|
1342
1366
|
image_chunks)
|
|
@@ -1356,7 +1380,7 @@ def load_and_run_detector_batch(model_file,
|
|
|
1356
1380
|
image_size=image_size,
|
|
1357
1381
|
include_image_size=include_image_size,
|
|
1358
1382
|
include_image_timestamp=include_image_timestamp,
|
|
1359
|
-
|
|
1383
|
+
include_exif_tags=include_exif_tags,
|
|
1360
1384
|
augment=augment,
|
|
1361
1385
|
detector_options=detector_options),
|
|
1362
1386
|
image_chunks)
|
|
@@ -1477,7 +1501,7 @@ def get_image_datetime(image):
|
|
|
1477
1501
|
returns None if EXIF datetime is not available.
|
|
1478
1502
|
"""
|
|
1479
1503
|
|
|
1480
|
-
exif_tags = read_exif.read_pil_exif(image,
|
|
1504
|
+
exif_tags = read_exif.read_pil_exif(image,exif_options_base)
|
|
1481
1505
|
|
|
1482
1506
|
try:
|
|
1483
1507
|
datetime_str = exif_tags['DateTimeOriginal']
|
|
@@ -1636,7 +1660,7 @@ if False:
|
|
|
1636
1660
|
class_mapping_filename = None
|
|
1637
1661
|
include_image_size = True
|
|
1638
1662
|
include_image_timestamp = True
|
|
1639
|
-
|
|
1663
|
+
include_exif_tags = None
|
|
1640
1664
|
overwrite_handling = None
|
|
1641
1665
|
|
|
1642
1666
|
# Generate a command line
|
|
@@ -1671,8 +1695,8 @@ if False:
|
|
|
1671
1695
|
cmd += ' --include_image_size'
|
|
1672
1696
|
if include_image_timestamp:
|
|
1673
1697
|
cmd += ' --include_image_timestamp'
|
|
1674
|
-
if
|
|
1675
|
-
cmd += ' --
|
|
1698
|
+
if include_exif_tags is not None:
|
|
1699
|
+
cmd += ' --include_exif_tags "{}"'.format(include_exif_tags)
|
|
1676
1700
|
if overwrite_handling is not None:
|
|
1677
1701
|
cmd += ' --overwrite_handling {}'.format(overwrite_handling)
|
|
1678
1702
|
|
|
@@ -1819,9 +1843,10 @@ def main(): # noqa
|
|
|
1819
1843
|
help='Include image datetime (if available) in output file'
|
|
1820
1844
|
)
|
|
1821
1845
|
parser.add_argument(
|
|
1822
|
-
'--
|
|
1823
|
-
|
|
1824
|
-
|
|
1846
|
+
'--include_exif_tags',
|
|
1847
|
+
type=str,
|
|
1848
|
+
default=None,
|
|
1849
|
+
help='Command-separated list of EXIF tags to include in output, or "all" to include all tags'
|
|
1825
1850
|
)
|
|
1826
1851
|
parser.add_argument(
|
|
1827
1852
|
'--overwrite_handling',
|
|
@@ -1860,20 +1885,26 @@ def main(): # noqa
|
|
|
1860
1885
|
action='store_true',
|
|
1861
1886
|
help=argparse.SUPPRESS)
|
|
1862
1887
|
|
|
1888
|
+
# This argument is deprecated in favor use --include_exif_tags
|
|
1889
|
+
parser.add_argument(
|
|
1890
|
+
'--include_exif_data',
|
|
1891
|
+
action='store_true',
|
|
1892
|
+
help=argparse.SUPPRESS)
|
|
1893
|
+
|
|
1863
1894
|
if len(sys.argv[1:]) == 0:
|
|
1864
1895
|
parser.print_help()
|
|
1865
1896
|
parser.exit()
|
|
1866
1897
|
|
|
1867
1898
|
args = parser.parse_args()
|
|
1868
1899
|
|
|
1869
|
-
global verbose
|
|
1870
1900
|
global use_threads_for_queue
|
|
1871
|
-
|
|
1872
|
-
if args.verbose:
|
|
1873
|
-
verbose = True
|
|
1874
1901
|
if args.use_threads_for_queue:
|
|
1875
1902
|
use_threads_for_queue = True
|
|
1876
1903
|
|
|
1904
|
+
# Support the legacy --include_exif_data flag
|
|
1905
|
+
if args.include_exif_data and (args.include_exif_tags is None):
|
|
1906
|
+
args.include_exif_tags = 'all'
|
|
1907
|
+
|
|
1877
1908
|
detector_options = parse_kvp_list(args.detector_options)
|
|
1878
1909
|
|
|
1879
1910
|
# If the specified detector file is really the name of a known model, find
|
|
@@ -2080,14 +2111,15 @@ def main(): # noqa
|
|
|
2080
2111
|
class_mapping_filename=args.class_mapping_filename,
|
|
2081
2112
|
include_image_size=args.include_image_size,
|
|
2082
2113
|
include_image_timestamp=args.include_image_timestamp,
|
|
2083
|
-
|
|
2114
|
+
include_exif_tags=args.include_exif_tags,
|
|
2084
2115
|
augment=args.augment,
|
|
2085
2116
|
# Don't download the model *again*
|
|
2086
2117
|
force_model_download=False,
|
|
2087
2118
|
detector_options=detector_options,
|
|
2088
2119
|
loader_workers=args.loader_workers,
|
|
2089
2120
|
preprocess_on_image_queue=args.preprocess_on_image_queue,
|
|
2090
|
-
batch_size=args.batch_size
|
|
2121
|
+
batch_size=args.batch_size,
|
|
2122
|
+
verbose_output=args.verbose)
|
|
2091
2123
|
|
|
2092
2124
|
elapsed = time.time() - start_time
|
|
2093
2125
|
images_per_second = len(results) / elapsed
|