megadetector 10.0.15__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.
Files changed (147) hide show
  1. megadetector/__init__.py +0 -0
  2. megadetector/api/__init__.py +0 -0
  3. megadetector/api/batch_processing/integration/digiKam/setup.py +6 -0
  4. megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +465 -0
  5. megadetector/api/batch_processing/integration/eMammal/test_scripts/config_template.py +5 -0
  6. megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +125 -0
  7. megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +55 -0
  8. megadetector/classification/__init__.py +0 -0
  9. megadetector/classification/aggregate_classifier_probs.py +108 -0
  10. megadetector/classification/analyze_failed_images.py +227 -0
  11. megadetector/classification/cache_batchapi_outputs.py +198 -0
  12. megadetector/classification/create_classification_dataset.py +626 -0
  13. megadetector/classification/crop_detections.py +516 -0
  14. megadetector/classification/csv_to_json.py +226 -0
  15. megadetector/classification/detect_and_crop.py +853 -0
  16. megadetector/classification/efficientnet/__init__.py +9 -0
  17. megadetector/classification/efficientnet/model.py +415 -0
  18. megadetector/classification/efficientnet/utils.py +608 -0
  19. megadetector/classification/evaluate_model.py +520 -0
  20. megadetector/classification/identify_mislabeled_candidates.py +152 -0
  21. megadetector/classification/json_to_azcopy_list.py +63 -0
  22. megadetector/classification/json_validator.py +696 -0
  23. megadetector/classification/map_classification_categories.py +276 -0
  24. megadetector/classification/merge_classification_detection_output.py +509 -0
  25. megadetector/classification/prepare_classification_script.py +194 -0
  26. megadetector/classification/prepare_classification_script_mc.py +228 -0
  27. megadetector/classification/run_classifier.py +287 -0
  28. megadetector/classification/save_mislabeled.py +110 -0
  29. megadetector/classification/train_classifier.py +827 -0
  30. megadetector/classification/train_classifier_tf.py +725 -0
  31. megadetector/classification/train_utils.py +323 -0
  32. megadetector/data_management/__init__.py +0 -0
  33. megadetector/data_management/animl_to_md.py +161 -0
  34. megadetector/data_management/annotations/__init__.py +0 -0
  35. megadetector/data_management/annotations/annotation_constants.py +33 -0
  36. megadetector/data_management/camtrap_dp_to_coco.py +270 -0
  37. megadetector/data_management/cct_json_utils.py +566 -0
  38. megadetector/data_management/cct_to_md.py +184 -0
  39. megadetector/data_management/cct_to_wi.py +293 -0
  40. megadetector/data_management/coco_to_labelme.py +284 -0
  41. megadetector/data_management/coco_to_yolo.py +701 -0
  42. megadetector/data_management/databases/__init__.py +0 -0
  43. megadetector/data_management/databases/add_width_and_height_to_db.py +107 -0
  44. megadetector/data_management/databases/combine_coco_camera_traps_files.py +210 -0
  45. megadetector/data_management/databases/integrity_check_json_db.py +563 -0
  46. megadetector/data_management/databases/subset_json_db.py +195 -0
  47. megadetector/data_management/generate_crops_from_cct.py +200 -0
  48. megadetector/data_management/get_image_sizes.py +164 -0
  49. megadetector/data_management/labelme_to_coco.py +559 -0
  50. megadetector/data_management/labelme_to_yolo.py +349 -0
  51. megadetector/data_management/lila/__init__.py +0 -0
  52. megadetector/data_management/lila/create_lila_blank_set.py +556 -0
  53. megadetector/data_management/lila/create_lila_test_set.py +192 -0
  54. megadetector/data_management/lila/create_links_to_md_results_files.py +106 -0
  55. megadetector/data_management/lila/download_lila_subset.py +182 -0
  56. megadetector/data_management/lila/generate_lila_per_image_labels.py +777 -0
  57. megadetector/data_management/lila/get_lila_annotation_counts.py +174 -0
  58. megadetector/data_management/lila/get_lila_image_counts.py +112 -0
  59. megadetector/data_management/lila/lila_common.py +319 -0
  60. megadetector/data_management/lila/test_lila_metadata_urls.py +164 -0
  61. megadetector/data_management/mewc_to_md.py +344 -0
  62. megadetector/data_management/ocr_tools.py +873 -0
  63. megadetector/data_management/read_exif.py +964 -0
  64. megadetector/data_management/remap_coco_categories.py +195 -0
  65. megadetector/data_management/remove_exif.py +156 -0
  66. megadetector/data_management/rename_images.py +194 -0
  67. megadetector/data_management/resize_coco_dataset.py +665 -0
  68. megadetector/data_management/speciesnet_to_md.py +41 -0
  69. megadetector/data_management/wi_download_csv_to_coco.py +247 -0
  70. megadetector/data_management/yolo_output_to_md_output.py +594 -0
  71. megadetector/data_management/yolo_to_coco.py +984 -0
  72. megadetector/data_management/zamba_to_md.py +188 -0
  73. megadetector/detection/__init__.py +0 -0
  74. megadetector/detection/change_detection.py +840 -0
  75. megadetector/detection/process_video.py +479 -0
  76. megadetector/detection/pytorch_detector.py +1451 -0
  77. megadetector/detection/run_detector.py +1267 -0
  78. megadetector/detection/run_detector_batch.py +2172 -0
  79. megadetector/detection/run_inference_with_yolov5_val.py +1314 -0
  80. megadetector/detection/run_md_and_speciesnet.py +1604 -0
  81. megadetector/detection/run_tiled_inference.py +1044 -0
  82. megadetector/detection/tf_detector.py +209 -0
  83. megadetector/detection/video_utils.py +1379 -0
  84. megadetector/postprocessing/__init__.py +0 -0
  85. megadetector/postprocessing/add_max_conf.py +72 -0
  86. megadetector/postprocessing/categorize_detections_by_size.py +166 -0
  87. megadetector/postprocessing/classification_postprocessing.py +1943 -0
  88. megadetector/postprocessing/combine_batch_outputs.py +249 -0
  89. megadetector/postprocessing/compare_batch_results.py +2110 -0
  90. megadetector/postprocessing/convert_output_format.py +403 -0
  91. megadetector/postprocessing/create_crop_folder.py +629 -0
  92. megadetector/postprocessing/detector_calibration.py +570 -0
  93. megadetector/postprocessing/generate_csv_report.py +522 -0
  94. megadetector/postprocessing/load_api_results.py +223 -0
  95. megadetector/postprocessing/md_to_coco.py +428 -0
  96. megadetector/postprocessing/md_to_labelme.py +351 -0
  97. megadetector/postprocessing/md_to_wi.py +41 -0
  98. megadetector/postprocessing/merge_detections.py +392 -0
  99. megadetector/postprocessing/postprocess_batch_results.py +2140 -0
  100. megadetector/postprocessing/remap_detection_categories.py +226 -0
  101. megadetector/postprocessing/render_detection_confusion_matrix.py +677 -0
  102. megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +206 -0
  103. megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +82 -0
  104. megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +1665 -0
  105. megadetector/postprocessing/separate_detections_into_folders.py +795 -0
  106. megadetector/postprocessing/subset_json_detector_output.py +964 -0
  107. megadetector/postprocessing/top_folders_to_bottom.py +238 -0
  108. megadetector/postprocessing/validate_batch_results.py +332 -0
  109. megadetector/taxonomy_mapping/__init__.py +0 -0
  110. megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +491 -0
  111. megadetector/taxonomy_mapping/map_new_lila_datasets.py +211 -0
  112. megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +165 -0
  113. megadetector/taxonomy_mapping/preview_lila_taxonomy.py +543 -0
  114. megadetector/taxonomy_mapping/retrieve_sample_image.py +71 -0
  115. megadetector/taxonomy_mapping/simple_image_download.py +231 -0
  116. megadetector/taxonomy_mapping/species_lookup.py +1008 -0
  117. megadetector/taxonomy_mapping/taxonomy_csv_checker.py +159 -0
  118. megadetector/taxonomy_mapping/taxonomy_graph.py +346 -0
  119. megadetector/taxonomy_mapping/validate_lila_category_mappings.py +83 -0
  120. megadetector/tests/__init__.py +0 -0
  121. megadetector/tests/test_nms_synthetic.py +335 -0
  122. megadetector/utils/__init__.py +0 -0
  123. megadetector/utils/ct_utils.py +1857 -0
  124. megadetector/utils/directory_listing.py +199 -0
  125. megadetector/utils/extract_frames_from_video.py +307 -0
  126. megadetector/utils/gpu_test.py +125 -0
  127. megadetector/utils/md_tests.py +2072 -0
  128. megadetector/utils/path_utils.py +2872 -0
  129. megadetector/utils/process_utils.py +172 -0
  130. megadetector/utils/split_locations_into_train_val.py +237 -0
  131. megadetector/utils/string_utils.py +234 -0
  132. megadetector/utils/url_utils.py +825 -0
  133. megadetector/utils/wi_platform_utils.py +968 -0
  134. megadetector/utils/wi_taxonomy_utils.py +1766 -0
  135. megadetector/utils/write_html_image_list.py +239 -0
  136. megadetector/visualization/__init__.py +0 -0
  137. megadetector/visualization/plot_utils.py +309 -0
  138. megadetector/visualization/render_images_with_thumbnails.py +243 -0
  139. megadetector/visualization/visualization_utils.py +1973 -0
  140. megadetector/visualization/visualize_db.py +630 -0
  141. megadetector/visualization/visualize_detector_output.py +498 -0
  142. megadetector/visualization/visualize_video_output.py +705 -0
  143. megadetector-10.0.15.dist-info/METADATA +115 -0
  144. megadetector-10.0.15.dist-info/RECORD +147 -0
  145. megadetector-10.0.15.dist-info/WHEEL +5 -0
  146. megadetector-10.0.15.dist-info/licenses/LICENSE +19 -0
  147. megadetector-10.0.15.dist-info/top_level.txt +1 -0
