megadetector 5.0.7__py3-none-any.whl → 5.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of megadetector might be problematic. Click here for more details.
- api/__init__.py +0 -0
- api/batch_processing/__init__.py +0 -0
- api/batch_processing/api_core/__init__.py +0 -0
- api/batch_processing/api_core/batch_service/__init__.py +0 -0
- api/batch_processing/api_core/batch_service/score.py +0 -1
- api/batch_processing/api_core/server_job_status_table.py +0 -1
- api/batch_processing/api_core_support/__init__.py +0 -0
- api/batch_processing/api_core_support/aggregate_results_manually.py +0 -1
- api/batch_processing/api_support/__init__.py +0 -0
- api/batch_processing/api_support/summarize_daily_activity.py +0 -1
- api/batch_processing/data_preparation/__init__.py +0 -0
- api/batch_processing/data_preparation/manage_local_batch.py +93 -79
- api/batch_processing/data_preparation/manage_video_batch.py +8 -8
- api/batch_processing/integration/digiKam/xmp_integration.py +0 -1
- api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +0 -1
- api/batch_processing/postprocessing/__init__.py +0 -0
- api/batch_processing/postprocessing/add_max_conf.py +12 -12
- api/batch_processing/postprocessing/categorize_detections_by_size.py +32 -14
- api/batch_processing/postprocessing/combine_api_outputs.py +69 -55
- api/batch_processing/postprocessing/compare_batch_results.py +114 -44
- api/batch_processing/postprocessing/convert_output_format.py +62 -19
- api/batch_processing/postprocessing/load_api_results.py +17 -20
- api/batch_processing/postprocessing/md_to_coco.py +31 -21
- api/batch_processing/postprocessing/md_to_labelme.py +165 -68
- api/batch_processing/postprocessing/merge_detections.py +40 -15
- api/batch_processing/postprocessing/postprocess_batch_results.py +270 -186
- api/batch_processing/postprocessing/remap_detection_categories.py +170 -0
- api/batch_processing/postprocessing/render_detection_confusion_matrix.py +75 -39
- api/batch_processing/postprocessing/repeat_detection_elimination/find_repeat_detections.py +53 -44
- api/batch_processing/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +25 -14
- api/batch_processing/postprocessing/repeat_detection_elimination/repeat_detections_core.py +244 -160
- api/batch_processing/postprocessing/separate_detections_into_folders.py +159 -114
- api/batch_processing/postprocessing/subset_json_detector_output.py +146 -169
- api/batch_processing/postprocessing/top_folders_to_bottom.py +77 -43
- api/synchronous/__init__.py +0 -0
- api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
- api/synchronous/api_core/animal_detection_api/api_backend.py +0 -2
- api/synchronous/api_core/animal_detection_api/api_frontend.py +266 -268
- api/synchronous/api_core/animal_detection_api/config.py +35 -35
- api/synchronous/api_core/tests/__init__.py +0 -0
- api/synchronous/api_core/tests/load_test.py +109 -109
- classification/__init__.py +0 -0
- classification/aggregate_classifier_probs.py +21 -24
- classification/analyze_failed_images.py +11 -13
- classification/cache_batchapi_outputs.py +51 -51
- classification/create_classification_dataset.py +69 -68
- classification/crop_detections.py +54 -53
- classification/csv_to_json.py +97 -100
- classification/detect_and_crop.py +105 -105
- classification/evaluate_model.py +43 -42
- classification/identify_mislabeled_candidates.py +47 -46
- classification/json_to_azcopy_list.py +10 -10
- classification/json_validator.py +72 -71
- classification/map_classification_categories.py +44 -43
- classification/merge_classification_detection_output.py +68 -68
- classification/prepare_classification_script.py +157 -154
- classification/prepare_classification_script_mc.py +228 -228
- classification/run_classifier.py +27 -26
- classification/save_mislabeled.py +30 -30
- classification/train_classifier.py +20 -20
- classification/train_classifier_tf.py +21 -22
- classification/train_utils.py +10 -10
- data_management/__init__.py +0 -0
- data_management/annotations/__init__.py +0 -0
- data_management/annotations/annotation_constants.py +18 -31
- data_management/camtrap_dp_to_coco.py +238 -0
- data_management/cct_json_utils.py +107 -59
- data_management/cct_to_md.py +176 -158
- data_management/cct_to_wi.py +247 -219
- data_management/coco_to_labelme.py +272 -0
- data_management/coco_to_yolo.py +86 -62
- data_management/databases/__init__.py +0 -0
- data_management/databases/add_width_and_height_to_db.py +20 -16
- data_management/databases/combine_coco_camera_traps_files.py +35 -31
- data_management/databases/integrity_check_json_db.py +130 -83
- data_management/databases/subset_json_db.py +25 -16
- data_management/generate_crops_from_cct.py +27 -45
- data_management/get_image_sizes.py +188 -144
- data_management/importers/add_nacti_sizes.py +8 -8
- data_management/importers/add_timestamps_to_icct.py +78 -78
- data_management/importers/animl_results_to_md_results.py +158 -160
- data_management/importers/auckland_doc_test_to_json.py +9 -9
- data_management/importers/auckland_doc_to_json.py +8 -8
- data_management/importers/awc_to_json.py +7 -7
- data_management/importers/bellevue_to_json.py +15 -15
- data_management/importers/cacophony-thermal-importer.py +13 -13
- data_management/importers/carrizo_shrubfree_2018.py +8 -8
- data_management/importers/carrizo_trail_cam_2017.py +8 -8
- data_management/importers/cct_field_adjustments.py +9 -9
- data_management/importers/channel_islands_to_cct.py +10 -10
- data_management/importers/eMammal/copy_and_unzip_emammal.py +1 -0
- data_management/importers/ena24_to_json.py +7 -7
- data_management/importers/filenames_to_json.py +8 -8
- data_management/importers/helena_to_cct.py +7 -7
- data_management/importers/idaho-camera-traps.py +7 -7
- data_management/importers/idfg_iwildcam_lila_prep.py +10 -10
- data_management/importers/jb_csv_to_json.py +9 -9
- data_management/importers/mcgill_to_json.py +8 -8
- data_management/importers/missouri_to_json.py +18 -18
- data_management/importers/nacti_fieldname_adjustments.py +10 -10
- data_management/importers/noaa_seals_2019.py +8 -8
- data_management/importers/pc_to_json.py +7 -7
- data_management/importers/plot_wni_giraffes.py +7 -7
- data_management/importers/prepare-noaa-fish-data-for-lila.py +359 -359
- data_management/importers/prepare_zsl_imerit.py +7 -7
- data_management/importers/rspb_to_json.py +8 -8
- data_management/importers/save_the_elephants_survey_A.py +8 -8
- data_management/importers/save_the_elephants_survey_B.py +9 -9
- data_management/importers/snapshot_safari_importer.py +26 -26
- data_management/importers/snapshot_safari_importer_reprise.py +665 -665
- data_management/importers/snapshot_serengeti_lila.py +14 -14
- data_management/importers/sulross_get_exif.py +8 -9
- data_management/importers/timelapse_csv_set_to_json.py +11 -11
- data_management/importers/ubc_to_json.py +13 -13
- data_management/importers/umn_to_json.py +7 -7
- data_management/importers/wellington_to_json.py +8 -8
- data_management/importers/wi_to_json.py +9 -9
- data_management/importers/zamba_results_to_md_results.py +181 -181
- data_management/labelme_to_coco.py +309 -159
- data_management/labelme_to_yolo.py +103 -60
- data_management/lila/__init__.py +0 -0
- data_management/lila/add_locations_to_island_camera_traps.py +9 -9
- data_management/lila/add_locations_to_nacti.py +147 -147
- data_management/lila/create_lila_blank_set.py +114 -31
- data_management/lila/create_lila_test_set.py +8 -8
- data_management/lila/create_links_to_md_results_files.py +106 -106
- data_management/lila/download_lila_subset.py +92 -90
- data_management/lila/generate_lila_per_image_labels.py +56 -43
- data_management/lila/get_lila_annotation_counts.py +18 -15
- data_management/lila/get_lila_image_counts.py +11 -11
- data_management/lila/lila_common.py +103 -70
- data_management/lila/test_lila_metadata_urls.py +132 -116
- data_management/ocr_tools.py +173 -128
- data_management/read_exif.py +161 -99
- data_management/remap_coco_categories.py +84 -0
- data_management/remove_exif.py +58 -62
- data_management/resize_coco_dataset.py +32 -44
- data_management/wi_download_csv_to_coco.py +246 -0
- data_management/yolo_output_to_md_output.py +86 -73
- data_management/yolo_to_coco.py +535 -95
- detection/__init__.py +0 -0
- detection/detector_training/__init__.py +0 -0
- detection/process_video.py +85 -33
- detection/pytorch_detector.py +43 -25
- detection/run_detector.py +157 -72
- detection/run_detector_batch.py +189 -114
- detection/run_inference_with_yolov5_val.py +118 -51
- detection/run_tiled_inference.py +113 -42
- detection/tf_detector.py +51 -28
- detection/video_utils.py +606 -521
- docs/source/conf.py +43 -0
- md_utils/__init__.py +0 -0
- md_utils/azure_utils.py +9 -9
- md_utils/ct_utils.py +249 -70
- md_utils/directory_listing.py +59 -64
- md_utils/md_tests.py +968 -862
- md_utils/path_utils.py +655 -155
- md_utils/process_utils.py +157 -133
- md_utils/sas_blob_utils.py +20 -20
- md_utils/split_locations_into_train_val.py +45 -32
- md_utils/string_utils.py +33 -10
- md_utils/url_utils.py +208 -27
- md_utils/write_html_image_list.py +51 -35
- md_visualization/__init__.py +0 -0
- md_visualization/plot_utils.py +102 -109
- md_visualization/render_images_with_thumbnails.py +34 -34
- md_visualization/visualization_utils.py +908 -311
- md_visualization/visualize_db.py +109 -58
- md_visualization/visualize_detector_output.py +61 -42
- {megadetector-5.0.7.dist-info → megadetector-5.0.9.dist-info}/METADATA +21 -17
- megadetector-5.0.9.dist-info/RECORD +224 -0
- {megadetector-5.0.7.dist-info → megadetector-5.0.9.dist-info}/WHEEL +1 -1
- {megadetector-5.0.7.dist-info → megadetector-5.0.9.dist-info}/top_level.txt +1 -0
- taxonomy_mapping/__init__.py +0 -0
- taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +342 -335
- taxonomy_mapping/map_new_lila_datasets.py +154 -154
- taxonomy_mapping/prepare_lila_taxonomy_release.py +142 -134
- taxonomy_mapping/preview_lila_taxonomy.py +591 -591
- taxonomy_mapping/retrieve_sample_image.py +12 -12
- taxonomy_mapping/simple_image_download.py +11 -11
- taxonomy_mapping/species_lookup.py +10 -10
- taxonomy_mapping/taxonomy_csv_checker.py +18 -18
- taxonomy_mapping/taxonomy_graph.py +47 -47
- taxonomy_mapping/validate_lila_category_mappings.py +83 -76
- data_management/cct_json_to_filename_json.py +0 -89
- data_management/cct_to_csv.py +0 -140
- data_management/databases/remove_corrupted_images_from_db.py +0 -191
- detection/detector_training/copy_checkpoints.py +0 -43
- md_visualization/visualize_megadb.py +0 -183
- megadetector-5.0.7.dist-info/RECORD +0 -202
- {megadetector-5.0.7.dist-info → megadetector-5.0.9.dist-info}/LICENSE +0 -0
data_management/cct_to_wi.py
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
cct_to_wi.py
|
|
4
|
+
|
|
5
|
+
Converts COCO Camera Traps .json files to the Wildlife Insights
|
|
6
|
+
batch upload format.
|
|
7
|
+
|
|
8
|
+
**This is very much just a demo script; all the relevant constants are hard-coded
|
|
9
|
+
at the top of main().**
|
|
10
|
+
|
|
11
|
+
But given that caveat, it works. You need to set up all the paths in the "paths" cell
|
|
12
|
+
at the top of main().
|
|
13
|
+
|
|
14
|
+
Also see:
|
|
15
|
+
|
|
16
|
+
* https://github.com/ConservationInternational/Wildlife-Insights----Data-Migration
|
|
17
|
+
* https://data.naturalsciences.org/wildlife-insights/taxonomy/search
|
|
18
|
+
|
|
19
|
+
"""
|
|
15
20
|
|
|
16
21
|
#%% Imports
|
|
17
22
|
|
|
@@ -21,241 +26,264 @@ import pandas as pd
|
|
|
21
26
|
from collections import defaultdict
|
|
22
27
|
|
|
23
28
|
|
|
24
|
-
#%%
|
|
25
|
-
|
|
26
|
-
# A COCO camera traps file with information about this dataset
|
|
27
|
-
input_file = r'c:\temp\camera_trap_images_no_people\bellevue_camera_traps.2020-12-26.json'
|
|
28
|
-
assert os.path.isfile(input_file)
|
|
29
|
-
|
|
30
|
-
# A .json dictionary mapping common names in this dataset to dictionaries with the
|
|
31
|
-
# WI taxonomy fields: common_name, wi_taxon_id, class, orer, family, genus, species
|
|
32
|
-
taxonomy_file = r'c:\temp\camera_trap_images_no_people\belleve_camera_traps_to_wi.json'
|
|
33
|
-
assert os.path.isfile(taxonomy_file)
|
|
29
|
+
#%% Main wrapper
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
def main():
|
|
32
|
+
"""
|
|
33
|
+
Converts COCO Camera Traps .json files to the Wildlife Insights
|
|
34
|
+
batch upload format; to use this, you need to modify all the paths in the "Paths"
|
|
35
|
+
cell.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
#%% Paths
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
# A COCO camera traps file with information about this dataset
|
|
41
|
+
input_file = r'c:\temp\camera_trap_images_no_people\bellevue_camera_traps.2020-12-26.json'
|
|
42
|
+
|
|
43
|
+
# A .json dictionary mapping common names in this dataset to dictionaries with the
|
|
44
|
+
# WI taxonomy fields: common_name, wi_taxon_id, class, order, family, genus, species
|
|
45
|
+
taxonomy_file = r'c:\temp\camera_trap_images_no_people\bellevue_camera_traps_to_wi.json'
|
|
40
46
|
|
|
47
|
+
# The folder where the .csv template files live
|
|
48
|
+
templates_dir = r'c:\temp\wi_batch_upload_templates'
|
|
49
|
+
|
|
50
|
+
# The folder to which you want to write WI-formatted .csv files
|
|
51
|
+
output_base = r'c:\temp\wi_output'
|
|
41
52
|
|
|
42
|
-
#%% Constants
|
|
43
|
-
|
|
44
|
-
projects_file_name = 'Template Wildlife Insights Batch Upload - Projectv1.0.csv'
|
|
45
|
-
deployments_file_name = 'Template Wildlife Insights Batch Upload - Deploymentv1.0.csv'
|
|
46
|
-
images_file_name = 'Template Wildlife Insights Batch Upload - Imagev1.0.csv'
|
|
47
|
-
cameras_file_name = 'Template Wildlife Insights Batch Upload - Camerav1.0.csv'
|
|
48
|
-
|
|
49
|
-
assert all([os.path.isfile(os.path.join(templates_dir,fn)) for fn in \
|
|
50
|
-
[projects_file_name,deployments_file_name,images_file_name,cameras_file_name]])
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
#%% Project information
|
|
54
|
-
|
|
55
|
-
project_info = {}
|
|
56
|
-
project_info['project_name'] = 'Bellevue Camera Traps'
|
|
57
|
-
project_info['project_id'] = 'bct_001'
|
|
58
|
-
project_info['project_short_name'] = 'BCT'
|
|
59
|
-
project_info['project_objectives'] = 'none'
|
|
60
|
-
project_info['project_species'] = 'Multiple'
|
|
61
|
-
project_info['project_species_individual'] = ''
|
|
62
|
-
project_info['project_sensor_layout'] = 'Convenience'
|
|
63
|
-
project_info['project_sensor_layout_targeted_type'] = ''
|
|
64
|
-
project_info['project_bait_use'] = 'No'
|
|
65
|
-
project_info['project_bait_type'] = 'None'
|
|
66
|
-
project_info['project_stratification'] = 'No'
|
|
67
|
-
project_info['project_stratification_type'] = ''
|
|
68
|
-
project_info['project_sensor_method'] = 'Sensor Detection'
|
|
69
|
-
project_info['project_individual_animals'] = 'No'
|
|
70
|
-
project_info['project_admin'] = 'Dan Morris'
|
|
71
|
-
project_info['project_admin_email'] = 'cameratraps@lila.science'
|
|
72
|
-
project_info['country_code'] = 'USA'
|
|
73
|
-
project_info['embargo'] = str(0)
|
|
74
|
-
project_info['initiative_id'] = ''
|
|
75
|
-
project_info['metadata_license'] = 'CC0'
|
|
76
|
-
project_info['image_license'] = 'CC0'
|
|
77
|
-
|
|
78
|
-
project_info['project_blank_images'] = 'No'
|
|
79
|
-
project_info['project_sensor_cluster'] = 'No'
|
|
80
|
-
|
|
81
|
-
camera_info = {}
|
|
82
|
-
camera_info['project_id'] = project_info['project_id']
|
|
83
|
-
camera_info['camera_id'] = '0000'
|
|
84
|
-
camera_info['make'] = ''
|
|
85
|
-
camera_info['model'] = ''
|
|
86
|
-
camera_info['serial_number'] = ''
|
|
87
|
-
camera_info['year_purchased'] = ''
|
|
88
|
-
|
|
89
|
-
deployment_info = {}
|
|
90
|
-
|
|
91
|
-
deployment_info['project_id'] = project_info['project_id']
|
|
92
|
-
deployment_info['deployment_id'] = 'test_deployment'
|
|
93
|
-
deployment_info['subproject_name'] = 'test_subproject'
|
|
94
|
-
deployment_info['subproject_design'] = ''
|
|
95
|
-
deployment_info['placename'] = 'yard'
|
|
96
|
-
deployment_info['longitude'] = '47.6101'
|
|
97
|
-
deployment_info['latitude'] = '-122.2015'
|
|
98
|
-
deployment_info['start_date'] = '2016-01-01 00:00:00'
|
|
99
|
-
deployment_info['end_date'] = '2026-01-01 00:00:00'
|
|
100
|
-
deployment_info['event_name'] = ''
|
|
101
|
-
deployment_info['event_description'] = ''
|
|
102
|
-
deployment_info['event_type'] = ''
|
|
103
|
-
deployment_info['bait_type'] = ''
|
|
104
|
-
deployment_info['bait_description'] = ''
|
|
105
|
-
deployment_info['feature_type'] = 'None'
|
|
106
|
-
deployment_info['feature_type_methodology'] = ''
|
|
107
|
-
deployment_info['camera_id'] = camera_info['camera_id']
|
|
108
|
-
deployment_info['quiet_period'] = str(60)
|
|
109
|
-
deployment_info['camera_functioning'] = 'Camera Functioning'
|
|
110
|
-
deployment_info['sensor_height'] = 'Chest height'
|
|
111
|
-
deployment_info['height_other'] = ''
|
|
112
|
-
deployment_info['sensor_orientation'] = 'Parallel'
|
|
113
|
-
deployment_info['orientation_other'] = ''
|
|
114
|
-
deployment_info['recorded_by'] = 'Dan Morris'
|
|
115
|
-
|
|
116
|
-
image_info = {}
|
|
117
|
-
image_info['identified_by'] = 'Dan Morris'
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
#%% Read templates
|
|
121
|
-
|
|
122
|
-
def parse_fields(templates_dir,file_name):
|
|
123
53
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return fields
|
|
54
|
+
#%% Path validation
|
|
55
|
+
|
|
56
|
+
assert os.path.isfile(input_file)
|
|
57
|
+
assert os.path.isfile(taxonomy_file)
|
|
58
|
+
assert os.path.isdir(templates_dir)
|
|
59
|
+
os.makedirs(output_base,exist_ok = True)
|
|
131
60
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
61
|
+
|
|
62
|
+
#%% Constants
|
|
63
|
+
|
|
64
|
+
projects_file_name = 'Template Wildlife Insights Batch Upload - Projectv1.0.csv'
|
|
65
|
+
deployments_file_name = 'Template Wildlife Insights Batch Upload - Deploymentv1.0.csv'
|
|
66
|
+
images_file_name = 'Template Wildlife Insights Batch Upload - Imagev1.0.csv'
|
|
67
|
+
cameras_file_name = 'Template Wildlife Insights Batch Upload - Camerav1.0.csv'
|
|
68
|
+
|
|
69
|
+
assert all([os.path.isfile(os.path.join(templates_dir,fn)) for fn in \
|
|
70
|
+
[projects_file_name,deployments_file_name,images_file_name,cameras_file_name]])
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
#%% Project information
|
|
74
|
+
|
|
75
|
+
project_info = {}
|
|
76
|
+
project_info['project_name'] = 'Bellevue Camera Traps'
|
|
77
|
+
project_info['project_id'] = 'bct_001'
|
|
78
|
+
project_info['project_short_name'] = 'BCT'
|
|
79
|
+
project_info['project_objectives'] = 'none'
|
|
80
|
+
project_info['project_species'] = 'Multiple'
|
|
81
|
+
project_info['project_species_individual'] = ''
|
|
82
|
+
project_info['project_sensor_layout'] = 'Convenience'
|
|
83
|
+
project_info['project_sensor_layout_targeted_type'] = ''
|
|
84
|
+
project_info['project_bait_use'] = 'No'
|
|
85
|
+
project_info['project_bait_type'] = 'None'
|
|
86
|
+
project_info['project_stratification'] = 'No'
|
|
87
|
+
project_info['project_stratification_type'] = ''
|
|
88
|
+
project_info['project_sensor_method'] = 'Sensor Detection'
|
|
89
|
+
project_info['project_individual_animals'] = 'No'
|
|
90
|
+
project_info['project_admin'] = 'Dan Morris'
|
|
91
|
+
project_info['project_admin_email'] = 'cameratraps@lila.science'
|
|
92
|
+
project_info['country_code'] = 'USA'
|
|
93
|
+
project_info['embargo'] = str(0)
|
|
94
|
+
project_info['initiative_id'] = ''
|
|
95
|
+
project_info['metadata_license'] = 'CC0'
|
|
96
|
+
project_info['image_license'] = 'CC0'
|
|
97
|
+
|
|
98
|
+
project_info['project_blank_images'] = 'No'
|
|
99
|
+
project_info['project_sensor_cluster'] = 'No'
|
|
100
|
+
|
|
101
|
+
camera_info = {}
|
|
102
|
+
camera_info['project_id'] = project_info['project_id']
|
|
103
|
+
camera_info['camera_id'] = '0000'
|
|
104
|
+
camera_info['make'] = ''
|
|
105
|
+
camera_info['model'] = ''
|
|
106
|
+
camera_info['serial_number'] = ''
|
|
107
|
+
camera_info['year_purchased'] = ''
|
|
108
|
+
|
|
109
|
+
deployment_info = {}
|
|
110
|
+
|
|
111
|
+
deployment_info['project_id'] = project_info['project_id']
|
|
112
|
+
deployment_info['deployment_id'] = 'test_deployment'
|
|
113
|
+
deployment_info['subproject_name'] = 'test_subproject'
|
|
114
|
+
deployment_info['subproject_design'] = ''
|
|
115
|
+
deployment_info['placename'] = 'yard'
|
|
116
|
+
deployment_info['longitude'] = '47.6101'
|
|
117
|
+
deployment_info['latitude'] = '-122.2015'
|
|
118
|
+
deployment_info['start_date'] = '2016-01-01 00:00:00'
|
|
119
|
+
deployment_info['end_date'] = '2026-01-01 00:00:00'
|
|
120
|
+
deployment_info['event_name'] = ''
|
|
121
|
+
deployment_info['event_description'] = ''
|
|
122
|
+
deployment_info['event_type'] = ''
|
|
123
|
+
deployment_info['bait_type'] = ''
|
|
124
|
+
deployment_info['bait_description'] = ''
|
|
125
|
+
deployment_info['feature_type'] = 'None'
|
|
126
|
+
deployment_info['feature_type_methodology'] = ''
|
|
127
|
+
deployment_info['camera_id'] = camera_info['camera_id']
|
|
128
|
+
deployment_info['quiet_period'] = str(60)
|
|
129
|
+
deployment_info['camera_functioning'] = 'Camera Functioning'
|
|
130
|
+
deployment_info['sensor_height'] = 'Chest height'
|
|
131
|
+
deployment_info['height_other'] = ''
|
|
132
|
+
deployment_info['sensor_orientation'] = 'Parallel'
|
|
133
|
+
deployment_info['orientation_other'] = ''
|
|
134
|
+
deployment_info['recorded_by'] = 'Dan Morris'
|
|
135
|
+
|
|
136
|
+
image_info = {}
|
|
137
|
+
image_info['identified_by'] = 'Dan Morris'
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
#%% Read templates
|
|
141
|
+
|
|
142
|
+
def parse_fields(templates_dir,file_name):
|
|
143
|
+
|
|
144
|
+
with open(os.path.join(templates_dir,file_name),'r') as f:
|
|
145
|
+
lines = f.readlines()
|
|
146
|
+
lines = [s.strip() for s in lines if len(s.strip().replace(',','')) > 0]
|
|
147
|
+
assert len(lines) == 1, 'Error processing template {}'.format(file_name)
|
|
148
|
+
fields = lines[0].split(',')
|
|
149
|
+
print('Parsed {} columns from {}'.format(len(fields),file_name))
|
|
150
|
+
return fields
|
|
136
151
|
|
|
152
|
+
projects_fields = parse_fields(templates_dir,projects_file_name)
|
|
153
|
+
deployments_fields = parse_fields(templates_dir,deployments_file_name)
|
|
154
|
+
images_fields = parse_fields(templates_dir,images_file_name)
|
|
155
|
+
cameras_fields = parse_fields(templates_dir,cameras_file_name)
|
|
137
156
|
|
|
138
|
-
#%% Compare dictionary to template lists
|
|
139
157
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
for s in info.keys():
|
|
143
|
-
assert s in template_fields,'Field {} not specified in {}_fields'.format(s,name)
|
|
144
|
-
for s in template_fields:
|
|
145
|
-
assert s in info.keys(),'Field {} not specified in {}_info'.format(s,name)
|
|
158
|
+
#%% Compare dictionary to template lists
|
|
146
159
|
|
|
160
|
+
def compare_info_to_template(info,template_fields,name):
|
|
161
|
+
|
|
162
|
+
for s in info.keys():
|
|
163
|
+
assert s in template_fields,'Field {} not specified in {}_fields'.format(s,name)
|
|
164
|
+
for s in template_fields:
|
|
165
|
+
assert s in info.keys(),'Field {} not specified in {}_info'.format(s,name)
|
|
147
166
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
167
|
+
|
|
168
|
+
def write_table(file_name,info,template_fields):
|
|
169
|
+
|
|
170
|
+
assert len(info) == len(template_fields)
|
|
171
|
+
|
|
172
|
+
project_output_file = os.path.join(output_base,file_name)
|
|
173
|
+
with open(project_output_file,'w') as f:
|
|
174
|
+
|
|
175
|
+
# Write the header
|
|
176
|
+
for i_field,s in enumerate(template_fields):
|
|
177
|
+
f.write(s)
|
|
178
|
+
if i_field != len(template_fields)-1:
|
|
179
|
+
f.write(',')
|
|
180
|
+
f.write('\n')
|
|
181
|
+
|
|
182
|
+
# Write values
|
|
183
|
+
for i_field,s in enumerate(template_fields):
|
|
184
|
+
f.write(info[s])
|
|
185
|
+
if i_field != len(template_fields)-1:
|
|
186
|
+
f.write(',')
|
|
187
|
+
f.write('\n')
|
|
161
188
|
|
|
162
|
-
# Write values
|
|
163
|
-
for i_field,s in enumerate(template_fields):
|
|
164
|
-
f.write(info[s])
|
|
165
|
-
if i_field != len(template_fields)-1:
|
|
166
|
-
f.write(',')
|
|
167
|
-
f.write('\n')
|
|
168
|
-
|
|
169
189
|
|
|
170
|
-
#%% Project file
|
|
190
|
+
#%% Project file
|
|
171
191
|
|
|
172
|
-
compare_info_to_template(project_info,projects_fields,'project')
|
|
173
|
-
write_table(projects_file_name,project_info,projects_fields)
|
|
192
|
+
compare_info_to_template(project_info,projects_fields,'project')
|
|
193
|
+
write_table(projects_file_name,project_info,projects_fields)
|
|
174
194
|
|
|
175
195
|
|
|
176
|
-
#%% Camera file
|
|
196
|
+
#%% Camera file
|
|
177
197
|
|
|
178
|
-
compare_info_to_template(camera_info,cameras_fields,'camera')
|
|
179
|
-
write_table(cameras_file_name,camera_info,cameras_fields)
|
|
198
|
+
compare_info_to_template(camera_info,cameras_fields,'camera')
|
|
199
|
+
write_table(cameras_file_name,camera_info,cameras_fields)
|
|
180
200
|
|
|
181
201
|
|
|
182
|
-
#%% Deployment file
|
|
202
|
+
#%% Deployment file
|
|
183
203
|
|
|
184
|
-
compare_info_to_template(deployment_info,deployments_fields,'deployment')
|
|
185
|
-
write_table(deployments_file_name,deployment_info,deployments_fields)
|
|
204
|
+
compare_info_to_template(deployment_info,deployments_fields,'deployment')
|
|
205
|
+
write_table(deployments_file_name,deployment_info,deployments_fields)
|
|
186
206
|
|
|
187
207
|
|
|
188
|
-
#%% Images file
|
|
208
|
+
#%% Images file
|
|
189
209
|
|
|
190
|
-
# Read .json file with image information
|
|
191
|
-
with open(input_file,'r') as f:
|
|
192
|
-
|
|
210
|
+
# Read .json file with image information
|
|
211
|
+
with open(input_file,'r') as f:
|
|
212
|
+
input_data = json.load(f)
|
|
193
213
|
|
|
194
|
-
# Read taxonomy dictionary
|
|
195
|
-
with open(taxonomy_file,'r') as f:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
url_base = taxonomy_mapping['url_base']
|
|
199
|
-
taxonomy_mapping = taxonomy_mapping['taxonomy']
|
|
214
|
+
# Read taxonomy dictionary
|
|
215
|
+
with open(taxonomy_file,'r') as f:
|
|
216
|
+
taxonomy_mapping = json.load(f)
|
|
217
|
+
|
|
218
|
+
url_base = taxonomy_mapping['url_base']
|
|
219
|
+
taxonomy_mapping = taxonomy_mapping['taxonomy']
|
|
200
220
|
|
|
201
|
-
# Populate output information
|
|
202
|
-
# df = pd.DataFrame(columns = images_fields)
|
|
221
|
+
# Populate output information
|
|
222
|
+
# df = pd.DataFrame(columns = images_fields)
|
|
203
223
|
|
|
204
|
-
category_id_to_name = {cat['id']:cat['name'] for cat in input_data['categories']}
|
|
224
|
+
category_id_to_name = {cat['id']:cat['name'] for cat in input_data['categories']}
|
|
205
225
|
|
|
206
|
-
image_id_to_annotations = defaultdict(list)
|
|
226
|
+
image_id_to_annotations = defaultdict(list)
|
|
207
227
|
|
|
208
|
-
annotations = input_data['annotations']
|
|
209
|
-
|
|
210
|
-
# annotation = annotations[0]
|
|
211
|
-
for annotation in annotations:
|
|
212
|
-
|
|
213
|
-
|
|
228
|
+
annotations = input_data['annotations']
|
|
229
|
+
|
|
230
|
+
# annotation = annotations[0]
|
|
231
|
+
for annotation in annotations:
|
|
232
|
+
image_id_to_annotations[annotation['image_id']].append(
|
|
233
|
+
category_id_to_name[annotation['category_id']])
|
|
214
234
|
|
|
215
|
-
rows = []
|
|
235
|
+
rows = []
|
|
216
236
|
|
|
217
|
-
# im = input_data['images'][0]
|
|
218
|
-
for im in input_data['images']:
|
|
237
|
+
# im = input_data['images'][0]
|
|
238
|
+
for im in input_data['images']:
|
|
219
239
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
url = url_base + im['file_name'].replace('\\','/')
|
|
223
|
-
row['project_id'] = project_info['project_id']
|
|
224
|
-
row['deployment_id'] = deployment_info['deployment_id']
|
|
225
|
-
row['image_id'] = im['id']
|
|
226
|
-
row['location'] = url
|
|
227
|
-
row['identified_by'] = image_info['identified_by']
|
|
228
|
-
|
|
229
|
-
category_names = image_id_to_annotations[im['id']]
|
|
230
|
-
assert len(category_names) == 1
|
|
231
|
-
category_name = category_names[0]
|
|
232
|
-
|
|
233
|
-
taxon_info = taxonomy_mapping[category_name]
|
|
234
|
-
|
|
235
|
-
assert len(taxon_info.keys()) == 7
|
|
236
|
-
|
|
237
|
-
for s in taxon_info.keys():
|
|
238
|
-
row[s] = taxon_info[s]
|
|
239
|
-
|
|
240
|
-
# We don't have counts, but we can differentiate between zero and 1
|
|
241
|
-
if category_name == 'empty':
|
|
242
|
-
row['number_of_objects'] = 0
|
|
243
|
-
else:
|
|
244
|
-
row['number_of_objects'] = 1
|
|
240
|
+
row = {}
|
|
245
241
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
242
|
+
url = url_base + im['file_name'].replace('\\','/')
|
|
243
|
+
row['project_id'] = project_info['project_id']
|
|
244
|
+
row['deployment_id'] = deployment_info['deployment_id']
|
|
245
|
+
row['image_id'] = im['id']
|
|
246
|
+
row['location'] = url
|
|
247
|
+
row['identified_by'] = image_info['identified_by']
|
|
248
|
+
|
|
249
|
+
category_names = image_id_to_annotations[im['id']]
|
|
250
|
+
assert len(category_names) == 1
|
|
251
|
+
category_name = category_names[0]
|
|
252
|
+
|
|
253
|
+
taxon_info = taxonomy_mapping[category_name]
|
|
254
|
+
|
|
255
|
+
assert len(taxon_info.keys()) == 7
|
|
256
|
+
|
|
257
|
+
for s in taxon_info.keys():
|
|
258
|
+
row[s] = taxon_info[s]
|
|
259
|
+
|
|
260
|
+
# We don't have counts, but we can differentiate between zero and 1
|
|
261
|
+
if category_name == 'empty':
|
|
262
|
+
row['number_of_objects'] = 0
|
|
263
|
+
else:
|
|
264
|
+
row['number_of_objects'] = 1
|
|
265
|
+
|
|
266
|
+
row['uncertainty'] = None
|
|
267
|
+
row['timestamp'] = im['datetime']; assert isinstance(im['datetime'],str)
|
|
268
|
+
row['highlighted'] = 0
|
|
269
|
+
row['age'] = None
|
|
270
|
+
row['sex'] = None
|
|
271
|
+
row['animal_recognizable'] = 'No'
|
|
272
|
+
row['individual_id'] = None
|
|
273
|
+
row['individual_animal_notes'] = None
|
|
274
|
+
row['markings'] = None
|
|
275
|
+
|
|
276
|
+
assert len(row) == len(images_fields)
|
|
277
|
+
rows.append(row)
|
|
278
|
+
|
|
279
|
+
df = pd.DataFrame(rows)
|
|
280
|
+
|
|
281
|
+
df.to_csv(os.path.join(output_base,images_file_name),index=False)
|
|
282
|
+
|
|
283
|
+
# ...main()
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
#%% Command-line driver
|
|
260
287
|
|
|
261
|
-
|
|
288
|
+
if __name__ == '__main__':
|
|
289
|
+
main()
|