megadetector 10.0.8__py3-none-any.whl → 10.0.10__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.

@@ -24,10 +24,14 @@ from multiprocessing.pool import Pool, ThreadPool
24
24
  from functools import partial
25
25
 
26
26
  from megadetector.utils.path_utils import insert_before_extension
27
+ from megadetector.utils.path_utils import path_join
28
+
27
29
  from megadetector.utils.ct_utils import split_list_into_n_chunks
28
30
  from megadetector.utils.ct_utils import invert_dictionary
29
31
  from megadetector.utils.ct_utils import compare_values_nan_equal
30
32
 
33
+ from megadetector.utils.string_utils import is_int
34
+
31
35
  from megadetector.utils.wi_taxonomy_utils import is_valid_prediction_string
32
36
  from megadetector.utils.wi_taxonomy_utils import no_cv_result_prediction_string
33
37
  from megadetector.utils.wi_taxonomy_utils import blank_prediction_string
@@ -68,7 +72,7 @@ def read_sequences_from_download_bundle(download_folder):
68
72
  assert len(sequence_list_files) == 1, \
69
73
  'Could not find sequences.csv in {}'.format(download_folder)
70
74
 
71
- sequence_list_file = os.path.join(download_folder,sequence_list_files[0])
75
+ sequence_list_file = path_join(download_folder,sequence_list_files[0])
72
76
 
73
77
  df = pd.read_csv(sequence_list_file)
74
78
  sequence_records = df.to_dict('records')
@@ -104,7 +108,7 @@ def read_images_from_download_bundle(download_folder):
104
108
  image_list_files = \
105
109
  [fn for fn in image_list_files if fn.startswith('images_') and fn.endswith('.csv')]
106
110
  image_list_files = \
107
- [os.path.join(download_folder,fn) for fn in image_list_files]
111
+ [path_join(download_folder,fn) for fn in image_list_files]
108
112
  print('Found {} image list files'.format(len(image_list_files)))
109
113
 
110
114
 
@@ -118,7 +122,7 @@ def read_images_from_download_bundle(download_folder):
118
122
  print('Reading images from list file {}'.format(
119
123
  os.path.basename(image_list_file)))
120
124
 
121
- df = pd.read_csv(image_list_file)
125
+ df = pd.read_csv(image_list_file,low_memory=False)
122
126
 
123
127
  # i_row = 0; row = df.iloc[i_row]
124
128
  for i_row,row in tqdm(df.iterrows(),total=len(df)):
