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.
- megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
- megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
- megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
- megadetector/classification/aggregate_classifier_probs.py +3 -3
- megadetector/classification/analyze_failed_images.py +5 -5
- megadetector/classification/cache_batchapi_outputs.py +5 -5
- megadetector/classification/create_classification_dataset.py +11 -12
- megadetector/classification/crop_detections.py +10 -10
- megadetector/classification/csv_to_json.py +8 -8
- megadetector/classification/detect_and_crop.py +13 -15
- megadetector/classification/efficientnet/model.py +8 -8
- megadetector/classification/efficientnet/utils.py +6 -5
- megadetector/classification/evaluate_model.py +7 -7
- megadetector/classification/identify_mislabeled_candidates.py +6 -6
- megadetector/classification/json_to_azcopy_list.py +1 -1
- megadetector/classification/json_validator.py +29 -32
- megadetector/classification/map_classification_categories.py +9 -9
- megadetector/classification/merge_classification_detection_output.py +12 -9
- megadetector/classification/prepare_classification_script.py +19 -19
- megadetector/classification/prepare_classification_script_mc.py +26 -26
- megadetector/classification/run_classifier.py +4 -4
- megadetector/classification/save_mislabeled.py +6 -6
- megadetector/classification/train_classifier.py +1 -1
- megadetector/classification/train_classifier_tf.py +9 -9
- megadetector/classification/train_utils.py +10 -10
- megadetector/data_management/annotations/annotation_constants.py +1 -2
- megadetector/data_management/camtrap_dp_to_coco.py +79 -46
- megadetector/data_management/cct_json_utils.py +103 -103
- megadetector/data_management/cct_to_md.py +49 -49
- megadetector/data_management/cct_to_wi.py +33 -33
- megadetector/data_management/coco_to_labelme.py +75 -75
- megadetector/data_management/coco_to_yolo.py +210 -193
- megadetector/data_management/databases/add_width_and_height_to_db.py +86 -12
- megadetector/data_management/databases/combine_coco_camera_traps_files.py +40 -40
- megadetector/data_management/databases/integrity_check_json_db.py +228 -200
- megadetector/data_management/databases/subset_json_db.py +33 -33
- megadetector/data_management/generate_crops_from_cct.py +88 -39
- megadetector/data_management/get_image_sizes.py +54 -49
- megadetector/data_management/labelme_to_coco.py +133 -125
- megadetector/data_management/labelme_to_yolo.py +159 -73
- megadetector/data_management/lila/create_lila_blank_set.py +81 -83
- megadetector/data_management/lila/create_lila_test_set.py +32 -31
- megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
- megadetector/data_management/lila/download_lila_subset.py +21 -24
- megadetector/data_management/lila/generate_lila_per_image_labels.py +365 -107
- megadetector/data_management/lila/get_lila_annotation_counts.py +35 -33
- megadetector/data_management/lila/get_lila_image_counts.py +22 -22
- megadetector/data_management/lila/lila_common.py +73 -70
- megadetector/data_management/lila/test_lila_metadata_urls.py +28 -19
- megadetector/data_management/mewc_to_md.py +344 -340
- megadetector/data_management/ocr_tools.py +262 -255
- megadetector/data_management/read_exif.py +249 -227
- megadetector/data_management/remap_coco_categories.py +90 -28
- megadetector/data_management/remove_exif.py +81 -21
- megadetector/data_management/rename_images.py +187 -187
- megadetector/data_management/resize_coco_dataset.py +588 -120
- megadetector/data_management/speciesnet_to_md.py +41 -41
- megadetector/data_management/wi_download_csv_to_coco.py +55 -55
- megadetector/data_management/yolo_output_to_md_output.py +248 -122
- megadetector/data_management/yolo_to_coco.py +333 -191
- megadetector/detection/change_detection.py +832 -0
- megadetector/detection/process_video.py +340 -337
- megadetector/detection/pytorch_detector.py +358 -278
- megadetector/detection/run_detector.py +399 -186
- megadetector/detection/run_detector_batch.py +404 -377
- megadetector/detection/run_inference_with_yolov5_val.py +340 -327
- megadetector/detection/run_tiled_inference.py +257 -249
- megadetector/detection/tf_detector.py +24 -24
- megadetector/detection/video_utils.py +332 -295
- megadetector/postprocessing/add_max_conf.py +19 -11
- megadetector/postprocessing/categorize_detections_by_size.py +45 -45
- megadetector/postprocessing/classification_postprocessing.py +468 -433
- megadetector/postprocessing/combine_batch_outputs.py +23 -23
- megadetector/postprocessing/compare_batch_results.py +590 -525
- megadetector/postprocessing/convert_output_format.py +106 -102
- megadetector/postprocessing/create_crop_folder.py +347 -147
- megadetector/postprocessing/detector_calibration.py +173 -168
- megadetector/postprocessing/generate_csv_report.py +508 -499
- megadetector/postprocessing/load_api_results.py +48 -27
- megadetector/postprocessing/md_to_coco.py +133 -102
- megadetector/postprocessing/md_to_labelme.py +107 -90
- megadetector/postprocessing/md_to_wi.py +40 -40
- megadetector/postprocessing/merge_detections.py +92 -114
- megadetector/postprocessing/postprocess_batch_results.py +319 -301
- megadetector/postprocessing/remap_detection_categories.py +91 -38
- megadetector/postprocessing/render_detection_confusion_matrix.py +214 -205
- megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
- megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +27 -28
- megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +704 -679
- megadetector/postprocessing/separate_detections_into_folders.py +226 -211
- megadetector/postprocessing/subset_json_detector_output.py +265 -262
- megadetector/postprocessing/top_folders_to_bottom.py +45 -45
- megadetector/postprocessing/validate_batch_results.py +70 -70
- megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
- megadetector/taxonomy_mapping/map_new_lila_datasets.py +18 -19
- megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +54 -33
- megadetector/taxonomy_mapping/preview_lila_taxonomy.py +67 -67
- megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
- megadetector/taxonomy_mapping/simple_image_download.py +8 -8
- megadetector/taxonomy_mapping/species_lookup.py +156 -74
- megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
- megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
- megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
- megadetector/utils/ct_utils.py +1049 -211
- megadetector/utils/directory_listing.py +21 -77
- megadetector/utils/gpu_test.py +22 -22
- megadetector/utils/md_tests.py +632 -529
- megadetector/utils/path_utils.py +1520 -431
- megadetector/utils/process_utils.py +41 -41
- megadetector/utils/split_locations_into_train_val.py +62 -62
- megadetector/utils/string_utils.py +148 -27
- megadetector/utils/url_utils.py +489 -176
- megadetector/utils/wi_utils.py +2658 -2526
- megadetector/utils/write_html_image_list.py +137 -137
- megadetector/visualization/plot_utils.py +34 -30
- megadetector/visualization/render_images_with_thumbnails.py +39 -74
- megadetector/visualization/visualization_utils.py +487 -435
- megadetector/visualization/visualize_db.py +232 -198
- megadetector/visualization/visualize_detector_output.py +82 -76
- {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/METADATA +5 -2
- megadetector-10.0.0.dist-info/RECORD +139 -0
- {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/WHEEL +1 -1
- megadetector/api/batch_processing/api_core/__init__.py +0 -0
- megadetector/api/batch_processing/api_core/batch_service/__init__.py +0 -0
- megadetector/api/batch_processing/api_core/batch_service/score.py +0 -439
- megadetector/api/batch_processing/api_core/server.py +0 -294
- megadetector/api/batch_processing/api_core/server_api_config.py +0 -97
- megadetector/api/batch_processing/api_core/server_app_config.py +0 -55
- megadetector/api/batch_processing/api_core/server_batch_job_manager.py +0 -220
- megadetector/api/batch_processing/api_core/server_job_status_table.py +0 -149
- megadetector/api/batch_processing/api_core/server_orchestration.py +0 -360
- megadetector/api/batch_processing/api_core/server_utils.py +0 -88
- megadetector/api/batch_processing/api_core_support/__init__.py +0 -0
- megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +0 -46
- megadetector/api/batch_processing/api_support/__init__.py +0 -0
- megadetector/api/batch_processing/api_support/summarize_daily_activity.py +0 -152
- megadetector/api/batch_processing/data_preparation/__init__.py +0 -0
- megadetector/api/synchronous/__init__.py +0 -0
- megadetector/api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
- megadetector/api/synchronous/api_core/animal_detection_api/api_backend.py +0 -151
- megadetector/api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -263
- megadetector/api/synchronous/api_core/animal_detection_api/config.py +0 -35
- megadetector/api/synchronous/api_core/tests/__init__.py +0 -0
- megadetector/api/synchronous/api_core/tests/load_test.py +0 -110
- megadetector/data_management/importers/add_nacti_sizes.py +0 -52
- megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
- megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
- megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
- megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
- megadetector/data_management/importers/awc_to_json.py +0 -191
- megadetector/data_management/importers/bellevue_to_json.py +0 -272
- megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
- megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
- megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
- megadetector/data_management/importers/cct_field_adjustments.py +0 -58
- megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
- megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
- megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
- megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
- megadetector/data_management/importers/ena24_to_json.py +0 -276
- megadetector/data_management/importers/filenames_to_json.py +0 -386
- megadetector/data_management/importers/helena_to_cct.py +0 -283
- megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
- megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
- megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
- megadetector/data_management/importers/jb_csv_to_json.py +0 -150
- megadetector/data_management/importers/mcgill_to_json.py +0 -250
- megadetector/data_management/importers/missouri_to_json.py +0 -490
- megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
- megadetector/data_management/importers/noaa_seals_2019.py +0 -181
- megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
- megadetector/data_management/importers/pc_to_json.py +0 -365
- megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
- megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
- megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
- megadetector/data_management/importers/rspb_to_json.py +0 -356
- megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
- megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
- megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
- megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
- megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
- megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
- megadetector/data_management/importers/sulross_get_exif.py +0 -65
- megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
- megadetector/data_management/importers/ubc_to_json.py +0 -399
- megadetector/data_management/importers/umn_to_json.py +0 -507
- megadetector/data_management/importers/wellington_to_json.py +0 -263
- megadetector/data_management/importers/wi_to_json.py +0 -442
- megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
- megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
- megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
- megadetector/utils/azure_utils.py +0 -178
- megadetector/utils/sas_blob_utils.py +0 -509
- megadetector-5.0.28.dist-info/RECORD +0 -209
- /megadetector/{api/batch_processing/__init__.py → __init__.py} +0 -0
- {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
55
|
+
if not os.path.isfile(fn_abs):
|
|
56
|
+
print('Could not find image file {}'.format(fn_abs))
|
|
57
|
+
continue
|
|
20
58
|
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
84
|
+
# ...def add_width_and_height_to_db(...)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
#%% Command-line driver
|
|
31
88
|
|
|
32
89
|
if __name__ == '__main__':
|
|
33
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|