megadetector 5.0.28__py3-none-any.whl → 10.0.0__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 (197) hide show
  1. megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
  2. megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
  3. megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
  4. megadetector/classification/aggregate_classifier_probs.py +3 -3
  5. megadetector/classification/analyze_failed_images.py +5 -5
  6. megadetector/classification/cache_batchapi_outputs.py +5 -5
  7. megadetector/classification/create_classification_dataset.py +11 -12
  8. megadetector/classification/crop_detections.py +10 -10
  9. megadetector/classification/csv_to_json.py +8 -8
  10. megadetector/classification/detect_and_crop.py +13 -15
  11. megadetector/classification/efficientnet/model.py +8 -8
  12. megadetector/classification/efficientnet/utils.py +6 -5
  13. megadetector/classification/evaluate_model.py +7 -7
  14. megadetector/classification/identify_mislabeled_candidates.py +6 -6
  15. megadetector/classification/json_to_azcopy_list.py +1 -1
  16. megadetector/classification/json_validator.py +29 -32
  17. megadetector/classification/map_classification_categories.py +9 -9
  18. megadetector/classification/merge_classification_detection_output.py +12 -9
  19. megadetector/classification/prepare_classification_script.py +19 -19
  20. megadetector/classification/prepare_classification_script_mc.py +26 -26
  21. megadetector/classification/run_classifier.py +4 -4
  22. megadetector/classification/save_mislabeled.py +6 -6
  23. megadetector/classification/train_classifier.py +1 -1
  24. megadetector/classification/train_classifier_tf.py +9 -9
  25. megadetector/classification/train_utils.py +10 -10
  26. megadetector/data_management/annotations/annotation_constants.py +1 -2
  27. megadetector/data_management/camtrap_dp_to_coco.py +79 -46
  28. megadetector/data_management/cct_json_utils.py +103 -103
  29. megadetector/data_management/cct_to_md.py +49 -49
  30. megadetector/data_management/cct_to_wi.py +33 -33
  31. megadetector/data_management/coco_to_labelme.py +75 -75
  32. megadetector/data_management/coco_to_yolo.py +210 -193
  33. megadetector/data_management/databases/add_width_and_height_to_db.py +86 -12
  34. megadetector/data_management/databases/combine_coco_camera_traps_files.py +40 -40
  35. megadetector/data_management/databases/integrity_check_json_db.py +228 -200
  36. megadetector/data_management/databases/subset_json_db.py +33 -33
  37. megadetector/data_management/generate_crops_from_cct.py +88 -39
  38. megadetector/data_management/get_image_sizes.py +54 -49
  39. megadetector/data_management/labelme_to_coco.py +133 -125
  40. megadetector/data_management/labelme_to_yolo.py +159 -73
  41. megadetector/data_management/lila/create_lila_blank_set.py +81 -83
  42. megadetector/data_management/lila/create_lila_test_set.py +32 -31
  43. megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
  44. megadetector/data_management/lila/download_lila_subset.py +21 -24
  45. megadetector/data_management/lila/generate_lila_per_image_labels.py +365 -107
  46. megadetector/data_management/lila/get_lila_annotation_counts.py +35 -33
  47. megadetector/data_management/lila/get_lila_image_counts.py +22 -22
  48. megadetector/data_management/lila/lila_common.py +73 -70
  49. megadetector/data_management/lila/test_lila_metadata_urls.py +28 -19
  50. megadetector/data_management/mewc_to_md.py +344 -340
  51. megadetector/data_management/ocr_tools.py +262 -255
  52. megadetector/data_management/read_exif.py +249 -227
  53. megadetector/data_management/remap_coco_categories.py +90 -28
  54. megadetector/data_management/remove_exif.py +81 -21
  55. megadetector/data_management/rename_images.py +187 -187
  56. megadetector/data_management/resize_coco_dataset.py +588 -120
  57. megadetector/data_management/speciesnet_to_md.py +41 -41
  58. megadetector/data_management/wi_download_csv_to_coco.py +55 -55
  59. megadetector/data_management/yolo_output_to_md_output.py +248 -122
  60. megadetector/data_management/yolo_to_coco.py +333 -191
  61. megadetector/detection/change_detection.py +832 -0
  62. megadetector/detection/process_video.py +340 -337
  63. megadetector/detection/pytorch_detector.py +358 -278
  64. megadetector/detection/run_detector.py +399 -186
  65. megadetector/detection/run_detector_batch.py +404 -377
  66. megadetector/detection/run_inference_with_yolov5_val.py +340 -327
  67. megadetector/detection/run_tiled_inference.py +257 -249
  68. megadetector/detection/tf_detector.py +24 -24
  69. megadetector/detection/video_utils.py +332 -295
  70. megadetector/postprocessing/add_max_conf.py +19 -11
  71. megadetector/postprocessing/categorize_detections_by_size.py +45 -45
  72. megadetector/postprocessing/classification_postprocessing.py +468 -433
  73. megadetector/postprocessing/combine_batch_outputs.py +23 -23
  74. megadetector/postprocessing/compare_batch_results.py +590 -525
  75. megadetector/postprocessing/convert_output_format.py +106 -102
  76. megadetector/postprocessing/create_crop_folder.py +347 -147
  77. megadetector/postprocessing/detector_calibration.py +173 -168
  78. megadetector/postprocessing/generate_csv_report.py +508 -499
  79. megadetector/postprocessing/load_api_results.py +48 -27
  80. megadetector/postprocessing/md_to_coco.py +133 -102
  81. megadetector/postprocessing/md_to_labelme.py +107 -90
  82. megadetector/postprocessing/md_to_wi.py +40 -40
  83. megadetector/postprocessing/merge_detections.py +92 -114
  84. megadetector/postprocessing/postprocess_batch_results.py +319 -301
  85. megadetector/postprocessing/remap_detection_categories.py +91 -38
  86. megadetector/postprocessing/render_detection_confusion_matrix.py +214 -205
  87. megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
  88. megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +27 -28
  89. megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +704 -679
  90. megadetector/postprocessing/separate_detections_into_folders.py +226 -211
  91. megadetector/postprocessing/subset_json_detector_output.py +265 -262
  92. megadetector/postprocessing/top_folders_to_bottom.py +45 -45
  93. megadetector/postprocessing/validate_batch_results.py +70 -70
  94. megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
  95. megadetector/taxonomy_mapping/map_new_lila_datasets.py +18 -19
  96. megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +54 -33
  97. megadetector/taxonomy_mapping/preview_lila_taxonomy.py +67 -67
  98. megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
  99. megadetector/taxonomy_mapping/simple_image_download.py +8 -8
  100. megadetector/taxonomy_mapping/species_lookup.py +156 -74
  101. megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
  102. megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
  103. megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
  104. megadetector/utils/ct_utils.py +1049 -211
  105. megadetector/utils/directory_listing.py +21 -77
  106. megadetector/utils/gpu_test.py +22 -22
  107. megadetector/utils/md_tests.py +632 -529
  108. megadetector/utils/path_utils.py +1520 -431
  109. megadetector/utils/process_utils.py +41 -41
  110. megadetector/utils/split_locations_into_train_val.py +62 -62
  111. megadetector/utils/string_utils.py +148 -27
  112. megadetector/utils/url_utils.py +489 -176
  113. megadetector/utils/wi_utils.py +2658 -2526
  114. megadetector/utils/write_html_image_list.py +137 -137
  115. megadetector/visualization/plot_utils.py +34 -30
  116. megadetector/visualization/render_images_with_thumbnails.py +39 -74
  117. megadetector/visualization/visualization_utils.py +487 -435
  118. megadetector/visualization/visualize_db.py +232 -198
  119. megadetector/visualization/visualize_detector_output.py +82 -76
  120. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/METADATA +5 -2
  121. megadetector-10.0.0.dist-info/RECORD +139 -0
  122. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/WHEEL +1 -1
  123. megadetector/api/batch_processing/api_core/__init__.py +0 -0
  124. megadetector/api/batch_processing/api_core/batch_service/__init__.py +0 -0
  125. megadetector/api/batch_processing/api_core/batch_service/score.py +0 -439
  126. megadetector/api/batch_processing/api_core/server.py +0 -294
  127. megadetector/api/batch_processing/api_core/server_api_config.py +0 -97
  128. megadetector/api/batch_processing/api_core/server_app_config.py +0 -55
  129. megadetector/api/batch_processing/api_core/server_batch_job_manager.py +0 -220
  130. megadetector/api/batch_processing/api_core/server_job_status_table.py +0 -149
  131. megadetector/api/batch_processing/api_core/server_orchestration.py +0 -360
  132. megadetector/api/batch_processing/api_core/server_utils.py +0 -88
  133. megadetector/api/batch_processing/api_core_support/__init__.py +0 -0
  134. megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +0 -46
  135. megadetector/api/batch_processing/api_support/__init__.py +0 -0
  136. megadetector/api/batch_processing/api_support/summarize_daily_activity.py +0 -152
  137. megadetector/api/batch_processing/data_preparation/__init__.py +0 -0
  138. megadetector/api/synchronous/__init__.py +0 -0
  139. megadetector/api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
  140. megadetector/api/synchronous/api_core/animal_detection_api/api_backend.py +0 -151
  141. megadetector/api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -263
  142. megadetector/api/synchronous/api_core/animal_detection_api/config.py +0 -35
  143. megadetector/api/synchronous/api_core/tests/__init__.py +0 -0
  144. megadetector/api/synchronous/api_core/tests/load_test.py +0 -110
  145. megadetector/data_management/importers/add_nacti_sizes.py +0 -52
  146. megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
  147. megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
  148. megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
  149. megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
  150. megadetector/data_management/importers/awc_to_json.py +0 -191
  151. megadetector/data_management/importers/bellevue_to_json.py +0 -272
  152. megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
  153. megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
  154. megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
  155. megadetector/data_management/importers/cct_field_adjustments.py +0 -58
  156. megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
  157. megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  158. megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
  159. megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
  160. megadetector/data_management/importers/ena24_to_json.py +0 -276
  161. megadetector/data_management/importers/filenames_to_json.py +0 -386
  162. megadetector/data_management/importers/helena_to_cct.py +0 -283
  163. megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
  164. megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  165. megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
  166. megadetector/data_management/importers/jb_csv_to_json.py +0 -150
  167. megadetector/data_management/importers/mcgill_to_json.py +0 -250
  168. megadetector/data_management/importers/missouri_to_json.py +0 -490
  169. megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
  170. megadetector/data_management/importers/noaa_seals_2019.py +0 -181
  171. megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
  172. megadetector/data_management/importers/pc_to_json.py +0 -365
  173. megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
  174. megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
  175. megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
  176. megadetector/data_management/importers/rspb_to_json.py +0 -356
  177. megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
  178. megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
  179. megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
  180. megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
  181. megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  182. megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  183. megadetector/data_management/importers/sulross_get_exif.py +0 -65
  184. megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
  185. megadetector/data_management/importers/ubc_to_json.py +0 -399
  186. megadetector/data_management/importers/umn_to_json.py +0 -507
  187. megadetector/data_management/importers/wellington_to_json.py +0 -263
  188. megadetector/data_management/importers/wi_to_json.py +0 -442
  189. megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
  190. megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
  191. megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
  192. megadetector/utils/azure_utils.py +0 -178
  193. megadetector/utils/sas_blob_utils.py +0 -509
  194. megadetector-5.0.28.dist-info/RECORD +0 -209
  195. /megadetector/{api/batch_processing/__init__.py → __init__.py} +0 -0
  196. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/licenses/LICENSE +0 -0
  197. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/top_level.txt +0 -0
