megadetector 5.0.22__py3-none-any.whl → 5.0.24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of megadetector might be problematic. Click here for more details.

Files changed (38) hide show
  1. megadetector/api/synchronous/api_core/animal_detection_api/api_backend.py +2 -3
  2. megadetector/classification/merge_classification_detection_output.py +2 -2
  3. megadetector/data_management/coco_to_labelme.py +2 -1
  4. megadetector/data_management/databases/integrity_check_json_db.py +15 -14
  5. megadetector/data_management/databases/subset_json_db.py +49 -21
  6. megadetector/data_management/mewc_to_md.py +340 -0
  7. megadetector/data_management/wi_to_md.py +41 -0
  8. megadetector/data_management/yolo_output_to_md_output.py +15 -8
  9. megadetector/detection/process_video.py +24 -7
  10. megadetector/detection/pytorch_detector.py +841 -160
  11. megadetector/detection/run_detector.py +340 -146
  12. megadetector/detection/run_detector_batch.py +306 -70
  13. megadetector/detection/run_inference_with_yolov5_val.py +61 -4
  14. megadetector/detection/tf_detector.py +6 -1
  15. megadetector/postprocessing/{combine_api_outputs.py → combine_batch_outputs.py} +10 -13
  16. megadetector/postprocessing/compare_batch_results.py +68 -6
  17. megadetector/postprocessing/md_to_labelme.py +7 -7
  18. megadetector/postprocessing/md_to_wi.py +40 -0
  19. megadetector/postprocessing/merge_detections.py +1 -1
  20. megadetector/postprocessing/postprocess_batch_results.py +10 -3
  21. megadetector/postprocessing/separate_detections_into_folders.py +32 -4
  22. megadetector/postprocessing/validate_batch_results.py +9 -4
  23. megadetector/utils/ct_utils.py +172 -57
  24. megadetector/utils/gpu_test.py +107 -0
  25. megadetector/utils/md_tests.py +363 -108
  26. megadetector/utils/path_utils.py +9 -2
  27. megadetector/utils/wi_utils.py +1794 -0
  28. megadetector/visualization/visualization_utils.py +82 -16
  29. megadetector/visualization/visualize_db.py +25 -7
  30. megadetector/visualization/visualize_detector_output.py +60 -13
  31. {megadetector-5.0.22.dist-info → megadetector-5.0.24.dist-info}/LICENSE +0 -0
  32. {megadetector-5.0.22.dist-info → megadetector-5.0.24.dist-info}/METADATA +129 -143
  33. {megadetector-5.0.22.dist-info → megadetector-5.0.24.dist-info}/RECORD +35 -33
  34. {megadetector-5.0.22.dist-info → megadetector-5.0.24.dist-info}/top_level.txt +0 -0
  35. megadetector/detection/detector_training/__init__.py +0 -0
  36. megadetector/detection/detector_training/model_main_tf2.py +0 -114
  37. megadetector/utils/torch_test.py +0 -32
  38. {megadetector-5.0.22.dist-info → megadetector-5.0.24.dist-info}/WHEEL +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  yolo_output_to_md_output.py
4
4
 
5
- Converts the output of YOLOv5's detect.py or val.py to the MD API output format.
5
+ Converts the output of YOLOv5's detect.py or val.py to the MD output format.
6
6
 
7
7
  **Converting .txt files**
8
8
 
@@ -74,7 +74,7 @@ def read_classes_from_yolo_dataset_file(fn):
74
74
  with open(fn,'r') as f:
75
75
  lines = f.readlines()
76
76
 
77
- pat = '\d+:.+'
77
+ pat = r'\d+:.+'
78
78
  for s in lines:
79
79
  if re.search(pat,s) is not None:
80
80
  tokens = s.split(':')