@@ -203,11 +207,91 @@ def find_images_in_identify_tab(download_folder_with_identify,download_folder_ex
203
207
  # ...def find_images_in_identify_tab(...)
204
208
 
205
209
 
206
- def write_download_commands(image_records_to_download,
210
+ def write_prefix_download_command(image_records,
211
+ download_dir_base,
212
+ force_download=False,
213
+ download_command_file=None):
214
+ """
215
+ Write a .sh script to download all images (using gcloud) from the longest common URL
216
+ prefix in the images represented in [image_records].
217
+
218
+ Args:
219
+ image_records (list of dict): list of dicts with at least the field 'location'.
220
+ Can also be a dict whose values are lists of record dicts.
221
+ download_dir_base (str): local destination folder
222
+ force_download (bool, optional): overwrite existing files
223
+ download_command_file (str, optional): path of the .sh script we should write, defaults
224
+ to "download_wi_images_with_prefix.sh" in the destination folder.
225
+ """
226
+
227
+ ##%% Input validation
228
+
229
+ # If a dict is provided, assume it maps image GUIDs to lists of records, flatten to a list
230
+ if isinstance(image_records,dict):
231
+ all_image_records = []
232
+ for k in image_records:
233
+ records_this_image = image_records[k]
234
+ all_image_records.extend(records_this_image)
235
+ image_records = all_image_records
236
+
237
+ assert isinstance(image_records,list), \
238
+ 'Illegal image record list format {}'.format(type(image_records))
239
+ assert isinstance(image_records[0],dict), \
240
+ 'Illegal image record format {}'.format(type(image_records[0]))
241
+
242
+ urls = [r['location'] for r in image_records]
243
+
244
+ # "urls" is a list of URLs starting with gs://. Find the highest-level folder
245
+ # that is common to all URLs in the list. For example, if the list is:
246
+ #
247
+ # gs://a/b/c
248
+ # gs://a/b/d
249
+ #
250
+ # The result should be:
251
+ #
252
+ # gs://a/b
253
+ common_prefix = os.path.commonprefix(urls)
254
+
255
+ # Remove the gs:// prefix if it's still there
256
+ if common_prefix.startswith('gs://'):
257
+ common_prefix = common_prefix[len('gs://'):]
258
+
259
+ # Ensure the common prefix ends with a '/' if it's not empty
260
+ if (len(common_prefix) > 0) and (not common_prefix.endswith('/')):
261
+ common_prefix = os.path.dirname(common_prefix) + '/'
262
+
263
+ print('Longest common prefix: {}'.format(common_prefix))
264
+
265
+ if download_command_file is None:
266
+ download_command_file = \
267
+ path_join(download_dir_base,'download_wi_images_with_prefix.sh')
268
+
269
+ os.makedirs(download_dir_base,exist_ok=True)
270
+
271
+ with open(download_command_file,'w',newline='\n') as f:
272
+ # The --no-clobber flag prevents overwriting existing files
273
+ # The -r flag is for recursive download
274
+ # The gs:// prefix is added back for the gcloud command
275
+ no_clobber_string = ''
276
+ if not force_download:
277
+ no_clobber_string = '--no-clobber'
278
+
279
+ cmd = 'gcloud storage cp -r {} "gs://{}" "{}"'.format(
280
+ no_clobber_string,common_prefix,download_dir_base)
281
+ print('Writing download command:\n{}'.format(cmd))
282
+ f.write(cmd + '\n')
283
+
284
+ print('Download script written to {}'.format(download_command_file))
285
+
286
+ # ...def write_prefix_download_command(...)
287
+
288
+
289
+ def write_download_commands(image_records,
207
290
  download_dir_base,
208
291
  force_download=False,
209
292
  n_download_workers=25,
210
- download_command_file_base=None):
293
+ download_command_file_base=None,
294
+ image_flattening='deployment'):
211
295
  """
212
296
  Given a list of dicts with at least the field 'location' (a gs:// URL), prepare a set of "gcloud
213
297
  storage" commands to download images, and write those to a series of .sh scripts, along with one
@@ -215,10 +299,9 @@ def write_download_commands(image_records_to_download,
215
299
 
216
300
  gcloud commands will use relative paths.
217
301
 
218
- image_records_to_download can also be a dict mapping IDs to lists of records.
219
-
220
302
  Args:
221
- image_records_to_download (list of dict): list of dicts with at least the field 'location'
303
+ image_records (list of dict): list of dicts with at least the field 'location'.
304
+ Can also be a dict whose values are lists of record dicts.
222
305
  download_dir_base (str): local destination folder
223
306
  force_download (bool, optional): include gs commands even if the target file exists
224
307
  n_download_workers (int, optional): number of scripts to write (that's our hacky way
@@ -226,42 +309,103 @@ def write_download_commands(image_records_to_download,
226
309
  download_command_file_base (str, optional): path of the .sh script we should write, defaults
227
310
  to "download_wi_images.sh" in the destination folder. Individual worker scripts will
228
311
  have a number added, e.g. download_wi_images_00.sh.
312
+ image_flattening (str, optional): if 'none', relative paths will be preserved
313
+ representing the entire URL for each image. Can be 'guid' (just download to
314
+ [GUID].JPG) or 'deployment' (download to [deployment]/[GUID].JPG).
229
315
  """
230
316
 
231
- if isinstance(image_records_to_download,dict):
317
+ ##%% Input validation
232
318
 
319
+ # If a dict is provided, assume it maps image GUIDs to lists of records, flatten to a list
320
+ if isinstance(image_records,dict):
233
321
  all_image_records = []
234
- for k in image_records_to_download:
235
- records_this_image = image_records_to_download[k]
322
+ for k in image_records:
323
+ records_this_image = image_records[k]
236
324
  all_image_records.extend(records_this_image)
237
- return write_download_commands(all_image_records,
238
- download_dir_base=download_dir_base,
239
- force_download=force_download,
240
- n_download_workers=n_download_workers,
241
- download_command_file_base=download_command_file_base)
325
+ image_records = all_image_records
326
+
327
+ assert isinstance(image_records,list), \
328
+ 'Illegal image record list format {}'.format(type(image_records))
329
+ assert isinstance(image_records[0],dict), \
330
+ 'Illegal image record format {}'.format(type(image_records[0]))
331
+
332
+
333
+ ##%% Map URLs to relative paths
334
+
335
+ # URLs look like:
336
+ #
337
+ # gs://145625555_2004881_2323_name__main/deployment/2241000/prod/directUpload/5fda0ddd-511e-46ca-95c1-302b3c71f8ea.JPG
338
+ if image_flattening is None:
339
+ image_flattening = 'none'
340
+ image_flattening = image_flattening.lower().strip()
341
+
342
+ assert image_flattening in ('none','guid','deployment'), \
343
+ 'Illegal image flattening strategy {}'.format(image_flattening)
344
+
345
+ url_to_relative_path = {}
346
+
347
+ for image_record in image_records:
348
+
349
+ url = image_record['location']
350
+ assert url.startswith('gs://'), 'Illegal URL {}'.format(url)
351
+
352
+ relative_path = None
353
+
354
+ if image_flattening == 'none':
355
+ relative_path = url.replace('gs://','')
356
+ elif image_flattening == 'guid':
357
+ relative_path = url.split('/')[-1]
358
+ else:
359
+ assert image_flattening == 'deployment'
360
+ tokens = url.split('/')
361
+ found_deployment_id = False
362
+ for i_token,token in enumerate(tokens):
363
+ if token == 'deployment':
364
+ assert i_token < (len(tokens)-1)
365
+ deployment_id_string = tokens[i_token + 1]
366
+ deployment_id_string = deployment_id_string.replace('_thumb','')
367
+ assert is_int(deployment_id_string), \
368
+ 'Illegal deployment ID {}'.format(deployment_id_string)
369
+ image_id = url.split('/')[-1]
370
+ relative_path = deployment_id_string + '/' + image_id
371
+ found_deployment_id = True
372
+ break
373
+ assert found_deployment_id, \
374
+ 'Could not find deployment ID in record {}'.format(str(image_record))
375
+
376
+ assert relative_path is not None
377
+
378
+ if url in url_to_relative_path:
379
+ assert url_to_relative_path[url] == relative_path, \
380
+ 'URL path mapping error'
381
+ else:
382
+ url_to_relative_path[url] = relative_path
383
+
384
+ # ...for each image record
385
+
242
386
 
243
387
  ##%% Make list of gcloud storage commands
244
388
 
245
389
  if download_command_file_base is None:
246
- download_command_file_base = os.path.join(download_dir_base,'download_wi_images.sh')
390
+ download_command_file_base = path_join(download_dir_base,'download_wi_images.sh')
247
391
 
248
392
  commands = []
249
393
  skipped_urls = []
250
394
  downloaded_urls = set()
251
395
 
252
- # image_record = image_records_to_download[0]
253
- for image_record in tqdm(image_records_to_download):
396
+ # image_record = image_records[0]
397
+ for image_record in tqdm(image_records):
254
398
 
255
399
  url = image_record['location']
256
400
  if url in downloaded_urls:
257
401
  continue
258
402
 
259
- assert url.startswith('gs://')
403
+ assert url.startswith('gs://'), 'Illegal URL {}'.format(url)
260
404
 
261
- relative_path = url.replace('gs://','')
262
- abs_path = os.path.join(download_dir_base,relative_path)
405
+ relative_path = url_to_relative_path[url]
406
+ abs_path = path_join(download_dir_base,relative_path)
263
407
 
264
- # Skip files that already exist
408
+ # Optionally skip files that already exist
265
409
  if (not force_download) and (os.path.isfile(abs_path)):
266
410
  skipped_urls.append(url)
267
411
  continue
@@ -271,7 +415,7 @@ def write_download_commands(image_records_to_download,
271
415
  commands.append(command)
272
416
 
273
417
  print('Generated {} commands for {} image records'.format(
274
- len(commands),len(image_records_to_download)))
418
+ len(commands),len(image_records)))
275
419
 
