megadetector 5.0.28__py3-none-any.whl → 5.0.29__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 (176) hide show
  1. megadetector/api/batch_processing/api_core/batch_service/score.py +4 -5
  2. megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +1 -1
  3. megadetector/api/batch_processing/api_support/summarize_daily_activity.py +1 -1
  4. megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
  5. megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
  6. megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
  7. megadetector/api/synchronous/api_core/tests/load_test.py +2 -3
  8. megadetector/classification/aggregate_classifier_probs.py +3 -3
  9. megadetector/classification/analyze_failed_images.py +5 -5
  10. megadetector/classification/cache_batchapi_outputs.py +5 -5
  11. megadetector/classification/create_classification_dataset.py +11 -12
  12. megadetector/classification/crop_detections.py +10 -10
  13. megadetector/classification/csv_to_json.py +8 -8
  14. megadetector/classification/detect_and_crop.py +13 -15
  15. megadetector/classification/evaluate_model.py +7 -7
  16. megadetector/classification/identify_mislabeled_candidates.py +6 -6
  17. megadetector/classification/json_to_azcopy_list.py +1 -1
  18. megadetector/classification/json_validator.py +29 -32
  19. megadetector/classification/map_classification_categories.py +9 -9
  20. megadetector/classification/merge_classification_detection_output.py +12 -9
  21. megadetector/classification/prepare_classification_script.py +19 -19
  22. megadetector/classification/prepare_classification_script_mc.py +23 -23
  23. megadetector/classification/run_classifier.py +4 -4
  24. megadetector/classification/save_mislabeled.py +6 -6
  25. megadetector/classification/train_classifier.py +1 -1
  26. megadetector/classification/train_classifier_tf.py +9 -9
  27. megadetector/classification/train_utils.py +10 -10
  28. megadetector/data_management/annotations/annotation_constants.py +1 -1
  29. megadetector/data_management/camtrap_dp_to_coco.py +45 -45
  30. megadetector/data_management/cct_json_utils.py +101 -101
  31. megadetector/data_management/cct_to_md.py +49 -49
  32. megadetector/data_management/cct_to_wi.py +33 -33
  33. megadetector/data_management/coco_to_labelme.py +75 -75
  34. megadetector/data_management/coco_to_yolo.py +189 -189
  35. megadetector/data_management/databases/add_width_and_height_to_db.py +3 -2
  36. megadetector/data_management/databases/combine_coco_camera_traps_files.py +38 -38
  37. megadetector/data_management/databases/integrity_check_json_db.py +202 -188
  38. megadetector/data_management/databases/subset_json_db.py +33 -33
  39. megadetector/data_management/generate_crops_from_cct.py +38 -38
  40. megadetector/data_management/get_image_sizes.py +54 -49
  41. megadetector/data_management/labelme_to_coco.py +130 -124
  42. megadetector/data_management/labelme_to_yolo.py +78 -72
  43. megadetector/data_management/lila/create_lila_blank_set.py +81 -83
  44. megadetector/data_management/lila/create_lila_test_set.py +32 -31
  45. megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
  46. megadetector/data_management/lila/download_lila_subset.py +21 -24
  47. megadetector/data_management/lila/generate_lila_per_image_labels.py +91 -91
  48. megadetector/data_management/lila/get_lila_annotation_counts.py +30 -30
  49. megadetector/data_management/lila/get_lila_image_counts.py +22 -22
  50. megadetector/data_management/lila/lila_common.py +70 -70
  51. megadetector/data_management/lila/test_lila_metadata_urls.py +13 -14
  52. megadetector/data_management/mewc_to_md.py +339 -340
  53. megadetector/data_management/ocr_tools.py +258 -252
  54. megadetector/data_management/read_exif.py +231 -224
  55. megadetector/data_management/remap_coco_categories.py +26 -26
  56. megadetector/data_management/remove_exif.py +31 -20
  57. megadetector/data_management/rename_images.py +187 -187
  58. megadetector/data_management/resize_coco_dataset.py +41 -41
  59. megadetector/data_management/speciesnet_to_md.py +41 -41
  60. megadetector/data_management/wi_download_csv_to_coco.py +55 -55
  61. megadetector/data_management/yolo_output_to_md_output.py +117 -120
  62. megadetector/data_management/yolo_to_coco.py +195 -188
  63. megadetector/detection/change_detection.py +831 -0
  64. megadetector/detection/process_video.py +340 -337
  65. megadetector/detection/pytorch_detector.py +304 -262
  66. megadetector/detection/run_detector.py +177 -164
  67. megadetector/detection/run_detector_batch.py +364 -363
  68. megadetector/detection/run_inference_with_yolov5_val.py +328 -325
  69. megadetector/detection/run_tiled_inference.py +256 -249
  70. megadetector/detection/tf_detector.py +24 -24
  71. megadetector/detection/video_utils.py +290 -282
  72. megadetector/postprocessing/add_max_conf.py +15 -11
  73. megadetector/postprocessing/categorize_detections_by_size.py +44 -44
  74. megadetector/postprocessing/classification_postprocessing.py +415 -415
  75. megadetector/postprocessing/combine_batch_outputs.py +20 -21
  76. megadetector/postprocessing/compare_batch_results.py +528 -517
  77. megadetector/postprocessing/convert_output_format.py +97 -97
  78. megadetector/postprocessing/create_crop_folder.py +219 -146
  79. megadetector/postprocessing/detector_calibration.py +173 -168
  80. megadetector/postprocessing/generate_csv_report.py +508 -499
  81. megadetector/postprocessing/load_api_results.py +23 -20
  82. megadetector/postprocessing/md_to_coco.py +129 -98
  83. megadetector/postprocessing/md_to_labelme.py +89 -83
  84. megadetector/postprocessing/md_to_wi.py +40 -40
  85. megadetector/postprocessing/merge_detections.py +87 -114
  86. megadetector/postprocessing/postprocess_batch_results.py +313 -298
  87. megadetector/postprocessing/remap_detection_categories.py +36 -36
  88. megadetector/postprocessing/render_detection_confusion_matrix.py +205 -199
  89. megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
  90. megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +27 -28
  91. megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +702 -677
  92. megadetector/postprocessing/separate_detections_into_folders.py +226 -211
  93. megadetector/postprocessing/subset_json_detector_output.py +265 -262
  94. megadetector/postprocessing/top_folders_to_bottom.py +45 -45
  95. megadetector/postprocessing/validate_batch_results.py +70 -70
  96. megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
  97. megadetector/taxonomy_mapping/map_new_lila_datasets.py +15 -15
  98. megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +14 -14
  99. megadetector/taxonomy_mapping/preview_lila_taxonomy.py +66 -66
  100. megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
  101. megadetector/taxonomy_mapping/simple_image_download.py +8 -8
  102. megadetector/taxonomy_mapping/species_lookup.py +33 -33
  103. megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
  104. megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
  105. megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
  106. megadetector/utils/azure_utils.py +22 -22
  107. megadetector/utils/ct_utils.py +1018 -200
  108. megadetector/utils/directory_listing.py +21 -77
  109. megadetector/utils/gpu_test.py +22 -22
  110. megadetector/utils/md_tests.py +541 -518
  111. megadetector/utils/path_utils.py +1457 -398
  112. megadetector/utils/process_utils.py +41 -41
  113. megadetector/utils/sas_blob_utils.py +53 -49
  114. megadetector/utils/split_locations_into_train_val.py +61 -61
  115. megadetector/utils/string_utils.py +147 -26
  116. megadetector/utils/url_utils.py +463 -173
  117. megadetector/utils/wi_utils.py +2629 -2526
  118. megadetector/utils/write_html_image_list.py +137 -137
  119. megadetector/visualization/plot_utils.py +21 -21
  120. megadetector/visualization/render_images_with_thumbnails.py +37 -73
  121. megadetector/visualization/visualization_utils.py +401 -397
  122. megadetector/visualization/visualize_db.py +197 -190
  123. megadetector/visualization/visualize_detector_output.py +79 -73
  124. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/METADATA +135 -132
  125. megadetector-5.0.29.dist-info/RECORD +163 -0
  126. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/WHEEL +1 -1
  127. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/licenses/LICENSE +0 -0
  128. {megadetector-5.0.28.dist-info → megadetector-5.0.29.dist-info}/top_level.txt +0 -0
  129. megadetector/data_management/importers/add_nacti_sizes.py +0 -52
  130. megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
  131. megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
  132. megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
  133. megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
  134. megadetector/data_management/importers/awc_to_json.py +0 -191
  135. megadetector/data_management/importers/bellevue_to_json.py +0 -272
  136. megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
  137. megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
  138. megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
  139. megadetector/data_management/importers/cct_field_adjustments.py +0 -58
  140. megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
  141. megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  142. megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
  143. megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
  144. megadetector/data_management/importers/ena24_to_json.py +0 -276
  145. megadetector/data_management/importers/filenames_to_json.py +0 -386
  146. megadetector/data_management/importers/helena_to_cct.py +0 -283
  147. megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
  148. megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  149. megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
  150. megadetector/data_management/importers/jb_csv_to_json.py +0 -150
  151. megadetector/data_management/importers/mcgill_to_json.py +0 -250
  152. megadetector/data_management/importers/missouri_to_json.py +0 -490
  153. megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
  154. megadetector/data_management/importers/noaa_seals_2019.py +0 -181
  155. megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
  156. megadetector/data_management/importers/pc_to_json.py +0 -365
  157. megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
  158. megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
  159. megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
  160. megadetector/data_management/importers/rspb_to_json.py +0 -356
  161. megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
  162. megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
  163. megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
  164. megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
  165. megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  166. megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  167. megadetector/data_management/importers/sulross_get_exif.py +0 -65
  168. megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
  169. megadetector/data_management/importers/ubc_to_json.py +0 -399
  170. megadetector/data_management/importers/umn_to_json.py +0 -507
  171. megadetector/data_management/importers/wellington_to_json.py +0 -263
  172. megadetector/data_management/importers/wi_to_json.py +0 -442
  173. megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
  174. megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
  175. megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
  176. megadetector-5.0.28.dist-info/RECORD +0 -209