@@ -4,30 +4,104 @@ add_width_and_height_to_db.py
4
4
 
5
5
  Grabs width and height from actual image files for a .json database that is missing w/h.
6
6
 
7
- TODO: this is a one-off script waiting to be cleaned up for more general use.
8
-
9
7
  """
10
8
 
11
9
  #%% Imports and constants
12
10
 
11
+ import os
12
+ import sys
13
13
  import json
14
+ import argparse
15
+
16
+ from tqdm import tqdm
14
17
  from PIL import Image
15
18
 
16
- datafile = '/datadrive/snapshotserengeti/databases/snapshotserengeti.json'
17
- image_base = '/datadrive/snapshotserengeti/images/'
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)
18
54
 
19
- def main():
55
+ if not os.path.isfile(fn_abs):
56
+ print('Could not find image file {}'.format(fn_abs))
57
+ continue
20
58
 
21
- with open(datafile,'r') as f:
22
- data = json.load(f)
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)
23
68
 
24
- for im in data['images']:
25
- if 'height' not in im:
26
- im_w, im_h = Image.open(image_base+im['file_name']).size
27
69
  im['height'] = im_h
28
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
29
83
 
30
- json.dump(data, open(datafile,'w'))
84
+ # ...def add_width_and_height_to_db(...)
85
+
86
+
87
+ #%% Command-line driver
31
88
 
32
89
  if __name__ == '__main__':
33
- 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)
@@ -10,7 +10,7 @@ writing the results to another .json file.
10
10
  - Checks compatibility in info structs, within reason.
11
11
 
12
12
  *Example command-line invocation*
13
-
13
+
14
14
  combine_coco_camera_traps_files input1.json input2.json ... inputN.json output.json
15
15
 
16
16
  """