276
420
  print('Skipped {} URLs'.format(len(skipped_urls)))
277
421
 
@@ -754,6 +754,7 @@ def generate_instances_json_from_folder(folder,
754
754
 
755
755
  assert os.path.isdir(folder)
756
756
 
757
+ print('Enumerating images in {}'.format(folder))
757
758
  image_files_abs = find_images(folder,recursive=True,return_relative_paths=False)
758
759
 
759
760
  if tokens_to_ignore is not None:
@@ -428,6 +428,7 @@ def main(): # noqa
428
428
  category_names_to_blur=category_names_to_blur)
429
429
 
430
430
  if (args.html_output_file is not None) and args.open_html_output_file:
431
+ print('Opening output file {}'.format(args.html_output_file))
431
432
  open_file(args.html_output_file)
432
433
 
433
434
  if __name__ == '__main__':
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: megadetector
3
- Version: 10.0.8
3
+ Version: 10.0.10
4
4
  Summary: MegaDetector is an AI model that helps conservation folks spend less time doing boring things with camera trap images.
5
5
  Author-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
6
6
  Maintainer-email: Your friendly neighborhood MegaDetector team <cameratraps@lila.science>
@@ -43,7 +43,7 @@ megadetector/data_management/labelme_to_coco.py,sha256=SO6DMfJ9WNlMUHF9EUYWjSNye
43
43
  megadetector/data_management/labelme_to_yolo.py,sha256=bsqpNUsnDJucJ60wSQD_yvq_tWiots1u4tSFNiHeaYA,12769
