megadetector 5.0.6__py3-none-any.whl → 5.0.8__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.
- api/batch_processing/data_preparation/manage_local_batch.py +297 -202
- api/batch_processing/data_preparation/manage_video_batch.py +7 -2
- api/batch_processing/postprocessing/add_max_conf.py +1 -0
- api/batch_processing/postprocessing/combine_api_outputs.py +2 -2
- api/batch_processing/postprocessing/compare_batch_results.py +111 -61
- api/batch_processing/postprocessing/convert_output_format.py +24 -6
- api/batch_processing/postprocessing/load_api_results.py +56 -72
- api/batch_processing/postprocessing/md_to_labelme.py +119 -51
- api/batch_processing/postprocessing/merge_detections.py +30 -5
- api/batch_processing/postprocessing/postprocess_batch_results.py +175 -55
- api/batch_processing/postprocessing/remap_detection_categories.py +163 -0
- api/batch_processing/postprocessing/render_detection_confusion_matrix.py +628 -0
- api/batch_processing/postprocessing/repeat_detection_elimination/find_repeat_detections.py +71 -23
- api/batch_processing/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +1 -1
- api/batch_processing/postprocessing/repeat_detection_elimination/repeat_detections_core.py +224 -76
- api/batch_processing/postprocessing/subset_json_detector_output.py +132 -5
- api/batch_processing/postprocessing/top_folders_to_bottom.py +1 -1
- classification/prepare_classification_script.py +191 -191
- data_management/cct_json_utils.py +7 -2
- data_management/coco_to_labelme.py +263 -0
- data_management/coco_to_yolo.py +72 -48
- data_management/databases/integrity_check_json_db.py +75 -64
- data_management/databases/subset_json_db.py +1 -1
- data_management/generate_crops_from_cct.py +1 -1
- data_management/get_image_sizes.py +44 -26
- data_management/importers/animl_results_to_md_results.py +3 -5
- data_management/importers/noaa_seals_2019.py +2 -2
- data_management/importers/zamba_results_to_md_results.py +2 -2
- data_management/labelme_to_coco.py +264 -127
- data_management/labelme_to_yolo.py +96 -53
- data_management/lila/create_lila_blank_set.py +557 -0
- data_management/lila/create_lila_test_set.py +2 -1
- data_management/lila/create_links_to_md_results_files.py +1 -1
- data_management/lila/download_lila_subset.py +138 -45
- data_management/lila/generate_lila_per_image_labels.py +23 -14
- data_management/lila/get_lila_annotation_counts.py +16 -10
- data_management/lila/lila_common.py +15 -42
- data_management/lila/test_lila_metadata_urls.py +116 -0
- data_management/read_exif.py +65 -16
- data_management/remap_coco_categories.py +84 -0
- data_management/resize_coco_dataset.py +14 -31
- data_management/wi_download_csv_to_coco.py +239 -0
- data_management/yolo_output_to_md_output.py +40 -13
- data_management/yolo_to_coco.py +313 -100
- detection/process_video.py +36 -14
- detection/pytorch_detector.py +1 -1
- detection/run_detector.py +73 -18
- detection/run_detector_batch.py +116 -27
- detection/run_inference_with_yolov5_val.py +135 -27
- detection/run_tiled_inference.py +153 -43
- detection/tf_detector.py +2 -1
- detection/video_utils.py +4 -2
- md_utils/ct_utils.py +101 -6
- md_utils/md_tests.py +264 -17
- md_utils/path_utils.py +326 -47
- md_utils/process_utils.py +26 -7
- md_utils/split_locations_into_train_val.py +215 -0
- md_utils/string_utils.py +10 -0
- md_utils/url_utils.py +66 -3
- md_utils/write_html_image_list.py +12 -2
- md_visualization/visualization_utils.py +380 -74
- md_visualization/visualize_db.py +41 -10
- md_visualization/visualize_detector_output.py +185 -104
- {megadetector-5.0.6.dist-info → megadetector-5.0.8.dist-info}/METADATA +11 -13
- {megadetector-5.0.6.dist-info → megadetector-5.0.8.dist-info}/RECORD +74 -67
- {megadetector-5.0.6.dist-info → megadetector-5.0.8.dist-info}/WHEEL +1 -1
- taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +1 -1
- taxonomy_mapping/map_new_lila_datasets.py +43 -39
- taxonomy_mapping/prepare_lila_taxonomy_release.py +5 -2
- taxonomy_mapping/preview_lila_taxonomy.py +27 -27
- taxonomy_mapping/species_lookup.py +33 -13
- taxonomy_mapping/taxonomy_csv_checker.py +7 -5
- md_visualization/visualize_megadb.py +0 -183
- {megadetector-5.0.6.dist-info → megadetector-5.0.8.dist-info}/LICENSE +0 -0
- {megadetector-5.0.6.dist-info → megadetector-5.0.8.dist-info}/top_level.txt +0 -0
md_utils/md_tests.py
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
########
|
|
2
2
|
#
|
|
3
|
-
#
|
|
3
|
+
# md_tests.py
|
|
4
4
|
#
|
|
5
5
|
# A series of tests to validate basic repo functionality and verify either "correct"
|
|
6
6
|
# inference behavior, or - when operating in environments other than the training
|
|
7
7
|
# environment - acceptable deviation from the correct results.
|
|
8
8
|
#
|
|
9
|
-
# This module should not depend on anything else in this repo outside of the
|
|
10
|
-
# tests themselves, even if it means some duplicated code (e.g. for downloading files),
|
|
11
|
-
# much of what it tries to test is, e.g., imports.
|
|
9
|
+
# This module should not depend on anything else in this repo outside of the
|
|
10
|
+
# tests themselves, even if it means some duplicated code (e.g. for downloading files),
|
|
11
|
+
# since much of what it tries to test is, e.g., imports.
|
|
12
12
|
#
|
|
13
13
|
########
|
|
14
14
|
|
|
15
|
-
#%% TODO
|
|
16
|
-
|
|
17
|
-
# Video tests
|
|
18
|
-
# Augmented inference tests
|
|
19
|
-
# Checkpoint tests
|
|
20
|
-
|
|
21
|
-
|
|
22
15
|
#%% Imports and constants
|
|
23
16
|
|
|
24
17
|
### Only standard imports belong here, not MD-specific imports ###
|
|
@@ -54,6 +47,7 @@ class MDTestOptions:
|
|
|
54
47
|
max_coord_error = 0.001
|
|
55
48
|
max_conf_error = 0.005
|
|
56
49
|
cli_working_dir = None
|
|
50
|
+
yolo_working_folder = None
|
|
57
51
|
|
|
58
52
|
|
|
59
53
|
#%% Support functions
|
|
@@ -92,11 +86,14 @@ def get_expected_results_filename(gpu_is_available):
|
|
|
92
86
|
return 'md-test-results-{}-{}.json'.format(hw_string,pt_string)
|
|
93
87
|
|
|
94
88
|
|
|
95
|
-
def download_test_data(options):
|
|
89
|
+
def download_test_data(options=None):
|
|
96
90
|
"""
|
|
97
91
|
Download the test zipfile if necessary, unzip if necessary.
|
|
98
92
|
"""
|
|
99
|
-
|
|
93
|
+
|
|
94
|
+
if options is None:
|
|
95
|
+
options = MDTestOptions()
|
|
96
|
+
|
|
100
97
|
if options.scratch_dir is None:
|
|
101
98
|
tempdir_base = tempfile.gettempdir()
|
|
102
99
|
scratch_dir = os.path.join(tempdir_base,'md-tests')
|
|
@@ -119,9 +116,9 @@ def download_test_data(options):
|
|
|
119
116
|
if download_zipfile:
|
|
120
117
|
print('Downloading test data zipfile')
|
|
121
118
|
urllib.request.urlretrieve(options.test_data_url, local_zipfile)
|
|
122
|
-
print('Finished download')
|
|
119
|
+
print('Finished download to {}'.format(local_zipfile))
|
|
123
120
|
else:
|
|
124
|
-
print('Bypassing test data zipfile download')
|
|
121
|
+
print('Bypassing test data zipfile download for {}'.format(local_zipfile))
|
|
125
122
|
|
|
126
123
|
|
|
127
124
|
## Unzip data
|
|
@@ -164,7 +161,10 @@ def download_test_data(options):
|
|
|
164
161
|
options.all_test_files = test_files
|
|
165
162
|
options.test_images = [fn for fn in test_files if os.path.splitext(fn.lower())[1] in ('.jpg','.jpeg','.png')]
|
|
166
163
|
options.test_videos = [fn for fn in test_files if os.path.splitext(fn.lower())[1] in ('.mp4','.avi')]
|
|
164
|
+
options.test_videos = [fn for fn in options.test_videos if 'rendered' not in fn]
|
|
167
165
|
|
|
166
|
+
print('Finished unzipping and enumerating test data')
|
|
167
|
+
|
|
168
168
|
# ...def download_test_data(...)
|
|
169
169
|
|
|
170
170
|
|
|
@@ -247,6 +247,8 @@ def execute_and_print(cmd,print_output=True):
|
|
|
247
247
|
|
|
248
248
|
def run_python_tests(options):
|
|
249
249
|
|
|
250
|
+
print('\n*** Starting module tests ***\n')
|
|
251
|
+
|
|
250
252
|
## Prepare data
|
|
251
253
|
|
|
252
254
|
download_test_data(options)
|
|
@@ -393,7 +395,84 @@ def run_python_tests(options):
|
|
|
393
395
|
assert os.path.isfile(rde_results.filterFile),\
|
|
394
396
|
'Could not find RDE output file {}'.format(rde_results.filterFile)
|
|
395
397
|
|
|
396
|
-
|
|
398
|
+
|
|
399
|
+
# TODO: add remove_repeat_detections test here
|
|
400
|
+
#
|
|
401
|
+
# It's already tested in the CLI tests, so this is not urgent.
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
## Video test (single video)
|
|
405
|
+
|
|
406
|
+
from detection.process_video import ProcessVideoOptions, process_video
|
|
407
|
+
|
|
408
|
+
video_options = ProcessVideoOptions()
|
|
409
|
+
video_options.model_file = 'MDV5A'
|
|
410
|
+
video_options.input_video_file = os.path.join(options.scratch_dir,options.test_videos[0])
|
|
411
|
+
video_options.output_json_file = os.path.join(options.scratch_dir,'single_video_output.json')
|
|
412
|
+
video_options.output_video_file = os.path.join(options.scratch_dir,'video_scratch/rendered_video.mp4')
|
|
413
|
+
video_options.frame_folder = os.path.join(options.scratch_dir,'video_scratch/frame_folder')
|
|
414
|
+
video_options.frame_rendering_folder = os.path.join(options.scratch_dir,'video_scratch/rendered_frame_folder')
|
|
415
|
+
video_options.render_output_video = True
|
|
416
|
+
# video_options.keep_rendered_frames = False
|
|
417
|
+
# video_options.keep_rendered_frames = False
|
|
418
|
+
video_options.force_extracted_frame_folder_deletion = True
|
|
419
|
+
video_options.force_rendered_frame_folder_deletion = True
|
|
420
|
+
# video_options.reuse_results_if_available = False
|
|
421
|
+
# video_options.reuse_frames_if_available = False
|
|
422
|
+
video_options.recursive = True
|
|
423
|
+
video_options.verbose = False
|
|
424
|
+
video_options.fourcc = 'mp4v'
|
|
425
|
+
# video_options.rendering_confidence_threshold = None
|
|
426
|
+
# video_options.json_confidence_threshold = 0.005
|
|
427
|
+
video_options.frame_sample = 5
|
|
428
|
+
video_options.n_cores = 5
|
|
429
|
+
# video_options.debug_max_frames = -1
|
|
430
|
+
# video_options.class_mapping_filename = None
|
|
431
|
+
|
|
432
|
+
_ = process_video(video_options)
|
|
433
|
+
|
|
434
|
+
assert os.path.isfile(video_options.output_video_file), \
|
|
435
|
+
'Python video test failed to render output video file'
|
|
436
|
+
assert os.path.isfile(video_options.output_json_file), \
|
|
437
|
+
'Python video test failed to render output .json file'
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
## Video test (folder)
|
|
441
|
+
|
|
442
|
+
from detection.process_video import ProcessVideoOptions, process_video_folder
|
|
443
|
+
|
|
444
|
+
video_options = ProcessVideoOptions()
|
|
445
|
+
video_options.model_file = 'MDV5A'
|
|
446
|
+
video_options.input_video_file = os.path.join(options.scratch_dir,
|
|
447
|
+
os.path.dirname(options.test_videos[0]))
|
|
448
|
+
video_options.output_json_file = os.path.join(options.scratch_dir,'video_folder_output.json')
|
|
449
|
+
# video_options.output_video_file = None
|
|
450
|
+
video_options.frame_folder = os.path.join(options.scratch_dir,'video_scratch/frame_folder')
|
|
451
|
+
video_options.frame_rendering_folder = os.path.join(options.scratch_dir,'video_scratch/rendered_frame_folder')
|
|
452
|
+
video_options.render_output_video = False
|
|
453
|
+
# video_options.keep_rendered_frames = False
|
|
454
|
+
# video_options.keep_rendered_frames = False
|
|
455
|
+
video_options.force_extracted_frame_folder_deletion = True
|
|
456
|
+
video_options.force_rendered_frame_folder_deletion = True
|
|
457
|
+
# video_options.reuse_results_if_available = False
|
|
458
|
+
# video_options.reuse_frames_if_available = False
|
|
459
|
+
video_options.recursive = True
|
|
460
|
+
video_options.verbose = False
|
|
461
|
+
# video_options.fourcc = None
|
|
462
|
+
# video_options.rendering_confidence_threshold = None
|
|
463
|
+
# video_options.json_confidence_threshold = 0.005
|
|
464
|
+
video_options.frame_sample = 5
|
|
465
|
+
video_options.n_cores = 5
|
|
466
|
+
# video_options.debug_max_frames = -1
|
|
467
|
+
# video_options.class_mapping_filename = None
|
|
468
|
+
|
|
469
|
+
_ = process_video_folder(video_options)
|
|
470
|
+
|
|
471
|
+
assert os.path.isfile(video_options.output_json_file), \
|
|
472
|
+
'Python video test failed to render output .json file'
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
print('\n*** Finished module tests ***\n')
|
|
397
476
|
|
|
398
477
|
# ...def run_python_tests(...)
|
|
399
478
|
|
|
@@ -402,6 +481,8 @@ def run_python_tests(options):
|
|
|
402
481
|
|
|
403
482
|
def run_cli_tests(options):
|
|
404
483
|
|
|
484
|
+
print('\n*** Starting CLI tests ***\n')
|
|
485
|
+
|
|
405
486
|
## chdir if necessary
|
|
406
487
|
|
|
407
488
|
if options.cli_working_dir is not None:
|
|
@@ -473,6 +554,158 @@ def run_cli_tests(options):
|
|
|
473
554
|
print('Running: {}'.format(cmd))
|
|
474
555
|
cmd_results = execute_and_print(cmd)
|
|
475
556
|
|
|
557
|
+
|
|
558
|
+
## RDE
|
|
559
|
+
|
|
560
|
+
rde_output_dir = os.path.join(options.scratch_dir,'rde_output_cli')
|
|
561
|
+
|
|
562
|
+
if options.cli_working_dir is None:
|
|
563
|
+
cmd = 'python -m api.batch_processing.postprocessing.repeat_detection_elimination.find_repeat_detections'
|
|
564
|
+
else:
|
|
565
|
+
cmd = 'python api/batch_processing/postprocessing/repeat_detection_elimination/find_repeat_detections.py'
|
|
566
|
+
cmd += ' {}'.format(inference_output_file)
|
|
567
|
+
cmd += ' --imageBase {}'.format(image_folder)
|
|
568
|
+
cmd += ' --outputBase {}'.format(rde_output_dir)
|
|
569
|
+
cmd += ' --occurrenceThreshold 1' # Use an absurd number here to make sure we get some suspicious detections
|
|
570
|
+
print('Running: {}'.format(cmd))
|
|
571
|
+
cmd_results = execute_and_print(cmd)
|
|
572
|
+
|
|
573
|
+
# Find the latest filtering folder
|
|
574
|
+
filtering_output_dir = os.listdir(rde_output_dir)
|
|
575
|
+
filtering_output_dir = [fn for fn in filtering_output_dir if fn.startswith('filtering_')]
|
|
576
|
+
filtering_output_dir = [os.path.join(rde_output_dir,fn) for fn in filtering_output_dir]
|
|
577
|
+
filtering_output_dir = [fn for fn in filtering_output_dir if os.path.isdir(fn)]
|
|
578
|
+
filtering_output_dir = sorted(filtering_output_dir)[-1]
|
|
579
|
+
|
|
580
|
+
print('Using RDE filtering folder {}'.format(filtering_output_dir))
|
|
581
|
+
|
|
582
|
+
filtered_output_file = inference_output_file.replace('.json','_filtered.json')
|
|
583
|
+
|
|
584
|
+
if options.cli_working_dir is None:
|
|
585
|
+
cmd = 'python -m api.batch_processing.postprocessing.repeat_detection_elimination.remove_repeat_detections'
|
|
586
|
+
else:
|
|
587
|
+
cmd = 'python api/batch_processing/postprocessing/repeat_detection_elimination/remove_repeat_detections.py'
|
|
588
|
+
cmd += ' {} {} {}'.format(inference_output_file,filtered_output_file,filtering_output_dir)
|
|
589
|
+
print('Running: {}'.format(cmd))
|
|
590
|
+
cmd_results = execute_and_print(cmd)
|
|
591
|
+
|
|
592
|
+
assert os.path.isfile(filtered_output_file), \
|
|
593
|
+
'Could not find RDE output file {}'.format(filtered_output_file)
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
## Run inference on a folder (tiled)
|
|
597
|
+
|
|
598
|
+
image_folder = os.path.join(options.scratch_dir,'md-test-images')
|
|
599
|
+
tiling_folder = os.path.join(options.scratch_dir,'tiling-folder')
|
|
600
|
+
inference_output_file_tiled = os.path.join(options.scratch_dir,'folder_inference_output_tiled.json')
|
|
601
|
+
if options.cli_working_dir is None:
|
|
602
|
+
cmd = 'python -m detection.run_tiled_inference'
|
|
603
|
+
else:
|
|
604
|
+
cmd = 'python detection/run_tiled_inference.py'
|
|
605
|
+
cmd += ' {} {} {} {}'.format(
|
|
606
|
+
model_file,image_folder,tiling_folder,inference_output_file_tiled)
|
|
607
|
+
cmd += ' --overwrite_handling overwrite'
|
|
608
|
+
print('Running: {}'.format(cmd))
|
|
609
|
+
cmd_results = execute_and_print(cmd)
|
|
610
|
+
|
|
611
|
+
with open(inference_output_file_tiled,'r') as f:
|
|
612
|
+
results_from_file = json.load(f) # noqa
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
## Run inference on a folder (augmented)
|
|
616
|
+
|
|
617
|
+
if options.yolo_working_folder is None:
|
|
618
|
+
|
|
619
|
+
print('Bypassing YOLOv5 val tests, no yolo folder supplied')
|
|
620
|
+
|
|
621
|
+
else:
|
|
622
|
+
|
|
623
|
+
image_folder = os.path.join(options.scratch_dir,'md-test-images')
|
|
624
|
+
yolo_results_folder = os.path.join(options.scratch_dir,'yolo-output-folder')
|
|
625
|
+
yolo_symlink_folder = os.path.join(options.scratch_dir,'yolo-symlink_folder')
|
|
626
|
+
inference_output_file_yolo_val = os.path.join(options.scratch_dir,'folder_inference_output_yolo_val.json')
|
|
627
|
+
if options.cli_working_dir is None:
|
|
628
|
+
cmd = 'python -m detection.run_inference_with_yolov5_val'
|
|
629
|
+
else:
|
|
630
|
+
cmd = 'python detection/run_inference_with_yolov5_val.py'
|
|
631
|
+
cmd += ' {} {} {}'.format(
|
|
632
|
+
model_file,image_folder,inference_output_file_yolo_val)
|
|
633
|
+
cmd += ' --yolo_working_folder {}'.format(options.yolo_working_folder)
|
|
634
|
+
cmd += ' --yolo_results_folder {}'.format(yolo_results_folder)
|
|
635
|
+
cmd += ' --symlink_folder {}'.format(yolo_symlink_folder)
|
|
636
|
+
cmd += ' --augment_enabled 1'
|
|
637
|
+
# cmd += ' --no_use_symlinks'
|
|
638
|
+
cmd += ' --overwrite_handling overwrite'
|
|
639
|
+
print('Running: {}'.format(cmd))
|
|
640
|
+
cmd_results = execute_and_print(cmd)
|
|
641
|
+
|
|
642
|
+
with open(inference_output_file_yolo_val,'r') as f:
|
|
643
|
+
results_from_file = json.load(f) # noqa
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
## Video test
|
|
647
|
+
|
|
648
|
+
model_file = 'MDV5A'
|
|
649
|
+
video_inference_output_file = os.path.join(options.scratch_dir,'video_inference_output.json')
|
|
650
|
+
output_video_file = os.path.join(options.scratch_dir,'video_scratch/cli_rendered_video.mp4')
|
|
651
|
+
frame_folder = os.path.join(options.scratch_dir,'video_scratch/frame_folder_cli')
|
|
652
|
+
frame_rendering_folder = os.path.join(options.scratch_dir,'video_scratch/rendered_frame_folder_cli')
|
|
653
|
+
|
|
654
|
+
video_fn = os.path.join(options.scratch_dir,options.test_videos[-1])
|
|
655
|
+
output_dir = os.path.join(options.scratch_dir,'single_video_test_cli')
|
|
656
|
+
if options.cli_working_dir is None:
|
|
657
|
+
cmd = 'python -m detection.process_video'
|
|
658
|
+
else:
|
|
659
|
+
cmd = 'python detection/process_video.py'
|
|
660
|
+
cmd += ' {} {}'.format(model_file,video_fn)
|
|
661
|
+
cmd += ' --frame_folder {} --frame_rendering_folder {} --output_json_file {} --output_video_file {}'.format(
|
|
662
|
+
frame_folder,frame_rendering_folder,video_inference_output_file,output_video_file)
|
|
663
|
+
cmd += ' --render_output_video --fourcc mp4v'
|
|
664
|
+
cmd += ' --force_extracted_frame_folder_deletion --force_rendered_frame_folder_deletion --n_cores 5 --frame_sample 3'
|
|
665
|
+
print('Running: {}'.format(cmd))
|
|
666
|
+
cmd_results = execute_and_print(cmd)
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
## Run inference on a folder (again, so we can do a comparison)
|
|
670
|
+
|
|
671
|
+
image_folder = os.path.join(options.scratch_dir,'md-test-images')
|
|
672
|
+
model_file = 'MDV5B'
|
|
673
|
+
inference_output_file_alt = os.path.join(options.scratch_dir,'folder_inference_output_alt.json')
|
|
674
|
+
if options.cli_working_dir is None:
|
|
675
|
+
cmd = 'python -m detection.run_detector_batch'
|
|
676
|
+
else:
|
|
677
|
+
cmd = 'python detection/run_detector_batch.py'
|
|
678
|
+
cmd += ' {} {} {} --recursive'.format(
|
|
679
|
+
model_file,image_folder,inference_output_file_alt)
|
|
680
|
+
cmd += ' --output_relative_filenames --quiet --include_image_size'
|
|
681
|
+
cmd += ' --include_image_timestamp --include_exif_data'
|
|
682
|
+
print('Running: {}'.format(cmd))
|
|
683
|
+
cmd_results = execute_and_print(cmd)
|
|
684
|
+
|
|
685
|
+
with open(inference_output_file_alt,'r') as f:
|
|
686
|
+
results_from_file = json.load(f) # noqa
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
## Compare the two files
|
|
690
|
+
|
|
691
|
+
comparison_output_folder = os.path.join(options.scratch_dir,'results_comparison')
|
|
692
|
+
image_folder = os.path.join(options.scratch_dir,'md-test-images')
|
|
693
|
+
results_files_string = '"{}" "{}"'.format(
|
|
694
|
+
inference_output_file,inference_output_file_alt)
|
|
695
|
+
if options.cli_working_dir is None:
|
|
696
|
+
cmd = 'python -m api.batch_processing.postprocessing.compare_batch_results'
|
|
697
|
+
else:
|
|
698
|
+
cmd = 'python api/batch_processing/postprocessing/compare_batch_results.py'
|
|
699
|
+
cmd += ' {} {} {}'.format(comparison_output_folder,image_folder,results_files_string)
|
|
700
|
+
print('Running: {}'.format(cmd))
|
|
701
|
+
cmd_results = execute_and_print(cmd)
|
|
702
|
+
|
|
703
|
+
assert cmd_results['status'] == 0, 'Error generating comparison HTML'
|
|
704
|
+
assert os.path.isfile(os.path.join(comparison_output_folder,'index.html')), \
|
|
705
|
+
'Failed to generate comparison HTML'
|
|
706
|
+
|
|
707
|
+
print('\n*** Finished CLI tests ***\n')
|
|
708
|
+
|
|
476
709
|
# ...def run_cli_tests(...)
|
|
477
710
|
|
|
478
711
|
|
|
@@ -518,9 +751,19 @@ if False:
|
|
|
518
751
|
|
|
519
752
|
options.disable_gpu = False
|
|
520
753
|
options.cpu_execution_is_error = False
|
|
521
|
-
options.
|
|
754
|
+
options.skip_video_tests = False
|
|
755
|
+
options.skip_python_tests = False
|
|
756
|
+
options.skip_cli_tests = False
|
|
522
757
|
options.scratch_dir = None
|
|
758
|
+
options.test_data_url = 'https://lila.science/public/md-test-package.zip'
|
|
759
|
+
options.force_data_download = False
|
|
760
|
+
options.force_data_unzip = False
|
|
761
|
+
options.warning_mode = True
|
|
762
|
+
options.test_image_subdir = 'md-test-images'
|
|
763
|
+
options.max_coord_error = 0.001
|
|
764
|
+
options.max_conf_error = 0.005
|
|
523
765
|
options.cli_working_dir = r'c:\git\MegaDetector'
|
|
766
|
+
options.yolo_working_folder = r'c:\git\yolov5'
|
|
524
767
|
|
|
525
768
|
|
|
526
769
|
#%%
|
|
@@ -602,6 +845,10 @@ def main():
|
|
|
602
845
|
type=str,
|
|
603
846
|
default=None,
|
|
604
847
|
help='Working directory for CLI tests')
|
|
848
|
+
|
|
849
|
+
# token used for linting
|
|
850
|
+
#
|
|
851
|
+
# no_arguments_required
|
|
605
852
|
|
|
606
853
|
args = parser.parse_args()
|
|
607
854
|
|