megadetector 10.0.13__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.

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 +702 -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 +528 -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 +187 -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 +663 -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 +876 -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 +2159 -0
  79. megadetector/detection/run_inference_with_yolov5_val.py +1314 -0
  80. megadetector/detection/run_md_and_speciesnet.py +1494 -0
  81. megadetector/detection/run_tiled_inference.py +1038 -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 +1752 -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 +2077 -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 +213 -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 +224 -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 +2832 -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 +1759 -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 +1940 -0
  140. megadetector/visualization/visualize_db.py +630 -0
  141. megadetector/visualization/visualize_detector_output.py +479 -0
  142. megadetector/visualization/visualize_video_output.py +705 -0
  143. megadetector-10.0.13.dist-info/METADATA +134 -0
  144. megadetector-10.0.13.dist-info/RECORD +147 -0
  145. megadetector-10.0.13.dist-info/WHEEL +5 -0
  146. megadetector-10.0.13.dist-info/licenses/LICENSE +19 -0
  147. megadetector-10.0.13.dist-info/top_level.txt +1 -0
File without changes
@@ -0,0 +1,107 @@
1
+ """
2
+
3
+ add_width_and_height_to_db.py
4
+
5
+ Grabs width and height from actual image files for a .json database that is missing w/h.
6
+
7
+ """
8
+
9
+ #%% Imports and constants
10
+
11
+ import os
12
+ import sys
13
+ import json
14
+ import argparse
15
+
16
+ from tqdm import tqdm
17
+ from PIL import Image
18
+
19
+ from megadetector.utils import ct_utils
20
+
21
+
22
+ #%% Main resizing function
23
+
24
+ def add_width_and_height_to_db(input_file,output_file,image_base_folder):
25
+ """
26
+ Add width and height to images in the COCO db [input_file]
27
+ that don't have non-None w/h values. Does not verify correctness
28
+ for images that already have non-None w/h values. Ignores files that
29
+ fail to open.
30
+
31
+ Args:
32
+ input_file (str): the COCO .json file to process
33
+ output_file (str): the COCO .json file to write
34
+ image_base_folder (str): image filenames in [input_file] should be relative
35
+ to this folder
36
+
37
+ Returns:
38
+ list: the list of image dicts that were modified
39
+ """
40
+
41
+ with open(input_file,'r') as f:
42
+ d = json.load(f)
43
+
44
+ to_return = []
45
+
46
+ for im in tqdm(d['images']):
47
+
48
+ if ('height' not in im) or ('width' not in im) or \
49
+ (im['height'] is None) or (im['width'] is None) or \
50
+ (im['height'] <= 0) or (im['width'] <= 0):
51
+
52
+ fn_relative = im['file_name']
53
+ fn_abs = os.path.join(image_base_folder,fn_relative)
54
+
55
+ if not os.path.isfile(fn_abs):
56
+ print('Could not find image file {}'.format(fn_abs))
57
+ continue
58
+
59
+ try:
60
+ im_w, im_h = Image.open(fn_abs).size
61
+ except Exception as e:
62
+ print('Error opening file {}: {}'.format(fn_abs,str(e)))
63
+ continue
64
+
65
+ assert isinstance(im_w,int) and isinstance(im_h,int) and \
66
+ im_w > 0 and im_h > 0, \
67
+ 'Illegal size retrieved for {}'.format(fn_abs)
68
+
69
+ im['height'] = im_h
70
+ im['width'] = im_w
71
+ to_return.append(im)
72
+
73
+ # ...if we need to add width and/or height to this image
74
+
75
+ # ...for each image
76
+
77
+ ct_utils.write_json(output_file, d)
78
+
79
+ print('Added size information to {} of {} images'.format(
80
+ len(to_return), len(d['images'])))
81
+
82
+ return to_return
83
+
84
+ # ...def add_width_and_height_to_db(...)
85
+
86
+
87
+ #%% Command-line driver
88
+
89
+ if __name__ == '__main__':
90
+
91
+ parser = argparse.ArgumentParser()
92
+ parser.add_argument('input_file', type=str,
93
+ help='Input COCO-formatted .json file')
94
+ parser.add_argument('output_file', type=str,
95
+ help='Output COCO-formatted .json file')
96
+ parser.add_argument('image_base_folder', type=str,
97
+ help='Base directory for images')
98
+
99
+ if len(sys.argv[1:]) == 0:
100
+ parser.print_help()
101
+ parser.exit()
102
+
103
+ args = parser.parse_args()
104
+
105
+ add_width_and_height_to_db(args.input_file,
106
+ args.output_file,
107
+ args.image_base_folder)
@@ -0,0 +1,210 @@
1
+ """
2
+
3
+ combine_coco_camera_traps_files.py
4
+
5
+ Merges two or more .json files in COCO Camera Traps format, optionally
6
+ writing the results to another .json file.
7
+
8
+ - Concatenates image lists, erroring if images are not unique.
9
+ - Errors on unrecognized fields.
10
+ - Checks compatibility in info structs, within reason.
11
+
12
+ *Example command-line invocation*
13
+
14
+ combine_coco_camera_traps_files input1.json input2.json ... inputN.json output.json
15
+
16
+ """
17
+
18
+ #%% Constants and imports
19
+
20
+ import argparse
21
+ import json
22
+ import sys
23
+ from megadetector.utils import ct_utils
24
+
25
+
26
+ #%% Merge functions
27
+
28
+ def combine_cct_files(input_files,
29
+ output_file=None,
30
+ require_uniqueness=True,
31
+ filename_prefixes=None):
32
+ """
33
+ Merges the list of COCO Camera Traps files [input_files] into a single
34
+ dictionary, optionally writing the result to [output_file].
35
+
36
+ Args:
37
+ input_files (list): paths to CCT .json files
38
+ output_file (str, optional): path to write merged .json file
39
+ require_uniqueness (bool, optional): whether to require that the images in
40
+ each input_dict be unique
41
+ filename_prefixes (dict, optional): dict mapping input filenames to strings
42
+ that should be prepended to image filenames from that source
43
+
44
+ Returns:
45
+ dict: the merged COCO-formatted .json dict
46
+ """
47
+
48
+ input_dicts = []
49
+ print('Loading input files')
50
+ for fn in input_files:
51
+ with open(fn, 'r', encoding='utf-8') as f:
52
+ d = json.load(f)
53
+ if filename_prefixes is not None:
54
+ assert fn in filename_prefixes
55
+ d['filename_prefix'] = filename_prefixes[fn]
56
+ input_dicts.append(d)
57
+
58
+ print('Merging results')
59
+ merged_dict = combine_cct_dictionaries(
60
+ input_dicts, require_uniqueness=require_uniqueness)
61
+
62
+ print('Writing output')
63
+ if output_file is not None:
64
+ ct_utils.write_json(output_file, merged_dict)
65
+
66
+ return merged_dict
67
+
68
+
69
+ def combine_cct_dictionaries(input_dicts, require_uniqueness=True):
70
+ """
71
+ Merges the list of COCO Camera Traps dictionaries [input_dicts]. See module header
72
+ comment for details on merge rules.
73
+
74
+ Args:
75
+ input_dicts (list of dict): list of CCT dicts
76
+ require_uniqueness (bool, optional): whether to require that the images in
77
+ each input_dict be unique
78
+
79
+ Returns:
80
+ dict: the merged COCO-formatted .json dict
81
+ """
82
+
83
+ filename_to_image = {}
84
+ all_annotations = []
85
+ info = None
86
+
87
+ category_name_to_id = {}
88
+ category_name_to_id['empty'] = 0
89
+ next_category_id = 1
90
+
91
+ known_fields = ['info', 'categories', 'annotations','images','filename_prefix']
92
+
93
+ # i_input_dict = 0; input_dict = input_dicts[i_input_dict]
94
+ for i_input_dict,input_dict in enumerate(input_dicts):
95
+
96
+ filename_prefix = ''
97
+ if ('filename_prefix' in input_dict.keys()):
98
+ filename_prefix = input_dict['filename_prefix']
99
+
100
+ for k in input_dict.keys():
101
+ if k not in known_fields:
102
+ raise ValueError(f'Unrecognized CCT field: {k}')
103
+
104
+ # We will prepend an index to every ID to guarantee uniqueness
105
+ index_string = 'ds' + str(i_input_dict).zfill(3) + '_'
106
+
107
+ old_cat_id_to_new_cat_id = {}
108
+
109
+ # Map detection categories from the original data set into the merged data set
110
+ for original_category in input_dict['categories']:
111
+
112
+ original_cat_id = original_category['id']
113
+ cat_name = original_category['name']
114
+ if cat_name in category_name_to_id:
115
+ new_cat_id = category_name_to_id[cat_name]
116
+ else:
117
+ new_cat_id = next_category_id
118
+ next_category_id += 1
119
+ category_name_to_id[cat_name] = new_cat_id
120
+
121
+ if original_cat_id in old_cat_id_to_new_cat_id:
122
+ assert old_cat_id_to_new_cat_id[original_cat_id] == new_cat_id
123
+ else:
124
+ old_cat_id_to_new_cat_id[original_cat_id] = new_cat_id
125
+
126
+ # ...for each category
127
+
128
+
129
+ # Merge original image list into the merged data set
130
+ for im in input_dict['images']:
131
+
132
+ if 'seq_id' in im:
133
+ im['seq_id'] = index_string + str(im['seq_id'])
134
+ if 'location' in im:
135
+ im['location'] = index_string + im['location']
136
+
137
+ im_file = filename_prefix + im['file_name']
138
+ im['file_name'] = im_file
139
+ if require_uniqueness:
140
+ assert im_file not in filename_to_image, f'Duplicate image: {im_file}'
141
+ else:
142
+ if im_file in filename_to_image:
143
+ print('Redundant image {}'.format(im_file))
144
+
145
+ # Create a unique ID
146
+ im['id'] = index_string + str(im['id'])
147
+ filename_to_image[im_file] = im
148
+
149
+ # ...for each image
150
+
151
+
152
+ # Same for annotations
153
+ for ann in input_dict['annotations']:
154
+
155
+ ann['image_id'] = index_string + str(ann['image_id'])
156
+ ann['id'] = index_string + str(ann['id'])
157
+ assert ann['category_id'] in old_cat_id_to_new_cat_id
158
+ ann['category_id'] = old_cat_id_to_new_cat_id[ann['category_id']]
159
+
160
+ # ...for each annotation
161
+
162
+ all_annotations.extend(input_dict['annotations'])
163
+
164
+ # Merge info dicts, don't check completion time fields
165
+ if info is None:
166
+ import copy
167
+ info = copy.deepcopy(input_dict['info'])
168
+ info['original_info'] = [input_dict['info']]
169
+ else:
170
+ info['original_info'].append(input_dict['info'])
171
+
172
+ # ...for each dictionary
173
+
174
+ # Convert merged image dictionaries to a sorted list
175
+ sorted_images = sorted(filename_to_image.values(), key=lambda im: im['file_name'])
176
+
177
+ all_categories = [{'id':category_name_to_id[cat_name],'name':cat_name} for\
178
+ cat_name in category_name_to_id.keys()]
179
+
180
+ merged_dict = {'info': info,
181
+ 'categories': all_categories,
182
+ 'images': sorted_images,
183
+ 'annotations': all_annotations}
184
+
185
+ return merged_dict
186
+
187
+ # ...combine_cct_dictionaries(...)
188
+
189
+
190
+ #%% Command-line driver
191
+
192
+ def main(): # noqa
193
+
194
+ parser = argparse.ArgumentParser()
195
+ parser.add_argument(
196
+ 'input_paths', nargs='+',
197
+ help='List of input .json files')
198
+ parser.add_argument(
199
+ 'output_path',
200
+ help='Output .json file')
201
+
202
+ if len(sys.argv[1:]) == 0:
203
+ parser.print_help()
204
+ parser.exit()
205
+
206
+ args = parser.parse_args()
207
+ combine_cct_files(args.input_paths, args.output_path)
208
+
209
+ if __name__ == '__main__':
210
+ main()