44
44
  megadetector/data_management/mewc_to_md.py,sha256=09XHEykIG-whGkgEIkho7xfVuPlic1TYTKGAufv_tto,12637
45
45
  megadetector/data_management/ocr_tools.py,sha256=aYpULCPn_tHaqatOd8qjEpKJ7MksRZS0o1kqQF04IE0,31389
46
- megadetector/data_management/read_exif.py,sha256=M_8492al57kWgZ-0gNWLNdzpm442zPCC8J2DtgzHAyA,29646
46
+ megadetector/data_management/read_exif.py,sha256=80L_P2mGRKGA02X7jaGje27pwxrZ7mfIPo5IHKpYihc,30166
47
47
  megadetector/data_management/remap_coco_categories.py,sha256=DT4Rdt7Y1IdhbO2TZiBhQDESdit-l_-b_Hw0tbJ2Nuw,7090
48
48
  megadetector/data_management/remove_exif.py,sha256=5JHGWMIeXqB2PE2ZwIMJOEtNYopxknNDwynQAuJCLvw,4031
49
49
  megadetector/data_management/rename_images.py,sha256=iHkdQ_c1G9Oc8C4wcnPLmhKv0S9i9g7ppbytfBBqn2Y,6516
@@ -73,20 +73,20 @@ megadetector/data_management/lila/test_lila_metadata_urls.py,sha256=ThU78Ks5V3rF
73
73
  megadetector/detection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
74
  megadetector/detection/change_detection.py,sha256=Ne3GajbH_0KPBU8ruHp4Rkr0uKd5oKAMQ3CQTRKRHgQ,28659
75
75
  megadetector/detection/process_video.py,sha256=kuQHrpOC3LQo9ecqJPpzkds9fZVnoLmrfJw_yh-oxi8,17890
76
- megadetector/detection/pytorch_detector.py,sha256=4Ix6AOBciMbn5zFHXe4hgb5tXGOup57ju3z8gtsin3s,60567
77
- megadetector/detection/run_detector.py,sha256=TTX29zxDN_O7ja61sOmMIVewUz3yRvKg1D1AAYhVEkc,46851
78
- megadetector/detection/run_detector_batch.py,sha256=aZgiywL6arrdQ_l3jzlHctlccqL537lwVStjhi1hIWw,89823
76
+ megadetector/detection/pytorch_detector.py,sha256=-TvtDcX2Hh_CgBEz7Eg2NzyEts8DjOgY0mE_fle6zkM,60705
77
+ megadetector/detection/run_detector.py,sha256=JWTIYsk5aCgW9PBCGnAECe31JwKHhkfp6zKsSDqfrsA,46831
78
+ megadetector/detection/run_detector_batch.py,sha256=gc3T_h61tRk705Lxbi4BXboc-BmaitiNd-5cR5MzHC0,91423
79
79
  megadetector/detection/run_inference_with_yolov5_val.py,sha256=dJXh3BwKOQQ4OA-Mq_heEb7AfBAk7qKUAagnIGuFtaU,53689