@@ -1,4 +1,4 @@
1
- """
1
+ r"""
2
2
 
3
3
  save_mislabeled.py
4
4
 
@@ -10,7 +10,7 @@ List of known mislabeled images is stored in Azure Blob Storage.
10
10
  * blob: megadb_mislabeled/{dataset}.csv, one file per dataset
11
11
 
12
12
  Each file megadb_mislabeled/{dataset}.csv has two columns:
13
-
13
+
14
14
  * 'file': str, blob name
15
15
 
16
16
  * 'correct_class': optional str, correct dataset class
@@ -41,7 +41,7 @@ import pandas as pd
41
41
  #%% Main function
42
42
 
43
43
  def update_mislabeled_images(container_path: str, input_csv_path: str) -> None:
44
-
44
+
45
45
  df = pd.read_csv(input_csv_path, index_col=False)
46
46
 
47
47
  # error checking
@@ -62,7 +62,7 @@ def update_mislabeled_images(container_path: str, input_csv_path: str) -> None:
62
62
  df['file'] = df['blob_dirname'] + '/' + df['File']
63
63
 
64
64
  for ds, ds_df in df.groupby('dataset'):
65
-
65
+
66
66
  sr_path = os.path.join(container_path, 'megadb_mislabeled', f'{ds}.csv')
