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,284 @@
1
+ """
2
+
3
+ coco_to_labelme.py
4
+
5
+ Converts a COCO dataset to labelme format (one .json per image file).
6
+
7
+ If you want to convert YOLO-formatted data to labelme format, use yolo_to_coco, then
8
+ coco_to_labelme.
9
+
10
+ """
11
+
12
+ #%% Imports and constants
13
+
14
+ import os
15
+ import json
16
+ import sys
17
+ import argparse
18
+
19
+ from tqdm import tqdm
20
+ from collections import defaultdict
21
+
22
+ from megadetector.visualization.visualization_utils import open_image
23
+ from megadetector.detection.run_detector import FAILURE_IMAGE_OPEN
24
+ from megadetector.utils import ct_utils
25
+
26
+
27
+ #%% Functions
28
+
29
+ def get_labelme_dict_for_image_from_coco_record(im,annotations,categories,info=None):
30
+ """
31
+ For the given image struct in COCO format and associated list of annotations, reformats the
32
+ detections into labelme format.
33
+
34
+ Args:
35
+ im (dict): image dict, as loaded from a COCO .json file; 'height' and 'width' are required
36
+ annotations (list): a list of annotations that refer to this image (this function errors if
37
+ that's not the case)
38
+ categories (list): a list of category in dicts in COCO format ({'id':x,'name':'s'})
39
+ info (dict, optional): a dict to store in a non-standard "custom_info" field in the output
40
+
41
+ Returns:
42
+ dict: a dict in labelme format, suitable for writing to a labelme .json file
43
+ """
44
+
45
+ image_base_name = os.path.basename(im['file_name'])
46
+
47
+ output_dict = {}
48
+ if info is not None:
49
+ output_dict['custom_info'] = info
50
+ output_dict['version'] = '5.3.0a0'
51
+ output_dict['flags'] = {}
52
+ output_dict['shapes'] = []
53
+ output_dict['imagePath'] = image_base_name
54
+ output_dict['imageHeight'] = im['height']
55
+ output_dict['imageWidth'] = im['width']
56
+ output_dict['imageData'] = None
57
+
58
+ # Store COCO categories in case we want to reconstruct the original IDs later
59
+ output_dict['coco_categories'] = categories
60
+
61
+ category_id_to_name = {c['id']:c['name'] for c in categories}
62
+
63
+ if 'flags' in im:
64
+ output_dict['flags'] = im['flags']
65
+
66
+ # ann = annotations[0]
67
+ for ann in annotations:
68
+
69
+ assert ann['image_id'] == im['id'], 'Annotation {} does not refer to image {}'.format(
70
+ ann['id'],im['id'])
71
+
72
+ if 'bbox' not in ann:
73
+ continue
74
+
75
+ shape = {}
76
+ shape['label'] = category_id_to_name[ann['category_id']]
77
+ shape['shape_type'] = 'rectangle'
78
+ shape['description'] = ''
79
+ shape['group_id'] = None
80
+
81
+ # COCO boxes are [x_min, y_min, width_of_box, height_of_box] (absolute)
82
+ #
83
+ # labelme boxes are [[x0,y0],[x1,y1]] (absolute)
84
+ x0 = ann['bbox'][0]
85
+ y0 = ann['bbox'][1]
86
+ x1 = ann['bbox'][0] + ann['bbox'][2]
87
+ y1 = ann['bbox'][1] + ann['bbox'][3]
88
+
89
+ shape['points'] = [[x0,y0],[x1,y1]]
90
+ output_dict['shapes'].append(shape)
91
+
92
+ # ...for each detection
93
+
94
+ return output_dict
95
+
96
+ # ...def get_labelme_dict_for_image()
97
+
98
+
99
+ def coco_to_labelme(coco_data,image_base,overwrite=False,bypass_image_size_check=False,verbose=False):
100
+ """
101
+ For all the images in [coco_data] (a dict or a filename), write a .json file in
102
+ labelme format alongside the corresponding relative path within image_base.
103
+
104
+ Args:
105
+ coco_data (dict or str): path to a COCO-formatted .json file, or an already-loaded
106
+ COCO-formatted dict
107
+ image_base (str): path where images live (filenames in [coco_data] should be relative to
108
+ [image_base]); this is also where labelme files will be written
109
+ overwrite (bool, optional): overwrite existing .json files
110
+ bypass_image_size_check (bool, optional): if you're sure that the COCO data already has
111
+ correct 'width' and 'height' fields, this bypasses the somewhat-slow loading of
112
+ each image to fetch image sizes
113
+ verbose (bool, optional): enable additional debug output
114
+ """
115
+
116
+ # Load COCO data if necessary
117
+ if isinstance(coco_data,str):
118
+ with open(coco_data,'r') as f:
119
+ coco_data = json.load(f)
120
+ assert isinstance(coco_data,dict)
121
+
122
+
123
+ ## Read image sizes if necessary
124
+
125
+ if bypass_image_size_check:
126
+
127
+ print('Bypassing size check')
128
+
129
+ else:
130
+
131
+ # TODO: parallelize this loop
132
+
133
+ print('Reading/validating image sizes...')
134
+
135
+ # im = coco_data['images'][0]
136
+ for im in tqdm(coco_data['images']):
137
+
138
+ # Make sure this file exists
139
+ im_full_path = os.path.join(image_base,im['file_name'])
140
+ assert os.path.isfile(im_full_path), 'Image file {} does not exist'.format(im_full_path)
141
+
142
+ # Load w/h information if necessary
143
+ if 'height' not in im or 'width' not in im:
144
+
145
+ try:
146
+ pil_im = open_image(im_full_path)
147
+ im['width'] = pil_im.width
148
+ im['height'] = pil_im.height
149
+ except Exception:
150
+ print('Warning: cannot open image {}'.format(im_full_path))
151
+ if 'failure' not in im:
152
+ im['failure'] = FAILURE_IMAGE_OPEN
153
+
154
+ # ...if we need to read w/h information
155
+
156
+ # ...for each image
157
+
158
+ # ...if we need to load image sizes
159
+
160
+
161
+ ## Generate labelme files
162
+
163
+ print('Generating .json files...')
164
+
165
+ image_id_to_annotations = defaultdict(list)
166
+ for ann in coco_data['annotations']:
167
+ image_id_to_annotations[ann['image_id']].append(ann)
168
+
169
+ n_json_files_written = 0
170
+ n_json_files_error = 0
171
+ n_json_files_exist = 0
172
+
173
+ # Write output
174
+ for im in tqdm(coco_data['images']):
175
+
176
+ # Skip this image if it failed to load in whatever system generated this COCO file
177
+ skip_image = False
178
+
179
+ # Errors are represented differently depending on the source
180
+ for error_string in ('failure','error'):
181
+ if (error_string in im) and (im[error_string] is not None):
182
+ if verbose:
183
+ print('Warning: skipping labelme file generation for failed image {}'.format(
184
+ im['file_name']))
185
+ skip_image = True
186
+ n_json_files_error += 1
187
+ break
188
+ if skip_image:
189
+ continue
190
+
191
+ im_full_path = os.path.join(image_base,im['file_name'])
192
+ json_path = os.path.splitext(im_full_path)[0] + '.json'
193
+
194
+ if (not overwrite) and (os.path.isfile(json_path)):
195
+ if verbose:
196
+ print('Skipping existing file {}'.format(json_path))
197
+ n_json_files_exist += 1
198
+ continue
199
+
200
+ annotations_this_image = image_id_to_annotations[im['id']]
201
+ output_dict = get_labelme_dict_for_image_from_coco_record(im,
202
+ annotations_this_image,
203
+ coco_data['categories'],
204
+ info=None)
205
+
206
+ n_json_files_written += 1
207
+ ct_utils.write_json(json_path, output_dict)
208
+
209
+ # ...for each image
210
+
211
+ print('\nWrote {} .json files (skipped {} for errors, {} because they exist)'.format(
212
+ n_json_files_written,n_json_files_error,n_json_files_exist))
213
+
214
+ # ...def coco_to_labelme()
215
+
216
+
217
+ #%% Interactive driver
218
+
219
+ if False:
220
+
221
+ pass
222
+
223
+ #%% Configure options
224
+
225
+ coco_file = \
226
+ r'C:\\temp\\snapshot-exploration\\images\\training-images-good\\training-images-good_from_yolo.json'
227
+ image_folder = os.path.dirname(coco_file)
228
+ overwrite = True
229
+
230
+
231
+ #%% Programmatic execution
232
+
233
+ coco_to_labelme(coco_data=coco_file,image_base=image_folder,overwrite=overwrite)
234
+
235
+
236
+ #%% Command-line execution
237
+
238
+ s = 'python coco_to_labelme.py "{}" "{}"'.format(coco_file,image_folder)
239
+ if overwrite:
240
+ s += ' --overwrite'
241
+
242
+ print(s)
243
+ import clipboard; clipboard.copy(s)
244
+
245
+
246
+ #%% Opening labelme
247
+
248
+ s = 'python labelme {}'.format(image_folder)
249
+ print(s)
250
+ import clipboard; clipboard.copy(s)
251
+
252
+
253
+ #%% Command-line driver
254
+
255
+ def main(): # noqa
256
+
257
+ parser = argparse.ArgumentParser(
258
+ description='Convert a COCO database to labelme annotation format')
259
+
260
+ parser.add_argument(
261
+ 'coco_file',
262
+ type=str,
263
+ help='Path to COCO data file (.json)')
264
+
265
+ parser.add_argument(
266
+ 'image_base',
267
+ type=str,
268
+ help='Path to images (also the output folder)')
269
+
270
+ parser.add_argument(
271
+ '--overwrite',
272
+ action='store_true',
273
+ help='Overwrite existing labelme .json files')
274
+
275
+ if len(sys.argv[1:]) == 0:
276
+ parser.print_help()
277
+ parser.exit()
278
+
279
+ args = parser.parse_args()
280
+
281
+ coco_to_labelme(coco_data=args.coco_file,image_base=args.image_base,overwrite=args.overwrite)
282
+
283
+ if __name__ == '__main__':
284
+ main()