80
- megadetector/detection/run_md_and_speciesnet.py,sha256=Dp_SpJZp0pX9jzFtxM6zPCyBNq49uyQpMDAdNDLVorM,50280
81
- megadetector/detection/run_tiled_inference.py,sha256=hVpR-URC67e6Ht-cy_EgIrJ4GFina29H_lBXOE3bzwM,39435
82
- megadetector/detection/tf_detector.py,sha256=3b2MiqgMw8KBDzHQliUSDXWrmKpa9iZnfe6EgYpMcYo,8398
80
+ megadetector/detection/run_md_and_speciesnet.py,sha256=LMpQVqpLqju2WFznHGKEyc9QCgU4pHSPyfDnf0HL9GA,52179
81
+ megadetector/detection/run_tiled_inference.py,sha256=v_wL4uZfYdswJdYXBoGci62UvVprBD9OHKkrw2g-G5M,41081
82
+ megadetector/detection/tf_detector.py,sha256=E0PZ1jHAv31kvsdaUD8IjuPmdLulkKwx6s2wbPMK-WQ,8151
83
83
  megadetector/detection/video_utils.py,sha256=M7yje6XeOnR_QwDyuG1o6bwTKvRysoA2NiOK2MSi98E,53943
84
84
  megadetector/postprocessing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  megadetector/postprocessing/add_max_conf.py,sha256=9MYtsH2mwkiaZb7Qcor5J_HskfAj7d9srp8G_Qldpk0,1722
86
86
  megadetector/postprocessing/categorize_detections_by_size.py,sha256=DpZpRNFlyeOfWuOc6ICuENgIWDCEtiErJ_frBZp9lYM,5382
87
- megadetector/postprocessing/classification_postprocessing.py,sha256=OoPVr34vXyLykB42SplcSKo9cj7dgf8Yju_DCDhd6_k,68574
87
+ megadetector/postprocessing/classification_postprocessing.py,sha256=WtZqgY43-KdbVmuG_PPh_5HK3J7-Q-laKQtQmbhdvI0,68701
88
88
  megadetector/postprocessing/combine_batch_outputs.py,sha256=BEP8cVa0sMIPg7tkWQc_8vOEPnbmWjOsQdVJHe61uz8,8468
89
- megadetector/postprocessing/compare_batch_results.py,sha256=RDlKLwea76rOWiDneSJUj6P_oMBMnD2BY4inoxLqQiw,84258
89
+ megadetector/postprocessing/compare_batch_results.py,sha256=QbdegGZkgVLZdO5Vjm3aTAQS5VzP9_tX0PKwCSkHKhw,85009
90
90
  megadetector/postprocessing/convert_output_format.py,sha256=3KLO6NqddofgIEYjV8_iZIf0iXaplFN2AroUq5i4R7k,14472
91
91
  megadetector/postprocessing/create_crop_folder.py,sha256=T37HnvBEakikXY3n3Bgk5boFo_0-Z5aKnkEWXv-Ki4s,23166
92
92
  megadetector/postprocessing/detector_calibration.py,sha256=UFjJ8D6tMghatLRj3CyrtJ7vrPIJkULMNsYMIj98j2M,20495
@@ -96,11 +96,11 @@ megadetector/postprocessing/md_to_coco.py,sha256=CkN1ky4A2uZj_gUu8rmyaaxyOH00k6J
96
96
  megadetector/postprocessing/md_to_labelme.py,sha256=r-EGyXVrSSyN6N6wqQ6pwKeV-fCNzb50ZkJqaDqjrvM,11935
