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
|
@@ -23,25 +23,25 @@ from megadetector.utils import path_utils
|
|
|
23
23
|
|
|
24
24
|
def write_html_image_list(filename=None,images=None,options=None):
|
|
25
25
|
"""
|
|
26
|
-
Given a list of image file names, writes an HTML file that shows all those images,
|
|
26
|
+
Given a list of image file names, writes an HTML file that shows all those images,
|
|
27
27
|
with optional one-line headers above each.
|
|
28
28
|
|
|
29
29
|
Args:
|
|
30
|
-
filename (str, optional): the .html output file; if None, just returns a valid
|
|
30
|
+
filename (str, optional): the .html output file; if None, just returns a valid
|
|
31
31
|
options dict
|
|
32
|
-
images (list, optional): the images to write to the .html file; if None, just returns
|
|
32
|
+
images (list, optional): the images to write to the .html file; if None, just returns
|
|
33
33
|
a valid options dict. This can be a flat list of image filenames, or this can
|
|
34
34
|
be a list of dictionaries with one or more of the following fields:
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
- filename (image filename) (required, all other fields are optional)
|
|
37
37
|
- imageStyle (css style for this image)
|
|
38
38
|
- textStyle (css style for the title associated with this image)
|
|
39
39
|
- title (text label for this image)
|
|
40
40
|
- linkTarget (URL to which this image should link on click)
|
|
41
|
-
|
|
42
|
-
options (dict, optional): a dict with one or more of the following fields:
|
|
43
|
-
|
|
44
|
-
-
|
|
41
|
+
|
|
42
|
+
options (dict, optional): a dict with one or more of the following fields:
|
|
43
|
+
|
|
44
|
+
- f_html (file pointer to write to, used for splitting write operations over multiple calls)
|
|
45
45
|
- pageTitle (HTML page title)
|
|
46
46
|
- headerHtml (html text to include before the image list)
|
|
47
47
|
- subPageHeaderHtml (html text to include before the images when images are broken into pages)
|
|
@@ -52,28 +52,28 @@ def write_html_image_list(filename=None,images=None,options=None):
|
|
|
52
52
|
multiple files and a TOC with links)
|
|
53
53
|
- urlEncodeFilenames (default True, e.g. '#' will be replaced by '%23')
|
|
54
54
|
- urlEncodeLinkTargets (default True, e.g. '#' will be replaced by '%23')
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
"""
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
# returns an options struct
|
|
59
59
|
if options is None:
|
|
60
60
|
options = {}
|
|
61
|
-
|
|
62
|
-
if '
|
|
63
|
-
options['
|
|
64
|
-
|
|
61
|
+
|
|
62
|
+
if 'f_html' not in options:
|
|
63
|
+
options['f_html'] = -1
|
|
64
|
+
|
|
65
65
|
if 'pageTitle' not in options or options['pageTitle'] is None:
|
|
66
66
|
options['pageTitle'] = ''
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
if 'headerHtml' not in options or options['headerHtml'] is None:
|
|
69
69
|
options['headerHtml'] = ''
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
if 'subPageHeaderHtml' not in options or options['subPageHeaderHtml'] is None:
|
|
72
72
|
options['subPageHeaderHtml'] = ''
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
if 'trailerHtml' not in options or options['trailerHtml'] is None:
|
|
75
75
|
options['trailerHtml'] = ''
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
if 'defaultTextStyle' not in options or options['defaultTextStyle'] is None:
|
|
78
78
|
options['defaultTextStyle'] = \
|
|
79
79
|
"font-family:calibri,verdana,arial;font-weight:bold;font-size:150%;text-align:left;margin:0px;"
|
|
@@ -81,160 +81,160 @@ def write_html_image_list(filename=None,images=None,options=None):
|
|
|
81
81
|
if 'defaultImageStyle' not in options or options['defaultImageStyle'] is None:
|
|
82
82
|
options['defaultImageStyle'] = \
|
|
83
83
|
"margin:0px;margin-top:5px;margin-bottom:5px;"
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
if 'urlEncodeFilenames' not in options or options['urlEncodeFilenames'] is None:
|
|
86
86
|
options['urlEncodeFilenames'] = True
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
if 'urlEncodeLinkTargets' not in options or options['urlEncodeLinkTargets'] is None:
|
|
89
89
|
options['urlEncodeLinkTargets'] = True
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
# Possibly split the html output for figures into multiple files; Chrome gets sad with
|
|
92
|
-
# thousands of images in a single tab.
|
|
92
|
+
# thousands of images in a single tab.
|
|
93
93
|
if 'maxFiguresPerHtmlFile' not in options or options['maxFiguresPerHtmlFile'] is None:
|
|
94
|
-
options['maxFiguresPerHtmlFile'] = math.inf
|
|
95
|
-
|
|
94
|
+
options['maxFiguresPerHtmlFile'] = math.inf
|
|
95
|
+
|
|
96
96
|
if filename is None or images is None:
|
|
97
97
|
return options
|
|
98
|
-
|
|
99
|
-
# images may be a list of images or a list of image/style/title dictionaries,
|
|
98
|
+
|
|
99
|
+
# images may be a list of images or a list of image/style/title dictionaries,
|
|
100
100
|
# enforce that it's the latter to simplify downstream code
|
|
101
|
-
for
|
|
102
|
-
if isinstance(
|
|
103
|
-
|
|
104
|
-
if 'filename' not in
|
|
105
|
-
|
|
106
|
-
if 'imageStyle' not in
|
|
107
|
-
|
|
108
|
-
if 'title' not in
|
|
109
|
-
|
|
110
|
-
if 'linkTarget' not in
|
|
111
|
-
|
|
112
|
-
if 'textStyle' not in
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
images[
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
101
|
+
for i_image,image_info in enumerate(images):
|
|
102
|
+
if isinstance(image_info,str):
|
|
103
|
+
image_info = {'filename':image_info}
|
|
104
|
+
if 'filename' not in image_info:
|
|
105
|
+
image_info['filename'] = ''
|
|
106
|
+
if 'imageStyle' not in image_info:
|
|
107
|
+
image_info['imageStyle'] = options['defaultImageStyle']
|
|
108
|
+
if 'title' not in image_info:
|
|
109
|
+
image_info['title'] = ''
|
|
110
|
+
if 'linkTarget' not in image_info:
|
|
111
|
+
image_info['linkTarget'] = ''
|
|
112
|
+
if 'textStyle' not in image_info:
|
|
113
|
+
text_style = options['defaultTextStyle']
|
|
114
|
+
image_info['textStyle'] = options['defaultTextStyle']
|
|
115
|
+
images[i_image] = image_info
|
|
116
|
+
|
|
117
|
+
n_images = len(images)
|
|
118
|
+
|
|
119
119
|
# If we need to break this up into multiple files...
|
|
120
|
-
if
|
|
121
|
-
|
|
120
|
+
if n_images > options['maxFiguresPerHtmlFile']:
|
|
121
|
+
|
|
122
122
|
# You can't supply your own file handle in this case
|
|
123
|
-
if options['
|
|
123
|
+
if options['f_html'] != -1:
|
|
124
124
|
raise ValueError(
|
|
125
125
|
"You can't supply your own file handle if we have to page the image set")
|
|
126
|
-
|
|
127
|
-
figureFileStartingIndices = list(range(0,nImages,options['maxFiguresPerHtmlFile']))
|
|
128
126
|
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
figure_file_starting_indices = list(range(0,n_images,options['maxFiguresPerHtmlFile']))
|
|
128
|
+
|
|
129
|
+
assert len(figure_file_starting_indices) > 1
|
|
130
|
+
|
|
131
131
|
# Open the meta-output file
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
f_meta = open(filename,'w')
|
|
133
|
+
|
|
134
134
|
# Write header stuff
|
|
135
|
-
|
|
135
|
+
title_string = '<title>Index page</title>'
|
|
136
136
|
if len(options['pageTitle']) > 0:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
for
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
trailer = 'image_{:05d}_{:05d}'.format(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
os.path.basename(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
137
|
+
title_string = '<title>Index page for: {}</title>'.format(options['pageTitle'])
|
|
138
|
+
f_meta.write('<html><head>{}</head><body>\n'.format(title_string))
|
|
139
|
+
f_meta.write(options['headerHtml'])
|
|
140
|
+
f_meta.write('<table border = 0 cellpadding = 2>\n')
|
|
141
|
+
|
|
142
|
+
for starting_index in figure_file_starting_indices:
|
|
143
|
+
|
|
144
|
+
i_start = starting_index
|
|
145
|
+
i_end = starting_index + options['maxFiguresPerHtmlFile'] - 1
|
|
146
|
+
if i_end >= n_images:
|
|
147
|
+
i_end = n_images-1
|
|
148
|
+
|
|
149
|
+
trailer = 'image_{:05d}_{:05d}'.format(i_start,i_end)
|
|
150
|
+
local_figures_html_filename = path_utils.insert_before_extension(filename,trailer)
|
|
151
|
+
f_meta.write('<tr><td>\n')
|
|
152
|
+
f_meta.write('<p style="padding-bottom:0px;margin-bottom:0px;text-align:left;font-family:''segoe ui'',calibri,arial;font-size:100%;text-decoration:none;font-weight:bold;">') # noqa
|
|
153
|
+
f_meta.write('<a href="{}">Figures for images {} through {}</a></p></td></tr>\n'.format(
|
|
154
|
+
os.path.basename(local_figures_html_filename),i_start,i_end))
|
|
155
|
+
|
|
156
|
+
local_images = images[i_start:i_end+1]
|
|
157
|
+
|
|
158
|
+
local_options = options.copy()
|
|
159
|
+
local_options['headerHtml'] = options['subPageHeaderHtml']
|
|
160
|
+
local_options['trailerHtml'] = ''
|
|
161
|
+
|
|
162
162
|
# Make a recursive call for this image set
|
|
163
|
-
write_html_image_list(
|
|
164
|
-
|
|
163
|
+
write_html_image_list(local_figures_html_filename,local_images,local_options)
|
|
164
|
+
|
|
165
165
|
# ...for each page of images
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
166
|
+
|
|
167
|
+
f_meta.write('</table></body>\n')
|
|
168
|
+
f_meta.write(options['trailerHtml'])
|
|
169
|
+
f_meta.write('</html>\n')
|
|
170
|
+
f_meta.close()
|
|
171
|
+
|
|
172
172
|
return options
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
# ...if we have to make multiple sub-pages
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if options['
|
|
179
|
-
|
|
180
|
-
|
|
175
|
+
|
|
176
|
+
b_clean_up_file = False
|
|
177
|
+
|
|
178
|
+
if options['f_html'] == -1:
|
|
179
|
+
b_clean_up_file = True
|
|
180
|
+
f_html = open(filename,'w')
|
|
181
181
|
else:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
f_html = options['f_html']
|
|
183
|
+
|
|
184
|
+
title_string = ''
|
|
185
185
|
if len(options['pageTitle']) > 0:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
186
|
+
title_string = '<title>{}</title>'.format(options['pageTitle'])
|
|
187
|
+
|
|
188
|
+
f_html.write('<html>{}<body>\n'.format(title_string))
|
|
189
|
+
|
|
190
|
+
f_html.write(options['headerHtml'])
|
|
191
|
+
|
|
192
192
|
# Write out images
|
|
193
|
-
for
|
|
194
|
-
|
|
193
|
+
for i_image,image in enumerate(images):
|
|
194
|
+
|
|
195
195
|
title = image['title']
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
image_style = image['imageStyle']
|
|
197
|
+
text_style = image['textStyle']
|
|
198
198
|
filename = image['filename']
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
link_target = image['linkTarget']
|
|
200
|
+
|
|
201
201
|
# Remove unicode characters
|
|
202
202
|
title = title.encode('ascii','ignore').decode('ascii')
|
|
203
203
|
filename = filename.encode('ascii','ignore').decode('ascii')
|
|
204
|
-
|
|
204
|
+
|
|
205
205
|
filename = filename.replace('\\','/')
|
|
206
|
-
if options['urlEncodeFilenames']:
|
|
206
|
+
if options['urlEncodeFilenames']:
|
|
207
207
|
filename = urllib.parse.quote(filename)
|
|
208
|
-
|
|
209
|
-
if len(title) > 0:
|
|
210
|
-
|
|
208
|
+
|
|
209
|
+
if len(title) > 0:
|
|
210
|
+
f_html.write(
|
|
211
211
|
'<p style="{}">{}</p>\n'\
|
|
212
|
-
.format(
|
|
212
|
+
.format(text_style,title))
|
|
213
213
|
|
|
214
|
-
|
|
214
|
+
link_target = link_target.replace('\\','/')
|
|
215
215
|
if options['urlEncodeLinkTargets']:
|
|
216
216
|
# These are typically absolute paths, so we only want to mess with certain characters
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if len(
|
|
220
|
-
|
|
221
|
-
#
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if len(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if
|
|
229
|
-
|
|
230
|
-
|
|
217
|
+
link_target = urllib.parse.quote(link_target,safe=':/')
|
|
218
|
+
|
|
219
|
+
if len(link_target) > 0:
|
|
220
|
+
f_html.write('<a href="{}">'.format(link_target))
|
|
221
|
+
# image_style.append(';border:0px;')
|
|
222
|
+
|
|
223
|
+
f_html.write('<img src="{}" style="{}">\n'.format(filename,image_style))
|
|
224
|
+
|
|
225
|
+
if len(link_target) > 0:
|
|
226
|
+
f_html.write('</a>')
|
|
227
|
+
|
|
228
|
+
if i_image != len(images)-1:
|
|
229
|
+
f_html.write('<br/>')
|
|
230
|
+
|
|
231
231
|
# ...for each image we need to write
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if
|
|
238
|
-
|
|
232
|
+
|
|
233
|
+
f_html.write(options['trailerHtml'])
|
|
234
|
+
|
|
235
|
+
f_html.write('</body></html>\n')
|
|
236
|
+
|
|
237
|
+
if b_clean_up_file:
|
|
238
|
+
f_html.close()
|
|
239
239
|
|
|
240
240
|
# ...function
|
|
@@ -34,22 +34,22 @@ def plot_confusion_matrix(matrix,
|
|
|
34
34
|
matrix (np.ndarray): shape [num_classes, num_classes], confusion matrix
|
|
35
35
|
where rows are ground-truth classes and columns are predicted classes
|
|
36
36
|
classes (list of str): class names for each row/column
|
|
37
|
-
normalize (bool, optional): whether to perform row-wise normalization;
|
|
37
|
+
normalize (bool, optional): whether to perform row-wise normalization;
|
|
38
38
|
by default, assumes values in the confusion matrix are percentages
|
|
39
39
|
title (str, optional): figure title
|
|
40
|
-
cmap (matplotlib.colors.colormap): colormap for cell backgrounds
|
|
41
|
-
vmax (float, optional)
|
|
40
|
+
cmap (matplotlib.colors.colormap, optional): colormap for cell backgrounds
|
|
41
|
+
vmax (float, optional): value corresponding to the largest value of the colormap;
|
|
42
42
|
if None, the maximum value in [matrix] will be used
|
|
43
43
|
use_colorbar (bool, optional): whether to show colorbar
|
|
44
44
|
y_label (bool, optional): whether to show class names on the y axis
|
|
45
|
-
fmt (str): format string for rendering numeric values
|
|
46
|
-
fig (Figure): existing figure to which we should render, otherwise
|
|
47
|
-
a new figure
|
|
48
|
-
|
|
49
|
-
Returns:
|
|
45
|
+
fmt (str, optional): format string for rendering numeric values
|
|
46
|
+
fig (Figure, optional): existing figure to which we should render, otherwise
|
|
47
|
+
creates a new figure
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
50
|
matplotlib.figure.Figure: the figure we rendered to or created
|
|
51
51
|
"""
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
num_classes = matrix.shape[0]
|
|
54
54
|
assert matrix.shape[1] == num_classes
|
|
55
55
|
assert len(classes) == num_classes
|
|
@@ -86,7 +86,7 @@ def plot_confusion_matrix(matrix,
|
|
|
86
86
|
ax.set_ylabel('Ground-truth class')
|
|
87
87
|
|
|
88
88
|
for i, j in np.ndindex(matrix.shape):
|
|
89
|
-
v = matrix[i, j]
|
|
89
|
+
v = matrix[i, j]
|
|
90
90
|
ax.text(j, i, fmt.format(v),
|
|
91
91
|
horizontalalignment='center',
|
|
92
92
|
verticalalignment='center',
|
|
@@ -97,8 +97,8 @@ def plot_confusion_matrix(matrix,
|
|
|
97
97
|
# ...def plot_confusion_matrix(...)
|
|
98
98
|
|
|
99
99
|
|
|
100
|
-
def plot_precision_recall_curve(precisions,
|
|
101
|
-
recalls,
|
|
100
|
+
def plot_precision_recall_curve(precisions,
|
|
101
|
+
recalls,
|
|
102
102
|
title='Precision/recall curve',
|
|
103
103
|
xlim=(0.0,1.05),
|
|
104
104
|
ylim=(0.0,1.05)):
|
|
@@ -115,10 +115,10 @@ def plot_precision_recall_curve(precisions,
|
|
|
115
115
|
xlim (tuple, optional): x-axis limits as a length-2 tuple
|
|
116
116
|
ylim (tuple, optional): y-axis limits as a length-2 tuple
|
|
117
117
|
|
|
118
|
-
Returns:
|
|
118
|
+
Returns:
|
|
119
119
|
matplotlib.figure.Figure: the (new) figure
|
|
120
120
|
"""
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
assert len(precisions) == len(recalls)
|
|
123
123
|
|
|
124
124
|
fig = matplotlib.figure.Figure(tight_layout=True)
|
|
@@ -128,23 +128,27 @@ def plot_precision_recall_curve(precisions,
|
|
|
128
128
|
|
|
129
129
|
try:
|
|
130
130
|
ax.set(x_label='Recall', y_label='Precision', title=title)
|
|
131
|
-
ax.set(x_lim=xlim, y_lim=ylim)
|
|
132
|
-
#
|
|
131
|
+
ax.set(x_lim=xlim, y_lim=ylim)
|
|
132
|
+
#
|
|
133
133
|
except Exception:
|
|
134
134
|
ax.set_xlabel('Recall')
|
|
135
135
|
ax.set_ylabel('Precision')
|
|
136
136
|
ax.set_title(title)
|
|
137
137
|
ax.set_xlim(xlim[0],xlim[1])
|
|
138
138
|
ax.set_ylim(ylim[0],ylim[1])
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
return fig
|
|
141
141
|
|
|
142
142
|
|
|
143
|
-
def plot_stacked_bar_chart(data,
|
|
144
|
-
|
|
143
|
+
def plot_stacked_bar_chart(data,
|
|
144
|
+
series_labels=None,
|
|
145
|
+
col_labels=None,
|
|
146
|
+
x_label=None,
|
|
147
|
+
y_label=None,
|
|
148
|
+
log_scale=False):
|
|
145
149
|
"""
|
|
146
150
|
Plot a stacked bar chart, for plotting e.g. species distribution across locations.
|
|
147
|
-
|
|
151
|
+
|
|
148
152
|
Reference: https://stackoverflow.com/q/44309507
|
|
149
153
|
|
|
150
154
|
Args:
|
|
@@ -154,12 +158,12 @@ def plot_stacked_bar_chart(data, series_labels=None, col_labels=None,
|
|
|
154
158
|
col_labels (list of str, optional): column labels, typically location names
|
|
155
159
|
x_label (str, optional): x-axis label
|
|
156
160
|
y_label (str, optional): y-axis label
|
|
157
|
-
log_scale (bool, optional) whether to plot the y axis in log-scale
|
|
161
|
+
log_scale (bool, optional): whether to plot the y axis in log-scale
|
|
158
162
|
|
|
159
|
-
Returns:
|
|
163
|
+
Returns:
|
|
160
164
|
matplotlib.figure.Figure: the (new) figure
|
|
161
165
|
"""
|
|
162
|
-
|
|
166
|
+
|
|
163
167
|
data = np.asarray(data)
|
|
164
168
|
num_series, num_columns = data.shape
|
|
165
169
|
ind = np.arange(num_columns)
|
|
@@ -206,24 +210,24 @@ def calibration_ece(true_scores, pred_scores, num_bins):
|
|
|
206
210
|
|
|
207
211
|
Implementation modified from sklearn.calibration.calibration_curve()
|
|
208
212
|
in order to implement ECE calculation. See:
|
|
209
|
-
|
|
213
|
+
|
|
210
214
|
https://github.com/scikit-learn/scikit-learn/issues/18268
|
|
211
215
|
|
|
212
216
|
Args:
|
|
213
217
|
true_scores (list of int): true values, length N, binary-valued (0 = neg, 1 = pos)
|
|
214
|
-
pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
|
|
218
|
+
pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
|
|
215
219
|
predicted confidence that example i is positive
|
|
216
220
|
num_bins (int): number of bins to use (`M` in eq. (3) of Guo 2017)
|
|
217
221
|
|
|
218
222
|
Returns:
|
|
219
223
|
tuple: a length-three tuple containing:
|
|
220
224
|
- accs: np.ndarray, shape [M], type float64, accuracy in each bin,
|
|
221
|
-
M <= num_bins because bins with no samples are not returned
|
|
225
|
+
M <= num_bins because bins with no samples are not returned
|
|
222
226
|
- confs: np.ndarray, shape [M], type float64, mean model confidence in
|
|
223
227
|
each bin
|
|
224
228
|
- ece: float, expected calibration error
|
|
225
229
|
"""
|
|
226
|
-
|
|
230
|
+
|
|
227
231
|
assert len(true_scores) == len(pred_scores)
|
|
228
232
|
|
|
229
233
|
bins = np.linspace(0., 1. + 1e-8, num=num_bins + 1)
|
|
@@ -250,19 +254,19 @@ def plot_calibration_curve(true_scores, pred_scores, num_bins,
|
|
|
250
254
|
|
|
251
255
|
Args:
|
|
252
256
|
true_scores (list of int): true values, length N, binary-valued (0 = neg, 1 = pos)
|
|
253
|
-
pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
|
|
257
|
+
pred_scores (list of float): predicted confidence values, length N, pred_scores[i] is the
|
|
254
258
|
predicted confidence that example i is positive
|
|
255
259
|
num_bins (int): number of bins to use (`M` in eq. (3) of Guo 2017)
|
|
256
260
|
name (str, optional): label in legend for the calibration curve
|
|
257
261
|
plot_perf (bool, optional): whether to plot y=x line indicating perfect calibration
|
|
258
262
|
plot_hist (bool, optional): whether to plot histogram of counts
|
|
259
263
|
ax (Axes, optional): if given then no legend is drawn, and fig_kwargs are ignored
|
|
260
|
-
fig_kwargs (dict
|
|
264
|
+
fig_kwargs (dict): only used if [ax] is None
|
|
261
265
|
|
|
262
266
|
Returns:
|
|
263
267
|
matplotlib.figure.Figure: the (new) figure
|
|
264
268
|
"""
|
|
265
|
-
|
|
269
|
+
|
|
266
270
|
accs, confs, ece = calibration_ece(true_scores, pred_scores, num_bins)
|
|
267
271
|
|
|
268
272
|
created_fig = False
|