67
67
  if os.path.exists(sr_path):
68
68
  old_sr = pd.read_csv(sr_path, index_col='file', squeeze=True)
@@ -89,7 +89,7 @@ def update_mislabeled_images(container_path: str, input_csv_path: str) -> None:
89
89
  #%% Command-line driver
90
90
 
91
91
  def _parse_args() -> argparse.Namespace:
92
-
92
+
93
93
  parser = argparse.ArgumentParser(
94
94
  formatter_class=argparse.ArgumentDefaultsHelpFormatter,
95
95
  description='Merges classification results with Batch Detection API '
@@ -104,7 +104,7 @@ def _parse_args() -> argparse.Namespace:
104
104
 
105
105
 
106
106
  if __name__ == '__main__':
107
-
107
+
108
108
  args = _parse_args()
109
109
  update_mislabeled_images(container_path=args.container_path,
110
110
  input_csv_path=args.input_csv)
@@ -44,7 +44,7 @@ from megadetector.visualization import plot_utils
44
44
 
45
45
  #%% Example usage
46
46
 
47
- """
47
+ """
48
48
  python train_classifier.py run_idfg /ssd/crops_sq \
49
49
  -m "efficientnet-b0" --pretrained --finetune --label-weighted \
50
50
  --epochs 50 --batch-size 512 --lr 1e-4 \
@@ -54,7 +54,7 @@ EFFICIENTNET_MODELS: Mapping[str, Mapping[str, Any]] = {
54
54
 
55
55
  #%% Example usage
56
56
 
57
- """
57
+ """
58
58
  python train_classifier_tf.py run_idfg /ssd/crops_sq \
59
59
  -m "efficientnet-b0" --pretrained --finetune --label-weighted \
60
60
  --epochs 50 --batch-size 512 --lr 1e-4 \
@@ -97,7 +97,7 @@ def create_dataset(
97
97
 
98
98
  Returns: tf.data.Dataset
99
99
  """
100
-
100
+
101
101
  # images dataset
102
102
  img_ds = tf.data.Dataset.from_tensor_slices(img_files)
103
103
  img_ds = img_ds.map(lambda p: tf.io.read_file(img_base_dir + os.sep + p),
@@ -162,7 +162,7 @@ def create_dataloaders(
162
162
  datasets: dict, maps split to DataLoader
163
163
  label_names: list of str, label names in order of label id
164
164
  """
165
-
165
+
166
166
  df, label_names, split_to_locs = load_dataset_csv(
167
167
  dataset_csv_path, label_index_json_path, splits_json_path,
168
168
  multilabel=multilabel, label_weighted=label_weighted,
@@ -238,7 +238,7 @@ def build_model(model_name: str, num_classes: int, img_size: int,
238
238
  """
239
239
  Creates a model with an EfficientNet base.
240
240
  """
241
-
241
+
242
242
  class_name = EFFICIENTNET_MODELS[model_name]['cls']
243
243
  dropout = EFFICIENTNET_MODELS[model_name]['dropout']
244
244
 
@@ -279,7 +279,7 @@ def log_images_with_confidence(
279
279
  epoch: int
280
280
  tag: str
281
281
  """
282
-
282
+
283
283
  for label_id, heap in heap_dict.items():
284
284
  label_name = label_names[label_id]
285
285
 
@@ -319,7 +319,7 @@ def track_extreme_examples(tp_heaps: dict[int, list[HeapItem]],
319
319
  img_files: tf.Tensor, shape [batch_size], type tf.string
320
320
  logits: tf.Tensor, shape [batch_size, num_classes]
321
321
  """
322
-
322
+
323
323
  labels = labels.numpy().tolist()
324
324
  inputs = inputs.numpy().astype(np.uint8)
325
325
  img_files = img_files.numpy().astype(str).tolist()
@@ -480,7 +480,7 @@ def log_run(split: str, epoch: int, writer: tf.summary.SummaryWriter,
480
480
  Args:
481
481
  metrics: dict, keys already prefixed with {split}/
482
482
  """
483
-
483
+
484
484
  per_class_recall = recall_from_confusion_matrix(cm, label_names)
485
485
  metrics.update(prefix_all_keys(per_class_recall, f'{split}/label_recall/'))
486
486
 
@@ -518,7 +518,7 @@ def main(dataset_dir: str,
518
518
  seed: Optional[int] = None,
519
519
  logdir: str = '',
520
520
  cache_splits: Sequence[str] = ()) -> None:
521
-
521
+
522
522
  # input validation
523
523
  assert os.path.exists(dataset_dir)
524
524
  assert os.path.exists(cropped_images_dir)
@@ -597,7 +597,7 @@ def main(dataset_dir: str,
597
597
  model.base_model.trainable = True
598
598
 
599
599
  print('- train:')
600
-
600
+
601
601
  train_metrics, train_heaps, train_cm = run_epoch(
602
602
  model, loader=loaders['train'], weighted=label_weighted,
603
603
  loss_fn=loss_fn, weight_decay=weight_decay, optimizer=optimizer,
@@ -35,7 +35,7 @@ class HeapItem:
35
35
  """
36
36
  A wrapper over non-comparable data with a comparable priority value.
37
37
  """
38
-
38
+
39
39
  priority: Any
40
40
  data: Any = dataclasses.field(compare=False, repr=False)
41
41
 
@@ -53,7 +53,7 @@ def add_to_heap(h: list[Any], item: HeapItem, k: Optional[int] = None) -> None:
53
53
  item: HeapItem
54
54
  k: int, desired capacity of the heap, or None for no limit
55
55
  """
56
-
56
+
57
57
  if k is None or len(h) < k:
58
58
  heapq.heappush(h, item)
59
59
  else:
@@ -66,17 +66,17 @@ def prefix_all_keys(d: Mapping[str, Any], prefix: str) -> dict[str, Any]:
66
66
  """
67
67
  Returns a new dict where the keys are prefixed by <prefix>.
68
68
  """
69
-
69
+
70
70
  return {f'{prefix}{k}': v for k, v in d.items()}
71
71
 
72
72
 
73
73
  def fig_to_img(fig: matplotlib.figure.Figure) -> np.ndarray:
74
74
  """
75
75
  Converts a matplotlib figure to an image represented by a numpy array.
76
-
76
+
77
77
  Returns: np.ndarray, type uint8, shape [H, W, 3]
78
78
  """
79
-
79
+
80
80
  with io.BytesIO() as b:
81
81
  fig.savefig(b, transparent=False, bbox_inches='tight', pad_inches=0,
82
82
  format='png')
@@ -103,7 +103,7 @@ def imgs_with_confidences(imgs_list: list[tuple[Any, ...]],
103
103
  fig: matplotlib.figure.Figure
104
104
  img_files: list of str
105
105
  """
106
-
106
+
107
107
  imgs, img_files, tags, titles = [], [], [], []
108
108
  for img, label_id, topk_conf, topk_preds, img_file in imgs_list:
109
109
  imgs.append(img)
@@ -140,7 +140,7 @@ def plot_img_grid(imgs: Sequence[Any], row_h: float, col_w: float,
140
140
 
141
141
  Returns: matplotlib.figure.Figure
142
142
  """
143
-
143
+
144
144
  # input validation
145
145
  num_images = len(imgs)
146
146
  if tags is not None:
@@ -186,7 +186,7 @@ def load_splits(splits_json_path: str) -> dict[str, set[tuple[str, str]]]:
186
186
 
187
187
  Returns: dict, maps split to set of (dataset, location) tuples
188
188
  """
189
-
189
+
190
190
  with open(splits_json_path, 'r') as f:
191
191
  split_to_locs_js = json.load(f)
192
192
  split_to_locs = {
@@ -235,7 +235,7 @@ def load_dataset_csv(dataset_csv_path: str,
235
235
  label_names: list of str, label names in order of label id
236
236
  split_to_locs: dict, maps split to set of (dataset, location) tuples
237
237
  """
238
-
238
+
239
239
  # read in dataset CSV and create merged (dataset, location) col
240
240
  df = pd.read_csv(dataset_csv_path, index_col=False, float_precision='high')
241
241
  df['dataset_location'] = list(zip(df['dataset'], df['location']))
@@ -315,7 +315,7 @@ def recall_from_confusion_matrix(
315
315
 
316
316
  Returns: dict, label_name => recall
317
317
  """
318
-
318
+
319
319
  result = {
320
320
  label_name: confusion_matrix[i, i] / (confusion_matrix[i].sum() + 1e-8)
321
321
  for i, label_name in enumerate(label_names)
@@ -4,7 +4,7 @@ annotation_constants.py
4
4
 
5
5
  Defines default categories for MegaDetector output boxes.
6
6
 
7
- Used throughout the repo; do not change unless you are Dan or Siyu. In fact, do not change unless
7
+ Used throughout the repo; do not change unless you are Dan or Siyu. In fact, do not change unless
8
8
  you are both Dan *and* Siyu.
9
9
 
10
10
  We use integer IDs here; this is different from the MD .json file format,
@@ -31,22 +31,22 @@ from collections import defaultdict
31
31
  def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
32
32
  """
33
33
  Convert the Camtrap DP package in [camtrap_dp_folder] to COCO.
34
-
34
+
35
35
  Does not validate images, just converts. Use integrity_check_json_db to validate
36
- the resulting COCO file.
37
-
36
+ the resulting COCO file.
37
+
38
38
  Optionally writes the results to [output_file]
39
39
  """
40
-
40
+
41
41
  required_files = ('datapackage.json','deployments.csv','events.csv','media.csv','observations.csv')
42
-
42
+
43
43
  for fn in required_files:
44
44
  fn_abs = os.path.join(camtrap_dp_folder,fn)
45
45
  assert os.path.isfile(fn_abs), 'Could not find required file {}'.format(fn_abs)
46
-
46
+
47
47
  with open(os.path.join(camtrap_dp_folder,'datapackage.json'),'r') as f:
48
48
  datapackage = json.load(f)
49
-
49
+
50
50
  assert datapackage['profile'] == 'https://raw.githubusercontent.com/tdwg/camtrap-dp/1.0/camtrap-dp-profile.json', \
51
51
  'I only know how to parse Camtrap DP 1.0 packages'
52
52
 
@@ -54,7 +54,7 @@ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
54
54
  events_file = None
55
55
  media_file = None
56
56
  observations_file = None
57
-
57
+
58
58
  resources = datapackage['resources']
59
59
  for r in resources:
60
60
  if r['name'] == 'deployments':
@@ -70,19 +70,19 @@ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
70
70
  assert events_file is not None, 'No events file specified'
71
71
  assert media_file is not None, 'No media file specified'
72
72
  assert observations_file is not None, 'No observation file specified'
73
-
73
+
74
74
  deployments_df = pd.read_csv(os.path.join(camtrap_dp_folder,deployments_file))
75
75
  events_df = pd.read_csv(os.path.join(camtrap_dp_folder,events_file))
76
76
  media_df = pd.read_csv(os.path.join(camtrap_dp_folder,media_file))
77
77
  observations_df = pd.read_csv(os.path.join(camtrap_dp_folder,observations_file))
78
-
78
+
79
79
  print('Read {} deployment lines'.format(len(deployments_df)))
80
80
  print('Read {} events lines'.format(len(events_df)))
81
81
  print('Read {} media lines'.format(len(media_df)))
82
82
  print('Read {} observation lines'.format(len(observations_df)))
83
-
83
+
84
84
  media_id_to_media_info = {}
85
-
85
+
86
86
  # i_row = 0; row = media_df.iloc[i_row]
87
87
  for i_row,row in media_df.iterrows():
88
88
  media_info = {}
@@ -94,23 +94,23 @@ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
94
94
  media_info['frame_num'] = -1
95
95
  media_info['seq_num_frames'] = -1
96
96
  media_id_to_media_info[row['mediaID']] = media_info
97
-
97
+
98
98
  event_id_to_media_ids = defaultdict(list)
99
-
99
+
100
100
  # i_row = 0; row = events_df.iloc[i_row]
101
101
  for i_row,row in events_df.iterrows():
102
102
  media_id = row['mediaID']
103
103
  assert media_id in media_id_to_media_info
104
104
  event_id_to_media_ids[row['eventID']].append(media_id)
105
-
105
+
106
106
  event_id_to_category_names = defaultdict(set)
107
-
107
+
108
108
  # i_row = 0; row = observations_df.iloc[i_row]
109
109
  for i_row,row in observations_df.iterrows():
110
-
110
+
111
111
  if row['observationLevel'] != 'event':
112
112
  raise ValueError("I don't know how to parse image-level events yet")
113
-
113
+
114
114
  if row['observationType'] == 'blank':
115
115
  event_id_to_category_names[row['eventID']].add('empty')
116
116
  elif row['observationType'] == 'unknown':
@@ -122,7 +122,7 @@ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
122
122
  assert row['observationType'] == 'animal'
123
123
  assert isinstance(row['scientificName'],str)
124
124
  event_id_to_category_names[row['eventID']].add(row['scientificName'])
125
-
125
+
126
126
  # Sort images within an event into frame numbers
127
127
  #
128
128
  # event_id = next(iter(event_id_to_media_ids))
@@ -134,7 +134,7 @@ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
134
134
  media_info['frame_num'] = i_media
135
135
  media_info['seq_num_frames'] = len(media_info_this_event)
136
136
  media_info['seq_id'] = event_id
137
-
137
+
138
138
  # Create category names
139
139
  category_name_to_category_id = {'empty':0}
140
140
  for event_id in event_id_to_category_names:
@@ -142,18 +142,18 @@ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
142
142
  for name in category_names_this_event:
143
143
  if name not in category_name_to_category_id:
144
144
  category_name_to_category_id[name] = len(category_name_to_category_id)
145
-
145
+
146
146
  # Move everything into COCO format
147
147
  images = list(media_id_to_media_info.values())
148
-
148
+
149
149
  categories = []
150
150
  for name in category_name_to_category_id:
151
151
  categories.append({'name':name,'id':category_name_to_category_id[name]})
152
152
  info = {'version':1.0,'description':datapackage['name']}
153
-
153
+
154
154
  # Create annotations
155
155
  annotations = []
156
-
156
+
157
157
  for event_id in event_id_to_media_ids.keys():
158
158
  i_ann = 0
159
159
  media_ids_this_event = event_id_to_media_ids[event_id]
@@ -168,23 +168,23 @@ def camtrap_dp_to_coco(camtrap_dp_folder,output_file=None):
168
168
  ann['category_id'] = category_name_to_category_id[category_name]
169
169
  ann['sequence_level_annotation'] = True
170
170
  annotations.append(ann)
171
-
171
+
172
172
  coco_data = {}
173
173
  coco_data['images'] = images
174
174
  coco_data['annotations'] = annotations
175
175
  coco_data['categories'] = categories
176
176
  coco_data['info'] = info
177
-
177
+
178
178
  for im in coco_data['images']:
179
179
  im['datetime'] = str(im['datetime'] )
180
-
180
+
181
181
  if output_file is not None:
182
182
  with open(output_file,'w') as f:
183
183
  json.dump(coco_data,f,indent=1)
184
-
184
+
185
185
  return coco_data
186
-
187
-
186
+
187
+
188
188
  #%% Interactive driver
189
189
 
190
190
  if False:
@@ -192,19 +192,19 @@ if False:
192
192
  pass
193
193
 
194
194
  #%%
195
-
195
+
196
196
  camtrap_dp_folder = r'C:\temp\pilot2\pilot2'
197
197
  coco_file = os.path.join(camtrap_dp_folder,'test-coco.json')
198
198
  coco_data = camtrap_dp_to_coco(camtrap_dp_folder,
199
199
  output_file=coco_file)
200
-
200
+
201
201
  #%% Validate
202
-
202
+
203
203
  from megadetector.data_management.databases.integrity_check_json_db import \
204
204
  integrity_check_json_db, IntegrityCheckOptions
205
-
205
+
206
206
  options = IntegrityCheckOptions()
207
-
207
+
208
208
  options.baseDir = camtrap_dp_folder
209
209
  options.bCheckImageSizes = False
210
210
  options.bCheckImageExistence = True
@@ -213,25 +213,25 @@ if False:
213
213
  options.iMaxNumImages = -1
214
214
  options.nThreads = 1
215
215
  options.verbose = True
216
-
217
- sortedCategories, data, errorInfo = integrity_check_json_db(coco_file,options)
216
+
217
+ sorted_categories, data, error_info = integrity_check_json_db(coco_file,options)
218
218
 
219
219
  #%% Preview
220
-
220
+
221
221
  from megadetector.visualization.visualize_db import DbVizOptions, visualize_db
222
-
222
+
223
223
  options = DbVizOptions()
224
224
  options.parallelize_rendering = True
225
225
  options.parallelize_rendering_with_threads = True
226
226
  options.parallelize_rendering_n_cores = 10
227
-
227
+
228
228
  preview_dir = r'c:\temp\camtrapdp-preview'
229
- htmlOutputFile,image_db = visualize_db(coco_file, preview_dir, camtrap_dp_folder, options=options)
230
-
229
+ html_output_file, image_db = visualize_db(coco_file, preview_dir, camtrap_dp_folder, options=options)
230
+
231
231
  from megadetector.utils.path_utils import open_file
232
- open_file(htmlOutputFile)
233
-
234
-
232
+ open_file(html_output_file)
233
+
234
+
235
235
  #%% Command-line driver
236
236
 
237
237
  # TODO