97
97
  megadetector/postprocessing/md_to_wi.py,sha256=8IHtkMNKRMIcvE2jsKNfKtdH94JTkzrByyo5uBXHOSA,1220
98
98
  megadetector/postprocessing/merge_detections.py,sha256=hvb4TJ6u1PyWOVQai9wZk72li1GpjmBxbpfUcV3qqXY,15749
99
- megadetector/postprocessing/postprocess_batch_results.py,sha256=VJyXx8I6KZgefrLNKdvUIf_lCtZW3e_lMBR9TMKYi0E,84606
99
+ megadetector/postprocessing/postprocess_batch_results.py,sha256=M6dTnMEPm6iaLYBwZl4qvAbMGPvWIcD7-HhVty43lTw,84610
100
100
  megadetector/postprocessing/remap_detection_categories.py,sha256=BE6Ce-PGBEx1FyG3XwbYp2D5sh5xUlVf6fonaMuPMAg,7927
101
101
  megadetector/postprocessing/render_detection_confusion_matrix.py,sha256=oNvDTh5td5ynELNnhz4XaLP2HiwLuojkJlob15TpgcY,26365
102
102
  megadetector/postprocessing/separate_detections_into_folders.py,sha256=Yvpkl_MsWbGoo4zvQHrXHkATRJaYdYligItfg9bvuV8,32262
103
- megadetector/postprocessing/subset_json_detector_output.py,sha256=R6CtSMcriXq50EHawXWC5pHZ-vtJFSKqjeleGKiouDY,32325
103
+ megadetector/postprocessing/subset_json_detector_output.py,sha256=HI-TD0rEzIttg7U8ap8HWHJnbXXjY2vS74axnmLnOGU,35041
104
104
  megadetector/postprocessing/top_folders_to_bottom.py,sha256=zYrqMHjUZG8urh2CYphfs91ZQ620uqe-TL8jVYy8KVw,6049
105
105
  megadetector/postprocessing/validate_batch_results.py,sha256=9nr7LeKMdki9Y821ag2bZFQCxuq0OqINDH7cPXyVcY8,12059
106
106
  megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py,sha256=XgVeyga8iSC01MAjXxb2rn-CgJTYHqC_gfxxEoSn4aw,9420
@@ -121,27 +121,27 @@ megadetector/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
121
121
  megadetector/tests/test_nms_synthetic.py,sha256=oY6xmT1sLSSN7weQJ8TPTaZgAiSiZ6s43EffUhwLWIw,14707
122
122
  megadetector/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
123
  megadetector/utils/ct_utils.py,sha256=IiZV8dWtJamveINv_joATMgMPHeDkZ8l82jDEQcLgQg,60502
124
- megadetector/utils/directory_listing.py,sha256=0-VMuQWo6rETIKERqfX6Zn7pRp_GJ4JiFiWvsw9PQcU,6500
124
+ megadetector/utils/directory_listing.py,sha256=ZTwryqP_02XSHlsaVNCo7qyLGM4EKB-2NYxcmQpQEwM,6573
125
125
  megadetector/utils/extract_frames_from_video.py,sha256=vjSVgxtb5z2syHCVYWc2KdNUpc-O6yY8nkbj_wqsIvY,12255
126
126
  megadetector/utils/gpu_test.py,sha256=5zUfAVeSjH8I08eCqayFmMxL-0mix8SjJJTe5ORABvU,3544
127
127
  megadetector/utils/md_tests.py,sha256=Iup4KjyIpLUpZ4TzzwEyGK61rg6aH7NrEQsdQ-ov51I,80300
128
- megadetector/utils/path_utils.py,sha256=tV8eh77m_uS8YYpOQZO8GUKR6l5sZrSSIkApqgi_DmY,101030
128
+ megadetector/utils/path_utils.py,sha256=RDz3-Cts6NG118ll2WXzSThNZe5rJUxWZdxeIbjUMcg,102900
129
129
  megadetector/utils/process_utils.py,sha256=gQcpH9WYvGPUs0FhtJ5_Xvl6JsvoGz8_mnDQk0PbTRM,5673
130
130
  megadetector/utils/split_locations_into_train_val.py,sha256=fd_6pj1aWY6hybwaXvBn9kBcOHjI90U-OsTmEAGpeu8,10297