@@ -20,12 +20,13 @@ combine_coco_camera_traps_files input1.json input2.json ... inputN.json output.j
20
20
  import argparse
21
21
  import json
22
22
  import sys
23
+ from megadetector.utils import ct_utils
23
24
 
24
25
 
25
26
  #%% Merge functions
26
27
 
27
- def combine_cct_files(input_files,
28
- output_file=None,
28
+ def combine_cct_files(input_files,
29
+ output_file=None,
29
30
  require_uniqueness=True,
30
31
  filename_prefixes=None):
31
32
  """
@@ -38,12 +39,12 @@ def combine_cct_files(input_files,
38
39
  require_uniqueness (bool, optional): whether to require that the images in
39
40
  each input_dict be unique
40
41
  filename_prefixes (dict, optional): dict mapping input filenames to strings
41
- that should be prepended to image filenames from that source
42
-
42
+ that should be prepended to image filenames from that source
43
+
43
44
  Returns:
44
45
  dict: the merged COCO-formatted .json dict
45
46
  """
46
-
47
+
47
48
  input_dicts = []
48
49
  print('Loading input files')
49
50
  for fn in input_files:
@@ -60,34 +61,33 @@ def combine_cct_files(input_files,
60
61
 
61
62
  print('Writing output')
62
63
  if output_file is not None:
63
- with open(output_file, 'w') as f:
64
- json.dump(merged_dict, f, indent=1)
64
+ ct_utils.write_json(output_file, merged_dict)
65
65
 
66
66
  return merged_dict
67
67
 
68
68
 
69
- def combine_cct_dictionaries(input_dicts, require_uniqueness=True):
69
+ def combine_cct_dictionaries(input_dicts, require_uniqueness=True):
70
70
  """
71
71
  Merges the list of COCO Camera Traps dictionaries [input_dicts]. See module header
72
72
  comment for details on merge rules.
73
73
 
74
74
  Args:
75
- input_dicts: list of CCT dicts
76
- require_uniqueness: bool, whether to require that the images in
75
+ input_dicts (list of dict): list of CCT dicts
76
+ require_uniqueness (bool, optional): whether to require that the images in
77
77
  each input_dict be unique
78
78
 
79
- Returns:
79
+ Returns:
80
80
  dict: the merged COCO-formatted .json dict
81
81
  """
82
-
82
+
83
83
  filename_to_image = {}
84
84
  all_annotations = []
85
85
  info = None
86
-
86
+
87
87
  category_name_to_id = {}
88
88
  category_name_to_id['empty'] = 0
89
89
  next_category_id = 1
90
-
90
+
91
91
  known_fields = ['info', 'categories', 'annotations','images','filename_prefix']
92
92
 
93
93
  # i_input_dict = 0; input_dict = input_dicts[i_input_dict]
@@ -96,19 +96,19 @@ def combine_cct_dictionaries(input_dicts, require_uniqueness=True):
96
96
  filename_prefix = ''
97
97
  if ('filename_prefix' in input_dict.keys()):
98
98
  filename_prefix = input_dict['filename_prefix']
99
-
99
+
100
100
  for k in input_dict.keys():
101
101
  if k not in known_fields:
102
102
  raise ValueError(f'Unrecognized CCT field: {k}')
103
103
 
104
104
  # We will prepend an index to every ID to guarantee uniqueness
105
105
  index_string = 'ds' + str(i_input_dict).zfill(3) + '_'
106
-
106
+
107
107
  old_cat_id_to_new_cat_id = {}
108
-
108
+
109
109
  # Map detection categories from the original data set into the merged data set
110
110
  for original_category in input_dict['categories']:
111
-
111
+
112
112
  original_cat_id = original_category['id']
113
113
  cat_name = original_category['name']
114
114
  if cat_name in category_name_to_id:
@@ -117,58 +117,58 @@ def combine_cct_dictionaries(input_dicts, require_uniqueness=True):
117
117
  new_cat_id = next_category_id
118
118
  next_category_id += 1
119
119
  category_name_to_id[cat_name] = new_cat_id
120
-
120
+
121
121
  if original_cat_id in old_cat_id_to_new_cat_id:
122
122
  assert old_cat_id_to_new_cat_id[original_cat_id] == new_cat_id
123
123
  else:
124
124
  old_cat_id_to_new_cat_id[original_cat_id] = new_cat_id
125
-
125
+
126
126
  # ...for each category
127
-
128
-
127
+
128
+
129
129
  # Merge original image list into the merged data set
130
130
  for im in input_dict['images']:
131
-
131
+
132
132
  if 'seq_id' in im:
133
133
  im['seq_id'] = index_string + im['seq_id']
134
134
  if 'location' in im:
135
135
  im['location'] = index_string + im['location']
136
-
136
+
137
137
  im_file = filename_prefix + im['file_name']
138
138
  im['file_name'] = im_file
139
139
  if require_uniqueness:
140
- assert im_file not in filename_to_image, f'Duplicate image: {im_file}'
140
+ assert im_file not in filename_to_image, f'Duplicate image: {im_file}'
141
141
  else:
142
142
  if im_file in filename_to_image:
143
143
  print('Redundant image {}'.format(im_file))
144
-
144
+
145
145
  # Create a unique ID
146
146
  im['id'] = index_string + im['id']
147
147
  filename_to_image[im_file] = im
148
148
 
149
149
  # ...for each image
150
-
151
-
150
+
151
+
152
152
  # Same for annotations
153
153
  for ann in input_dict['annotations']:
154
-
154
+
155
155
  ann['image_id'] = index_string + ann['image_id']
156
156
  ann['id'] = index_string + ann['id']
157
157
  assert ann['category_id'] in old_cat_id_to_new_cat_id
158
158
  ann['category_id'] = old_cat_id_to_new_cat_id[ann['category_id']]
159
-
159
+
160
160
  # ...for each annotation
161
-
161
+
162
162
  all_annotations.extend(input_dict['annotations'])
163
-
163
+
164
164
  # Merge info dicts, don't check completion time fields
165
165
  if info is None:
166
- import copy
166
+ import copy
167
167
  info = copy.deepcopy(input_dict['info'])
168
168
  info['original_info'] = [input_dict['info']]
169
169
  else:
170
170
  info['original_info'].append(input_dict['info'])
171
-
171
+
172
172
  # ...for each dictionary
173
173
 
174
174
  # Convert merged image dictionaries to a sorted list
@@ -176,12 +176,12 @@ def combine_cct_dictionaries(input_dicts, require_uniqueness=True):
176
176
 
177
177
  all_categories = [{'id':category_name_to_id[cat_name],'name':cat_name} for\
178
178
  cat_name in category_name_to_id.keys()]
179
-
179
+
180
180
  merged_dict = {'info': info,
181
181
  'categories': all_categories,
182
182
  'images': sorted_images,
183
183
  'annotations': all_annotations}
184
-
184
+
185
185
  return merged_dict
186
186
 
187
187
  # ...combine_cct_dictionaries(...)
@@ -189,8 +189,8 @@ def combine_cct_dictionaries(input_dicts, require_uniqueness=True):
189
189
 
190
190
  #%% Command-line driver
191
191
 
192
- def main():
193
-
192
+ def main(): # noqa
193
+
194
194
  parser = argparse.ArgumentParser()
195
195
  parser.add_argument(
196
196
  'input_paths', nargs='+',
@@ -202,7 +202,7 @@ def main():
202
202
  if len(sys.argv[1:]) == 0:
203
203
  parser.print_help()
204
204
  parser.exit()
205
-
205
+
206
206
  args = parser.parse_args()
207
207
  combine_cct_files(args.input_paths, args.output_path)
208
208