@@ -0,0 +1,270 @@
1
+ """
2
+
3
+ camtrap_dp_to_coco.py
4
+
5
+ Parse a very limited subset of the Camtrap DP data package format:
6
+
7
+ https://camtrap-dp.tdwg.org/
8
+
9
+ ...and convert to COCO format. Assumes that all required metadata files have been
10
+ put in the same directory (which is standard).
11
+
12
+ Does not currently parse bounding boxes, just attaches species labels to images.
13
+
14
+ Currently supports only sequence-level labeling.
15
+
16
+ """
17
+
18
+ #%% Imports and constants
19
+
20
+ import os
21
+ import json
22
+ import argparse
23
+
24
+ import pandas as pd
25
+
26
+ from dateutil import parser as dateparser
27
+
28
+ from collections import defaultdict
29
+
30
+
31
+ #%% Functions
32
+
33
+ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
34
+ """
35
+ Convert the Camtrap DP package in [camtrap_dp_folder] to COCO.
36
+
37
+ Does not validate images, just converts. Use integrity_check_json_db to validate
38
+ the resulting COCO file.
39
+
40
+ Optionally writes the results to [output_file]
41
+
42
+ Args:
43
+ camtrap_dp_folder (str): input folder, containing a CamtrapDP package
44
+ output_file (str, optional): COCO-formatted output file
45
+ """
46
+
47
+ required_files = ('datapackage.json','deployments.csv','events.csv','media.csv','observations.csv')
48
+
49
+ for fn in required_files:
50
+ fn_abs = os.path.join(camtrap_dp_folder,fn)
51
+ assert os.path.isfile(fn_abs), 'Could not find required file {}'.format(fn_abs)
52
+
53
+ with open(os.path.join(camtrap_dp_folder,'datapackage.json'),'r') as f:
54
+ datapackage = json.load(f)
55
+
56
+ assert datapackage['profile'] == 'https://raw.githubusercontent.com/tdwg/camtrap-dp/1.0/camtrap-dp-profile.json', \
57
+ 'I only know how to parse Camtrap DP 1.0 packages'
58
+
59
+ deployments_file = None
60
+ events_file = None
61
+ media_file = None
62
+ observations_file = None
63
+
64
+ resources = datapackage['resources']
65
+ for r in resources:
66
+ if r['name'] == 'deployments':
67
+ deployments_file = r['path']
68
+ elif r['name'] == 'media':
69
+ media_file = r['path']
70
+ elif r['name'] == 'events':
71
+ events_file = r['path']
72
+ elif r['name'] == 'observations':
73
+ observations_file = r['path']
74
+
75
+ assert deployments_file is not None, 'No deployment file specified'
76
+ assert events_file is not None, 'No events file specified'
77
+ assert media_file is not None, 'No media file specified'
78
+ assert observations_file is not None, 'No observation file specified'
79
+
80
+ deployments_df = pd.read_csv(os.path.join(camtrap_dp_folder,deployments_file))
81
+ events_df = pd.read_csv(os.path.join(camtrap_dp_folder,events_file))
82
+ media_df = pd.read_csv(os.path.join(camtrap_dp_folder,media_file))
83
+ observations_df = pd.read_csv(os.path.join(camtrap_dp_folder,observations_file))
84
+
85
+ print('Read {} deployment lines'.format(len(deployments_df)))
86
+ print('Read {} events lines'.format(len(events_df)))
87
+ print('Read {} media lines'.format(len(media_df)))
88
+ print('Read {} observation lines'.format(len(observations_df)))
89
+
90
+ media_id_to_media_info = {}
91
+
92
+ # i_row = 0; row = media_df.iloc[i_row]
93
+ for i_row,row in media_df.iterrows():
94
+ media_info = {}
95
+ media_info['file_name'] = os.path.join(row['filePath'],row['fileName']).replace('\\','/')
96
+ media_info['location'] = row['deploymentID']
97
+ media_info['id'] = row['mediaID']
98
+ media_info['datetime'] = row['timestamp']
99
+ media_info['datetime'] = dateparser.parse(media_info['datetime'])
100
+ media_info['frame_num'] = -1
101
+ media_info['seq_num_frames'] = -1
102
+ media_id_to_media_info[row['mediaID']] = media_info
103
+
104
+ event_id_to_media_ids = defaultdict(list)
105
+
106
+ # i_row = 0; row = events_df.iloc[i_row]
107
+ for i_row,row in events_df.iterrows():
108
+ media_id = row['mediaID']
109
+ assert media_id in media_id_to_media_info
110
+ event_id_to_media_ids[row['eventID']].append(media_id)
111
+
112
+ event_id_to_category_names = defaultdict(set)
113
+
114
+ # i_row = 0; row = observations_df.iloc[i_row]
115
+ for i_row,row in observations_df.iterrows():
116
+
117
+ if row['observationLevel'] != 'event':
118
+ raise ValueError("I don't know how to parse image-level events yet")
119
+
120
+ if row['observationType'] == 'blank':
121
+ event_id_to_category_names[row['eventID']].add('empty')
122
+ elif row['observationType'] == 'unknown':
123
+ event_id_to_category_names[row['eventID']].add('unknown')
124
+ elif row['observationType'] == 'human':
125
+ assert row['scientificName'] == 'Homo sapiens'
126
+ event_id_to_category_names[row['eventID']].add(row['scientificName'])
127
+ else:
128
+ assert row['observationType'] == 'animal'
129
+ assert isinstance(row['scientificName'],str)
130
+ event_id_to_category_names[row['eventID']].add(row['scientificName'])
131
+
132
+ # Sort images within an event into frame numbers
133
+ #
134
+ # event_id = next(iter(event_id_to_media_ids))
135
+ for event_id in event_id_to_media_ids.keys():
136
+ media_ids_this_event = event_id_to_media_ids[event_id]
137
+ media_info_this_event = [media_id_to_media_info[media_id] for media_id in media_ids_this_event]
138
+ media_info_this_event = sorted(media_info_this_event, key=lambda x: x['datetime'])
139
+ for i_media,media_info in enumerate(media_info_this_event):
140
+ media_info['frame_num'] = i_media
141
+ media_info['seq_num_frames'] = len(media_info_this_event)
142
+ media_info['seq_id'] = event_id
143
+
144
+ # Create category names
145
+ category_name_to_category_id = {'empty':0}
146
+ for event_id in event_id_to_category_names:
147
+ category_names_this_event = event_id_to_category_names[event_id]
148
+ for name in category_names_this_event:
149
+ if name not in category_name_to_category_id:
150
+ category_name_to_category_id[name] = len(category_name_to_category_id)
151
+
152
+ # Move everything into COCO format
153
+ images = list(media_id_to_media_info.values())
154
+
155
+ categories = []
156
+ for name in category_name_to_category_id:
157
+ categories.append({'name':name,'id':category_name_to_category_id[name]})
158
+ info = {'version':1.0,'description':datapackage['name']}
159
+
160
+ # Create annotations
161
+ annotations = []
162
+
163
+ for event_id in event_id_to_media_ids.keys():
164
+ i_ann = 0
165
+ media_ids_this_event = event_id_to_media_ids[event_id]
166
+ media_info_this_event = [media_id_to_media_info[media_id] for media_id in media_ids_this_event]
167
+ categories_this_event = event_id_to_category_names[event_id]
168
+ for im in media_info_this_event:
169
+ for category_name in categories_this_event:
170
+ ann = {}
171
+ ann['id'] = event_id + '_' + str(i_ann)
172
+ i_ann += 1
173
+ ann['image_id'] = im['id']
174
+ ann['category_id'] = category_name_to_category_id[category_name]
175
+ ann['sequence_level_annotation'] = True
176
+ annotations.append(ann)
177
+
178
+ coco_data = {}
179
+ coco_data['images'] = images
180
+ coco_data['annotations'] = annotations
181
+ coco_data['categories'] = categories
182
+ coco_data['info'] = info
183
+
184
+ for im in coco_data['images']:
185
+ im['datetime'] = str(im['datetime'] )
186
+
187
+ if output_file is not None:
188
+ with open(output_file,'w') as f:
189
+ json.dump(coco_data,f,indent=1)
190
+
191
+ return coco_data
192
+
193
+
194
+ #%% Interactive driver
195
+
196
+ if False:
197
+
198
+ pass
199
+
200
+ #%%
201
+
202
+ camtrap_dp_folder = r'C:\temp\pilot2\pilot2'
203
+ coco_file = os.path.join(camtrap_dp_folder,'test-coco.json')
204
+ coco_data = camtrap_dp_to_coco(camtrap_dp_folder,
205
+ output_file=coco_file)
206
+
207
+ #%% Validate
208
+
209
+ from megadetector.data_management.databases.integrity_check_json_db import \
210
+ integrity_check_json_db, IntegrityCheckOptions
211
+
212
+ options = IntegrityCheckOptions()
213
+
214
+ options.baseDir = camtrap_dp_folder
215
+ options.bCheckImageSizes = False
216
+ options.bCheckImageExistence = True
217
+ options.bFindUnusedImages = True
218
+ options.bRequireLocation = True
219
+ options.iMaxNumImages = -1
220
+ options.nThreads = 1
221
+ options.verbose = True
222
+
223
+ sorted_categories, data, error_info = integrity_check_json_db(coco_file,options)
224
+
225
+ #%% Preview
226
+
227
+ from megadetector.visualization.visualize_db import DbVizOptions, visualize_db
228
+
229
+ options = DbVizOptions()
230
+ options.parallelize_rendering = True
231
+ options.parallelize_rendering_with_threads = True
232
+ options.parallelize_rendering_n_cores = 10
233
+
234
+ preview_dir = r'c:\temp\camtrapdp-preview'
235
+ html_output_file, image_db = visualize_db(coco_file, preview_dir, camtrap_dp_folder, options=options)
236
+
237
+ from megadetector.utils.path_utils import open_file
238
+ open_file(html_output_file)
239
+
240
+
241
+ #%% Command-line driver
242
+
243
+ def main():
244
+ """
245
+ Command-line interface to convert Camtrap DP to COCO.
246
+ """
247
+
248
+ parser = argparse.ArgumentParser(description='Convert Camtrap DP to COCO format')
249
+ parser.add_argument('camtrap_dp_folder', type=str,
250
+ help='Input folder, containing a CamtrapDP package')
251
+ parser.add_argument('--output_file', type=str, default=None,
252
+ help='COCO-formatted output file (defaults to [camtrap_dp_folder]_coco.json)')
253
+
254
+ args = parser.parse_args()
255
+
256
+ if args.output_file is None:
257
+ # Default output file name: [camtrap_dp_folder]_coco.json
258
+ #
259
+ # Remove trailing slash if present
260
+ folder_name = args.camtrap_dp_folder.rstrip(os.sep)
261
+ output_file = folder_name + '_coco.json'
262
+ else:
263
+ output_file = args.output_file
264
+
265
+ camtrap_dp_to_coco(camtrap_dp_folder=args.camtrap_dp_folder, output_file=output_file)
266
+ print(f"Successfully converted Camtrap DP package at '{args.camtrap_dp_folder}' to " + \
267
+ f"COCO format at '{output_file}'")
268
+
269
+ if __name__ == '__main__':
270
+ main()