@@ -281,7 +281,7 @@ def yolo_json_output_to_md_output(yolo_json_file,
281
281
  output_det['category'] = str(int(yolo_cat_id))
282
282
  conf = det['score']
283
283
  if truncate_to_standard_md_precision:
284
- conf = ct_utils.truncate_float(conf,CONF_DIGITS)
284
+ conf = ct_utils.round_float(conf,CONF_DIGITS)
285
285
  output_det['conf'] = conf
286
286
  input_bbox = det['bbox']
287
287
 
@@ -301,7 +301,7 @@ def yolo_json_output_to_md_output(yolo_json_file,
301
301
  box_width_relative,box_height_relative]
302
302
 
303
303
  if truncate_to_standard_md_precision:
304
- output_bbox = ct_utils.truncate_float_array(output_bbox,COORD_DIGITS)
304
+ output_bbox = ct_utils.round_float_array(output_bbox,COORD_DIGITS)
305
305
 
306
306
  output_det['bbox'] = output_bbox
307
307
  im['detections'].append(output_det)
@@ -332,7 +332,8 @@ def yolo_json_output_to_md_output(yolo_json_file,
332
332
  def yolo_txt_output_to_md_output(input_results_folder,
333
333
  image_folder,
334
334
  output_file,
335
- detector_tag=None):
335
+ detector_tag=None,
336
+ truncate_to_standard_md_precision=True):
336
337
  """
337
338
  Converts a folder of YOLO-output .txt files to MD .json format.
338
339
 
@@ -347,7 +348,9 @@ def yolo_txt_output_to_md_output(input_results_folder,
347
348
  output_file (str): the MD-formatted .json file to which we should write
348
349
  results
349
350
  detector_tag (str, optional): string to put in the 'detector' field in the
350
- output file
351
+ output file
352
+ truncate_to_standard_md_precision (bool, optional): set this to truncate to
353
+ COORD_DIGITS and CONF_DIGITS, like the standard MD pipeline does.
351
354
  """
352
355
 
353
356
  assert os.path.isdir(input_results_folder)
@@ -398,12 +401,16 @@ def yolo_txt_output_to_md_output(input_results_folder,
398
401
  api_box = ct_utils.convert_yolo_to_xywh([float(row[1]), float(row[2]),
399
402
  float(row[3]), float(row[4])])
400
403
 
401
- conf = ct_utils.truncate_float(float(row[5]), precision=4)
404
+ conf = float(row[5])
405
+
406
+ if truncate_to_standard_md_precision:
407
+ conf = ct_utils.round_float(conf, precision=CONF_DIGITS)
408
+ api_box = ct_utils.round_float_array(api_box, precision=COORD_DIGITS)
402
409
 
403
410
  detections.append({
404
411
  'category': str(category),
405
412
  'conf': conf,
406
- 'bbox': ct_utils.truncate_float_array(api_box, precision=4)
413
+ 'bbox': api_box
407
414
  })
408
415
 
409
416
  images_entries.append({
@@ -28,6 +28,7 @@ from uuid import uuid1
28
28
  from megadetector.detection import run_detector_batch
29
29
  from megadetector.visualization import visualize_detector_output
30
30
  from megadetector.utils.ct_utils import args_to_object
31
+ from megadetector.utils.ct_utils import dict_to_kvp_list, parse_kvp_list
31
32
  from megadetector.utils.path_utils import insert_before_extension, clean_path
32
33
  from megadetector.detection.video_utils import video_to_frames
33
34
  from megadetector.detection.video_utils import run_callback_on_frames
@@ -163,7 +164,7 @@ class ProcessVideoOptions:
163
164
  self.max_width = None
164
165
 
165
166
  #: Run the model at this image size (don't mess with this unless you know what you're
166
- #: getting into)
167
+ #: getting into)... if you just want to pass smaller frames to MD, use max_width
167
168
  self.image_size = None
168
169
 
169
170
  #: Enable image augmentation
@@ -178,6 +179,9 @@ class ProcessVideoOptions:
178
179
  #: frame result for each video (default), or every frame that was processed?
179
180
  self.include_all_processed_frames = False
180
181
 
182
+ #: Detector-specific options
183
+ self.detector_options = None
184
+
181
185
  # ...class ProcessVideoOptions
182
186
 
183
187
 
@@ -402,7 +406,7 @@ def process_video(options):
402
406
  print('Warning: frame_folder specified, but keep_extracted_frames is ' + \
403
407
  'not; no raw frames will be written')
404
408
 
405
- detector = load_detector(options.model_file)
409
+ detector = load_detector(options.model_file,detector_options=options.detector_options)
406
410
 
407
411
  def frame_callback(image_np,image_id):
408
412
  return detector.generate_detections_one_image(image_np,
@@ -475,7 +479,8 @@ def process_video(options):
475
479
  class_mapping_filename=options.class_mapping_filename,
476
480
  quiet=True,
477
481
  augment=options.augment,
478
- image_size=options.image_size)
482
+ image_size=options.image_size,
483
+ detector_options=options.detector_options)
479
484
 
480
485
  results = _add_frame_numbers_to_results(results)
481
486
 
@@ -612,7 +617,7 @@ def process_video_folder(options):
612
617
  print('Warning: frame_folder specified, but keep_extracted_frames is ' + \
613
618
  'not; no raw frames will be written')
614
619
 
615
- detector = load_detector(options.model_file)
620
+ detector = load_detector(options.model_file,detector_options=options.detector_options)
616
621
 
617
622
  def frame_callback(image_np,image_id):
618
623
  return detector.generate_detections_one_image(image_np,
@@ -719,7 +724,8 @@ def process_video_folder(options):
719
724
  class_mapping_filename=options.class_mapping_filename,
720
725
  quiet=True,
721
726
  augment=options.augment,
722
- image_size=options.image_size)
727
+ image_size=options.image_size,
728
+ detector_options=options.detector_options)
723
729
 
724
730
  _add_frame_numbers_to_results(results)
725
731
 
@@ -910,6 +916,8 @@ def options_to_command(options):
910
916
  cmd += ' --force_extracted_frame_folder_deletion'
911
917
  if options.force_rendered_frame_folder_deletion:
912
918
  cmd += ' --force_rendered_frame_folder_deletion'
919
+ if options.detector_options is not None and len(options.detector_options) > 0:
920
+ cmd += '--detector_options {}'.format(dict_to_kvp_list(options.detector_options))
913
921
 
914
922
  return cmd
915
923
 
@@ -1209,14 +1217,23 @@ def main():
1209
1217
  parser.add_argument('--allow_empty_videos',
1210
1218
  action='store_true',
1211
1219
  help='By default, videos with no retrievable frames cause an error, this makes it a warning')
1212
-
1220
+
1221
+ parser.add_argument(
1222
+ '--detector_options',
1223
+ nargs='*',
1224
+ metavar='KEY=VALUE',
1225
+ default='',
1226
+ help='Detector-specific options, as a space-separated list of key-value pairs')
1227
+
1213
1228
  if len(sys.argv[1:]) == 0:
1214
1229
  parser.print_help()
1215
1230
  parser.exit()
1216
1231
 
1217
1232
  args = parser.parse_args()
1218
- options = ProcessVideoOptions()
1233
+ options = ProcessVideoOptions()
1219
1234
  args_to_object(args,options)
1235
+
1236
+ options.detector_options = parse_kvp_list(args.detector_options)
1220
1237
 
1221
1238
  if os.path.isdir(options.input_video_file):
1222
1239
  process_video_folder(options)