131
- megadetector/utils/string_utils.py,sha256=r2Maw3zbzk3EyaZcNkdqr96yP_8m4ey6v0WxlemEY9U,6155
131
+ megadetector/utils/string_utils.py,sha256=OejBfVWdmc-uHaCTfQN5PChsd1tMuiRJVRHQV0xZWt8,6533
132
132
  megadetector/utils/url_utils.py,sha256=PzqN-VquAZFBRin2ZaYi5U2WCsMYSwvM0X-NN45Fdh4,28448
133
- megadetector/utils/wi_platform_utils.py,sha256=8CGpiox_aL6RVZKfJqPVwpW4_6Cjku0HIajJPcmeNpE,32019
134
- megadetector/utils/wi_taxonomy_utils.py,sha256=o4AvY5gZXfk69pPckdGxgIPhqsH2-hJQucavSRsUnoc,66513
133
+ megadetector/utils/wi_platform_utils.py,sha256=TSckCBi6yIe6VAJhZtbf7aiZ_U0ipBzr_RU9OEqneaU,37688
134
+ megadetector/utils/wi_taxonomy_utils.py,sha256=yd8C38DJWUfhSTaO5Zr_YoDqqR02OA-ZbrSHCbU1utI,66566
135
135
  megadetector/utils/write_html_image_list.py,sha256=6Tbe5wyUxoBYJgH9yVrxxKCeWF2BVre_wQMEOQJ-ZIU,9068
136
136
  megadetector/visualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
137
  megadetector/visualization/plot_utils.py,sha256=uDDlOhdaJ3V8sGj2kS9b0cgszKc8WCq2_ofl6TW_XUs,10727
138
138
  megadetector/visualization/render_images_with_thumbnails.py,sha256=-XX4PG4wnrFjFTIwd0sMxXxKMxPuu0SZ_TfK3dI1x8Y,8425
139
139
  megadetector/visualization/visualization_utils.py,sha256=E5uvysS3F1S_yiPFxZty3U2f6cjuE8zG6XWggYOu-5o,75921
140
140
  megadetector/visualization/visualize_db.py,sha256=8YDWSR0eMehXYdPtak9z8UUw35xV7hu-0eCuzgSLjWc,25558
141
- megadetector/visualization/visualize_detector_output.py,sha256=HpWh7ugwo51YBHsFi40iAp9G-uRAMMjgsm8H_uBolBs,20295
141
+ megadetector/visualization/visualize_detector_output.py,sha256=nfB4JtfNU5PgFzuWxXSUSfCib29DWSNPhIf9drtD9Qs,20365
142
142
  megadetector/visualization/visualize_video_output.py,sha256=ibMGB5ynMwNXmaMlY8h8tURb-Lyvuxs1EB08x_jvev0,20606
143
- megadetector-10.0.8.dist-info/licenses/LICENSE,sha256=RMa3qq-7Cyk7DdtqRj_bP1oInGFgjyHn9-PZ3PcrqIs,1100
144
- megadetector-10.0.8.dist-info/METADATA,sha256=eMFedi5m5t_vYsJzAQsf7Q2Z9mHASAqEOuJjiQVWgZE,6486
145
- megadetector-10.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
146
- megadetector-10.0.8.dist-info/top_level.txt,sha256=wf9DXa8EwiOSZ4G5IPjakSxBPxTDjhYYnqWRfR-zS4M,13
147
- megadetector-10.0.8.dist-info/RECORD,,
143
+ megadetector-10.0.10.dist-info/licenses/LICENSE,sha256=RMa3qq-7Cyk7DdtqRj_bP1oInGFgjyHn9-PZ3PcrqIs,1100
144
+ megadetector-10.0.10.dist-info/METADATA,sha256=-4OEXDgVH3BLpXqLN2a3BKeVBI4wDbOQTnfzRs2dggw,6487
145
+ megadetector-10.0.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
146
+ megadetector-10.0.10.dist-info/top_level.txt,sha256=wf9DXa8EwiOSZ4G5IPjakSxBPxTDjhYYnqWRfR-zS4M,13
147
+ megadetector-10.0.10.dist-info/RECORD,,