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
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
md_to_labelme.py
|
|
4
4
|
|
|
5
5
|
"Converts" a MegaDetector output .json file to labelme format (one .json per image
|
|
6
|
-
file). "Convert" is in quotes because this is an opinionated transformation that
|
|
6
|
+
file). "Convert" is in quotes because this is an opinionated transformation that
|
|
7
7
|
requires a confidence threshold.
|
|
8
8
|
|
|
9
|
-
TODO:
|
|
10
|
-
|
|
9
|
+
TODO: # noqa
|
|
10
|
+
|
|
11
11
|
* support variable confidence thresholds across classes
|
|
12
12
|
* support classification data
|
|
13
13
|
|
|
@@ -17,6 +17,8 @@ TODO:
|
|
|
17
17
|
|
|
18
18
|
import os
|
|
19
19
|
import json
|
|
20
|
+
import sys
|
|
21
|
+
import argparse
|
|
20
22
|
|
|
21
23
|
from tqdm import tqdm
|
|
22
24
|
|
|
@@ -39,10 +41,10 @@ def get_labelme_dict_for_image(im,image_base_name=None,category_id_to_name=None,
|
|
|
39
41
|
"""
|
|
40
42
|
For the given image struct in MD results format, reformat the detections into
|
|
41
43
|
labelme format.
|
|
42
|
-
|
|
44
|
+
|
|
43
45
|
Args:
|
|
44
46
|
im (dict): MegaDetector-formatted results dict, must include 'height' and 'width' fields
|
|
45
|
-
image_base_name (str, optional): written directly to the 'imagePath' field in the output;
|
|
47
|
+
image_base_name (str, optional): written directly to the 'imagePath' field in the output;
|
|
46
48
|
defaults to os.path.basename(im['file']).
|
|
47
49
|
category_id_to_name (dict, optional): maps string-int category IDs to category names, defaults
|
|
48
50
|
to the standard MD categories
|
|
@@ -50,20 +52,20 @@ def get_labelme_dict_for_image(im,image_base_name=None,category_id_to_name=None,
|
|
|
50
52
|
dict
|
|
51
53
|
confidence_threshold (float, optional): only detections at or above this confidence threshold
|
|
52
54
|
will be included in the output dict
|
|
53
|
-
|
|
55
|
+
|
|
54
56
|
Return:
|
|
55
57
|
dict: labelme-formatted dictionary, suitable for writing directly to a labelme-formatted .json file
|
|
56
58
|
"""
|
|
57
|
-
|
|
59
|
+
|
|
58
60
|
if image_base_name is None:
|
|
59
61
|
image_base_name = os.path.basename(im['file'])
|
|
60
|
-
|
|
62
|
+
|
|
61
63
|
if category_id_to_name:
|
|
62
64
|
category_id_to_name = DEFAULT_DETECTOR_LABEL_MAP
|
|
63
|
-
|
|
64
|
-
if confidence_threshold is None:
|
|
65
|
+
|
|
66
|
+
if confidence_threshold is None:
|
|
65
67
|
confidence_threshold = -1.0
|
|
66
|
-
|
|
68
|
+
|
|
67
69
|
output_dict = {}
|
|
68
70
|
if info is not None:
|
|
69
71
|
output_dict['detector_info'] = info
|
|
@@ -75,22 +77,22 @@ def get_labelme_dict_for_image(im,image_base_name=None,category_id_to_name=None,
|
|
|
75
77
|
output_dict['imageWidth'] = im['width']
|
|
76
78
|
output_dict['imageData'] = None
|
|
77
79
|
output_dict['detections'] = im['detections']
|
|
78
|
-
|
|
80
|
+
|
|
79
81
|
# det = im['detections'][1]
|
|
80
82
|
for det in im['detections']:
|
|
81
|
-
|
|
83
|
+
|
|
82
84
|
if det['conf'] < confidence_threshold:
|
|
83
85
|
continue
|
|
84
|
-
|
|
86
|
+
|
|
85
87
|
shape = {}
|
|
86
88
|
shape['conf'] = det['conf']
|
|
87
|
-
shape['label'] = category_id_to_name[det['category']]
|
|
89
|
+
shape['label'] = category_id_to_name[det['category']]
|
|
88
90
|
shape['shape_type'] = 'rectangle'
|
|
89
91
|
shape['description'] = ''
|
|
90
92
|
shape['group_id'] = None
|
|
91
|
-
|
|
93
|
+
|
|
92
94
|
# MD boxes are [x_min, y_min, width_of_box, height_of_box] (relative)
|
|
93
|
-
#
|
|
95
|
+
#
|
|
94
96
|
# labelme boxes are [[x0,y0],[x1,y1]] (absolute)
|
|
95
97
|
x0 = round_float(det['bbox'][0] * im['width'],output_precision)
|
|
96
98
|
y0 = round_float(det['bbox'][1] * im['height'],output_precision)
|
|
@@ -98,28 +100,33 @@ def get_labelme_dict_for_image(im,image_base_name=None,category_id_to_name=None,
|
|
|
98
100
|
y1 = round_float(y0 + det['bbox'][3] * im['height'],output_precision)
|
|
99
101
|
shape['points'] = [[x0,y0],[x1,y1]]
|
|
100
102
|
output_dict['shapes'].append(shape)
|
|
101
|
-
|
|
103
|
+
|
|
102
104
|
# ...for each detection
|
|
103
|
-
|
|
105
|
+
|
|
104
106
|
return output_dict
|
|
105
107
|
|
|
106
108
|
# ...def get_labelme_dict_for_image()
|
|
107
109
|
|
|
108
110
|
|
|
109
|
-
def _write_output_for_image(im,
|
|
110
|
-
|
|
111
|
+
def _write_output_for_image(im,
|
|
112
|
+
image_base,
|
|
113
|
+
extension_prefix,
|
|
114
|
+
info,
|
|
115
|
+
confidence_threshold,
|
|
116
|
+
category_id_to_name,
|
|
117
|
+
overwrite,
|
|
111
118
|
verbose=False):
|
|
112
|
-
|
|
119
|
+
|
|
113
120
|
if 'failure' in im and im['failure'] is not None:
|
|
114
121
|
assert 'detections' not in im or im['detections'] is None
|
|
115
122
|
if verbose:
|
|
116
123
|
print('Skipping labelme file generation for failed image {}'.format(
|
|
117
124
|
im['file']))
|
|
118
125
|
return
|
|
119
|
-
|
|
126
|
+
|
|
120
127
|
im_full_path = os.path.join(image_base,im['file'])
|
|
121
128
|
json_path = os.path.splitext(im_full_path)[0] + extension_prefix + '.json'
|
|
122
|
-
|
|
129
|
+
|
|
123
130
|
if (not overwrite) and (os.path.isfile(json_path)):
|
|
124
131
|
if verbose:
|
|
125
132
|
print('Skipping existing file {}'.format(json_path))
|
|
@@ -130,43 +137,49 @@ def _write_output_for_image(im,image_base,extension_prefix,info,
|
|
|
130
137
|
category_id_to_name=category_id_to_name,
|
|
131
138
|
info=info,
|
|
132
139
|
confidence_threshold=confidence_threshold)
|
|
133
|
-
|
|
140
|
+
|
|
134
141
|
with open(json_path,'w') as f:
|
|
135
142
|
json.dump(output_dict,f,indent=1)
|
|
136
|
-
|
|
143
|
+
|
|
137
144
|
# ...def write_output_for_image(...)
|
|
138
145
|
|
|
139
146
|
|
|
140
147
|
|
|
141
|
-
def md_to_labelme(results_file,
|
|
142
|
-
|
|
143
|
-
|
|
148
|
+
def md_to_labelme(results_file,
|
|
149
|
+
image_base,
|
|
150
|
+
confidence_threshold=None,
|
|
151
|
+
overwrite=False,
|
|
152
|
+
extension_prefix='',
|
|
153
|
+
n_workers=1,
|
|
154
|
+
use_threads=False,
|
|
155
|
+
bypass_image_size_read=False,
|
|
144
156
|
verbose=False):
|
|
145
157
|
"""
|
|
146
158
|
For all the images in [results_file], write a .json file in labelme format alongside the
|
|
147
159
|
corresponding relative path within image_base.
|
|
148
|
-
|
|
160
|
+
|
|
149
161
|
Args:
|
|
150
162
|
results_file (str): MD results .json file to convert to Labelme format
|
|
151
163
|
image_base (str): folder of images; filenames in [results_file] should be relative to
|
|
152
164
|
this folder
|
|
153
165
|
confidence_threshold (float, optional): only detections at or above this confidence threshold
|
|
154
|
-
will be included in the output dict
|
|
166
|
+
will be included in the output dict. If None, no threshold will be applied.
|
|
155
167
|
overwrite (bool, optional): whether to overwrite existing output files; if this is False
|
|
156
168
|
and the output file for an image exists, we'll skip that image
|
|
157
|
-
extension_prefix (str, optional): if non-empty, "extension_prefix" will be inserted before the .json
|
|
158
|
-
extension
|
|
169
|
+
extension_prefix (str, optional): if non-empty, "extension_prefix" will be inserted before the .json
|
|
170
|
+
extension (typically used to generate multiple copies of labelme files representing different
|
|
171
|
+
MD thresholds)
|
|
159
172
|
n_workers (int, optional): enables multiprocessing if > 1
|
|
160
173
|
use_threads (bool, optional): if [n_workers] > 1, determines whether we parallelize via threads (True)
|
|
161
174
|
or processes (False)
|
|
162
175
|
bypass_image_size_read (bool, optional): if True, skips reading image sizes and trusts whatever is in
|
|
163
176
|
the MD results file (don't set this to "True" if your MD results file doesn't contain image sizes)
|
|
164
|
-
verbose (bool, optional): enables additionald ebug output
|
|
177
|
+
verbose (bool, optional): enables additionald ebug output
|
|
165
178
|
"""
|
|
166
|
-
|
|
179
|
+
|
|
167
180
|
if extension_prefix is None:
|
|
168
181
|
extension_prefix = ''
|
|
169
|
-
|
|
182
|
+
|
|
170
183
|
# Load MD results if necessary
|
|
171
184
|
if isinstance(results_file,dict):
|
|
172
185
|
md_results = results_file
|
|
@@ -174,34 +187,34 @@ def md_to_labelme(results_file,image_base,confidence_threshold=None,
|
|
|
174
187
|
print('Loading MD results...')
|
|
175
188
|
with open(results_file,'r') as f:
|
|
176
189
|
md_results = json.load(f)
|
|
177
|
-
|
|
178
|
-
# Read image sizes if necessary
|
|
179
|
-
if bypass_image_size_read:
|
|
180
|
-
|
|
190
|
+
|
|
191
|
+
# Read image sizes if necessary
|
|
192
|
+
if bypass_image_size_read:
|
|
193
|
+
|
|
181
194
|
print('Bypassing image size read')
|
|
182
|
-
|
|
195
|
+
|
|
183
196
|
else:
|
|
184
|
-
|
|
197
|
+
|
|
185
198
|
# TODO: parallelize this loop
|
|
186
|
-
|
|
199
|
+
|
|
187
200
|
print('Reading image sizes...')
|
|
188
|
-
|
|
201
|
+
|
|
189
202
|
# im = md_results['images'][0]
|
|
190
203
|
for im in tqdm(md_results['images']):
|
|
191
|
-
|
|
204
|
+
|
|
192
205
|
# Make sure this file exists
|
|
193
206
|
im_full_path = os.path.join(image_base,im['file'])
|
|
194
207
|
assert os.path.isfile(im_full_path), 'Image file {} does not exist'.format(im_full_path)
|
|
195
|
-
|
|
208
|
+
|
|
196
209
|
json_path = os.path.splitext(im_full_path)[0] + extension_prefix + '.json'
|
|
197
|
-
|
|
210
|
+
|
|
198
211
|
# Don't even bother reading sizes for files we're not going to generate
|
|
199
212
|
if (not overwrite) and (os.path.isfile(json_path)):
|
|
200
213
|
continue
|
|
201
|
-
|
|
214
|
+
|
|
202
215
|
# Load w/h information if necessary
|
|
203
216
|
if 'height' not in im or 'width' not in im:
|
|
204
|
-
|
|
217
|
+
|
|
205
218
|
try:
|
|
206
219
|
pil_im = open_image(im_full_path)
|
|
207
220
|
im['width'] = pil_im.width
|
|
@@ -211,88 +224,92 @@ def md_to_labelme(results_file,image_base,confidence_threshold=None,
|
|
|
211
224
|
im_full_path))
|
|
212
225
|
if 'failure' not in im:
|
|
213
226
|
im['failure'] = FAILURE_IMAGE_OPEN
|
|
214
|
-
|
|
227
|
+
|
|
215
228
|
# ...if we need to read w/h information
|
|
216
|
-
|
|
229
|
+
|
|
217
230
|
# ...for each image
|
|
218
|
-
|
|
219
|
-
# ...if we're not bypassing image size read
|
|
220
|
-
|
|
231
|
+
|
|
232
|
+
# ...if we're not bypassing image size read
|
|
233
|
+
|
|
221
234
|
print('\nGenerating labelme files...')
|
|
222
|
-
|
|
235
|
+
|
|
223
236
|
# Write output
|
|
224
237
|
if n_workers <= 1:
|
|
225
|
-
for im in tqdm(md_results['images']):
|
|
238
|
+
for im in tqdm(md_results['images']):
|
|
226
239
|
_write_output_for_image(im,image_base,extension_prefix,md_results['info'],confidence_threshold,
|
|
227
240
|
md_results['detection_categories'],overwrite,verbose)
|
|
228
241
|
else:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
pool = None
|
|
243
|
+
try:
|
|
244
|
+
if use_threads:
|
|
245
|
+
print('Starting parallel thread pool with {} workers'.format(n_workers))
|
|
246
|
+
pool = ThreadPool(n_workers)
|
|
247
|
+
else:
|
|
248
|
+
print('Starting parallel process pool with {} workers'.format(n_workers))
|
|
249
|
+
pool = Pool(n_workers)
|
|
250
|
+
_ = list(tqdm(pool.imap(
|
|
251
|
+
partial(_write_output_for_image,
|
|
252
|
+
image_base=image_base,extension_prefix=extension_prefix,
|
|
253
|
+
info=md_results['info'],confidence_threshold=confidence_threshold,
|
|
254
|
+
category_id_to_name=md_results['detection_categories'],
|
|
255
|
+
overwrite=overwrite,verbose=verbose),
|
|
256
|
+
md_results['images']),
|
|
257
|
+
total=len(md_results['images'])))
|
|
258
|
+
finally:
|
|
259
|
+
pool.close()
|
|
260
|
+
pool.join()
|
|
261
|
+
print("Pool closed and joined for labelme file writes")
|
|
262
|
+
|
|
244
263
|
# ...for each image
|
|
245
|
-
|
|
264
|
+
|
|
246
265
|
# ...def md_to_labelme()
|
|
247
266
|
|
|
248
267
|
|
|
249
268
|
#%% Interactive driver
|
|
250
269
|
|
|
251
270
|
if False:
|
|
252
|
-
|
|
271
|
+
|
|
253
272
|
pass
|
|
254
273
|
|
|
255
274
|
#%% Configure options
|
|
256
|
-
|
|
275
|
+
|
|
257
276
|
md_results_file = os.path.expanduser('~/data/md-test.json')
|
|
258
277
|
coco_output_file = os.path.expanduser('~/data/md-test-coco.json')
|
|
259
|
-
image_folder = os.path.expanduser('~/data/md-test')
|
|
278
|
+
image_folder = os.path.expanduser('~/data/md-test')
|
|
260
279
|
confidence_threshold = 0.2
|
|
261
|
-
overwrite = True
|
|
262
|
-
|
|
263
|
-
|
|
280
|
+
overwrite = True
|
|
281
|
+
|
|
282
|
+
|
|
264
283
|
#%% Programmatic execution
|
|
265
|
-
|
|
284
|
+
|
|
266
285
|
md_to_labelme(results_file=md_results_file,
|
|
267
286
|
image_base=image_folder,
|
|
268
287
|
confidence_threshold=confidence_threshold,
|
|
269
288
|
overwrite=overwrite)
|
|
270
289
|
|
|
271
|
-
|
|
290
|
+
|
|
272
291
|
#%% Command-line execution
|
|
273
|
-
|
|
292
|
+
|
|
274
293
|
s = 'python md_to_labelme.py {} {} --confidence_threshold {}'.format(md_results_file,
|
|
275
294
|
image_folder,
|
|
276
295
|
confidence_threshold)
|
|
277
296
|
if overwrite:
|
|
278
297
|
s += ' --overwrite'
|
|
279
|
-
|
|
298
|
+
|
|
280
299
|
print(s)
|
|
281
300
|
import clipboard; clipboard.copy(s)
|
|
282
301
|
|
|
283
302
|
|
|
284
303
|
#%% Opening labelme
|
|
285
|
-
|
|
304
|
+
|
|
286
305
|
s = 'python labelme {}'.format(image_folder)
|
|
287
306
|
print(s)
|
|
288
307
|
import clipboard; clipboard.copy(s)
|
|
289
|
-
|
|
290
308
|
|
|
291
|
-
#%% Command-line driver
|
|
292
309
|
|
|
293
|
-
|
|
310
|
+
#%% Command-line driver
|
|
294
311
|
|
|
295
|
-
def main():
|
|
312
|
+
def main(): # noqa
|
|
296
313
|
|
|
297
314
|
parser = argparse.ArgumentParser(
|
|
298
315
|
description='Convert MD output to labelme annotation format')
|
|
@@ -300,19 +317,19 @@ def main():
|
|
|
300
317
|
'results_file',
|
|
301
318
|
type=str,
|
|
302
319
|
help='Path to MD results file (.json)')
|
|
303
|
-
|
|
320
|
+
|
|
304
321
|
parser.add_argument(
|
|
305
322
|
'image_base',
|
|
306
323
|
type=str,
|
|
307
324
|
help='Path to images (also the output folder)')
|
|
308
|
-
|
|
325
|
+
|
|
309
326
|
parser.add_argument(
|
|
310
327
|
'--confidence_threshold',
|
|
311
328
|
type=float,
|
|
312
329
|
default=default_confidence_threshold,
|
|
313
330
|
help='Confidence threshold (default {})'.format(default_confidence_threshold)
|
|
314
331
|
)
|
|
315
|
-
|
|
332
|
+
|
|
316
333
|
parser.add_argument(
|
|
317
334
|
'--overwrite',
|
|
318
335
|
action='store_true',
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
md_to_wi.py
|
|
4
|
-
|
|
5
|
-
Converts the MD .json format to the WI predictions.json format.
|
|
6
|
-
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
#%% Imports and constants
|
|
10
|
-
|
|
11
|
-
import sys
|
|
12
|
-
import argparse
|
|
13
|
-
from megadetector.utils.wi_utils import generate_predictions_json_from_md_results
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
#%% Command-line driver
|
|
17
|
-
|
|
18
|
-
def main():
|
|
19
|
-
|
|
20
|
-
parser = argparse.ArgumentParser()
|
|
21
|
-
parser.add_argument('md_results_file', action='store', type=str,
|
|
22
|
-
help='output file in MD format to convert')
|
|
23
|
-
parser.add_argument('predictions_json_file', action='store', type=str,
|
|
24
|
-
help='.json file to write in predictions.json format')
|
|
25
|
-
parser.add_argument('--base_folder', action='store', type=str, default=None,
|
|
26
|
-
help='folder name to prepend to each path in md_results_file, ' + \
|
|
27
|
-
'to convert relative paths to absolute paths.')
|
|
28
|
-
|
|
29
|
-
if len(sys.argv[1:]) == 0:
|
|
30
|
-
parser.print_help()
|
|
31
|
-
parser.exit()
|
|
32
|
-
|
|
33
|
-
args = parser.parse_args()
|
|
34
|
-
|
|
35
|
-
generate_predictions_json_from_md_results(args.md_results_file,
|
|
36
|
-
args.predictions_json_file,
|
|
37
|
-
base_folder=None)
|
|
38
|
-
|
|
39
|
-
if __name__ == '__main__':
|
|
40
|
-
main()
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
md_to_wi.py
|
|
4
|
+
|
|
5
|
+
Converts the MD .json format to the WI predictions.json format.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
#%% Imports and constants
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
import argparse
|
|
13
|
+
from megadetector.utils.wi_utils import generate_predictions_json_from_md_results
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
#%% Command-line driver
|
|
17
|
+
|
|
18
|
+
def main(): # noqa
|
|
19
|
+
|
|
20
|
+
parser = argparse.ArgumentParser()
|
|
21
|
+
parser.add_argument('md_results_file', action='store', type=str,
|
|
22
|
+
help='output file in MD format to convert')
|
|
23
|
+
parser.add_argument('predictions_json_file', action='store', type=str,
|
|
24
|
+
help='.json file to write in predictions.json format')
|
|
25
|
+
parser.add_argument('--base_folder', action='store', type=str, default=None,
|
|
26
|
+
help='folder name to prepend to each path in md_results_file, ' + \
|
|
27
|
+
'to convert relative paths to absolute paths.')
|
|
28
|
+
|
|
29
|
+
if len(sys.argv[1:]) == 0:
|
|
30
|
+
parser.print_help()
|
|
31
|
+
parser.exit()
|
|
32
|
+
|
|
33
|
+
args = parser.parse_args()
|
|
34
|
+
|
|
35
|
+
generate_predictions_json_from_md_results(args.md_results_file,
|
|
36
|
+
args.predictions_json_file,
|
|
37
|
+
base_folder=None)
|
|
38
|
+
|
|
39
|
+
if __name__ == '__main__':
|
|
40
|
+
main()
|