megadetector 5.0.9__py3-none-any.whl → 5.0.11__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 (226) hide show
  1. {megadetector-5.0.9.dist-info → megadetector-5.0.11.dist-info}/LICENSE +0 -0
  2. {megadetector-5.0.9.dist-info → megadetector-5.0.11.dist-info}/METADATA +12 -11
  3. megadetector-5.0.11.dist-info/RECORD +5 -0
  4. megadetector-5.0.11.dist-info/top_level.txt +1 -0
  5. api/__init__.py +0 -0
  6. api/batch_processing/__init__.py +0 -0
  7. api/batch_processing/api_core/__init__.py +0 -0
  8. api/batch_processing/api_core/batch_service/__init__.py +0 -0
  9. api/batch_processing/api_core/batch_service/score.py +0 -439
  10. api/batch_processing/api_core/server.py +0 -294
  11. api/batch_processing/api_core/server_api_config.py +0 -98
  12. api/batch_processing/api_core/server_app_config.py +0 -55
  13. api/batch_processing/api_core/server_batch_job_manager.py +0 -220
  14. api/batch_processing/api_core/server_job_status_table.py +0 -152
  15. api/batch_processing/api_core/server_orchestration.py +0 -360
  16. api/batch_processing/api_core/server_utils.py +0 -92
  17. api/batch_processing/api_core_support/__init__.py +0 -0
  18. api/batch_processing/api_core_support/aggregate_results_manually.py +0 -46
  19. api/batch_processing/api_support/__init__.py +0 -0
  20. api/batch_processing/api_support/summarize_daily_activity.py +0 -152
  21. api/batch_processing/data_preparation/__init__.py +0 -0
  22. api/batch_processing/data_preparation/manage_local_batch.py +0 -2391
  23. api/batch_processing/data_preparation/manage_video_batch.py +0 -327
  24. api/batch_processing/integration/digiKam/setup.py +0 -6
  25. api/batch_processing/integration/digiKam/xmp_integration.py +0 -465
  26. api/batch_processing/integration/eMammal/test_scripts/config_template.py +0 -5
  27. api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +0 -126
  28. api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +0 -55
  29. api/batch_processing/postprocessing/__init__.py +0 -0
  30. api/batch_processing/postprocessing/add_max_conf.py +0 -64
  31. api/batch_processing/postprocessing/categorize_detections_by_size.py +0 -163
  32. api/batch_processing/postprocessing/combine_api_outputs.py +0 -249
  33. api/batch_processing/postprocessing/compare_batch_results.py +0 -958
  34. api/batch_processing/postprocessing/convert_output_format.py +0 -397
  35. api/batch_processing/postprocessing/load_api_results.py +0 -195
  36. api/batch_processing/postprocessing/md_to_coco.py +0 -310
  37. api/batch_processing/postprocessing/md_to_labelme.py +0 -330
  38. api/batch_processing/postprocessing/merge_detections.py +0 -401
  39. api/batch_processing/postprocessing/postprocess_batch_results.py +0 -1904
  40. api/batch_processing/postprocessing/remap_detection_categories.py +0 -170
  41. api/batch_processing/postprocessing/render_detection_confusion_matrix.py +0 -661
  42. api/batch_processing/postprocessing/repeat_detection_elimination/find_repeat_detections.py +0 -211
  43. api/batch_processing/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +0 -82
  44. api/batch_processing/postprocessing/repeat_detection_elimination/repeat_detections_core.py +0 -1631
  45. api/batch_processing/postprocessing/separate_detections_into_folders.py +0 -731
  46. api/batch_processing/postprocessing/subset_json_detector_output.py +0 -696
  47. api/batch_processing/postprocessing/top_folders_to_bottom.py +0 -223
  48. api/synchronous/__init__.py +0 -0
  49. api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
  50. api/synchronous/api_core/animal_detection_api/api_backend.py +0 -152
  51. api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -266
  52. api/synchronous/api_core/animal_detection_api/config.py +0 -35
  53. api/synchronous/api_core/animal_detection_api/data_management/annotations/annotation_constants.py +0 -47
  54. api/synchronous/api_core/animal_detection_api/detection/detector_training/copy_checkpoints.py +0 -43
  55. api/synchronous/api_core/animal_detection_api/detection/detector_training/model_main_tf2.py +0 -114
  56. api/synchronous/api_core/animal_detection_api/detection/process_video.py +0 -543
  57. api/synchronous/api_core/animal_detection_api/detection/pytorch_detector.py +0 -304
  58. api/synchronous/api_core/animal_detection_api/detection/run_detector.py +0 -627
  59. api/synchronous/api_core/animal_detection_api/detection/run_detector_batch.py +0 -1029
  60. api/synchronous/api_core/animal_detection_api/detection/run_inference_with_yolov5_val.py +0 -581
  61. api/synchronous/api_core/animal_detection_api/detection/run_tiled_inference.py +0 -754
  62. api/synchronous/api_core/animal_detection_api/detection/tf_detector.py +0 -165
  63. api/synchronous/api_core/animal_detection_api/detection/video_utils.py +0 -495
  64. api/synchronous/api_core/animal_detection_api/md_utils/azure_utils.py +0 -174
  65. api/synchronous/api_core/animal_detection_api/md_utils/ct_utils.py +0 -262
  66. api/synchronous/api_core/animal_detection_api/md_utils/directory_listing.py +0 -251
  67. api/synchronous/api_core/animal_detection_api/md_utils/matlab_porting_tools.py +0 -97
  68. api/synchronous/api_core/animal_detection_api/md_utils/path_utils.py +0 -416
  69. api/synchronous/api_core/animal_detection_api/md_utils/process_utils.py +0 -110
  70. api/synchronous/api_core/animal_detection_api/md_utils/sas_blob_utils.py +0 -509
  71. api/synchronous/api_core/animal_detection_api/md_utils/string_utils.py +0 -59
  72. api/synchronous/api_core/animal_detection_api/md_utils/url_utils.py +0 -144
  73. api/synchronous/api_core/animal_detection_api/md_utils/write_html_image_list.py +0 -226
  74. api/synchronous/api_core/animal_detection_api/md_visualization/visualization_utils.py +0 -841
  75. api/synchronous/api_core/tests/__init__.py +0 -0
  76. api/synchronous/api_core/tests/load_test.py +0 -110
  77. classification/__init__.py +0 -0
  78. classification/aggregate_classifier_probs.py +0 -108
  79. classification/analyze_failed_images.py +0 -227
  80. classification/cache_batchapi_outputs.py +0 -198
  81. classification/create_classification_dataset.py +0 -627
  82. classification/crop_detections.py +0 -516
  83. classification/csv_to_json.py +0 -226
  84. classification/detect_and_crop.py +0 -855
  85. classification/efficientnet/__init__.py +0 -9
  86. classification/efficientnet/model.py +0 -415
  87. classification/efficientnet/utils.py +0 -610
  88. classification/evaluate_model.py +0 -520
  89. classification/identify_mislabeled_candidates.py +0 -152
  90. classification/json_to_azcopy_list.py +0 -63
  91. classification/json_validator.py +0 -695
  92. classification/map_classification_categories.py +0 -276
  93. classification/merge_classification_detection_output.py +0 -506
  94. classification/prepare_classification_script.py +0 -194
  95. classification/prepare_classification_script_mc.py +0 -228
  96. classification/run_classifier.py +0 -286
  97. classification/save_mislabeled.py +0 -110
  98. classification/train_classifier.py +0 -825
  99. classification/train_classifier_tf.py +0 -724
  100. classification/train_utils.py +0 -322
  101. data_management/__init__.py +0 -0
  102. data_management/annotations/__init__.py +0 -0
  103. data_management/annotations/annotation_constants.py +0 -34
  104. data_management/camtrap_dp_to_coco.py +0 -238
  105. data_management/cct_json_utils.py +0 -395
  106. data_management/cct_to_md.py +0 -176
  107. data_management/cct_to_wi.py +0 -289
  108. data_management/coco_to_labelme.py +0 -272
  109. data_management/coco_to_yolo.py +0 -662
  110. data_management/databases/__init__.py +0 -0
  111. data_management/databases/add_width_and_height_to_db.py +0 -33
  112. data_management/databases/combine_coco_camera_traps_files.py +0 -206
  113. data_management/databases/integrity_check_json_db.py +0 -477
  114. data_management/databases/subset_json_db.py +0 -115
  115. data_management/generate_crops_from_cct.py +0 -149
  116. data_management/get_image_sizes.py +0 -188
  117. data_management/importers/add_nacti_sizes.py +0 -52
  118. data_management/importers/add_timestamps_to_icct.py +0 -79
  119. data_management/importers/animl_results_to_md_results.py +0 -158
  120. data_management/importers/auckland_doc_test_to_json.py +0 -372
  121. data_management/importers/auckland_doc_to_json.py +0 -200
  122. data_management/importers/awc_to_json.py +0 -189
  123. data_management/importers/bellevue_to_json.py +0 -273
  124. data_management/importers/cacophony-thermal-importer.py +0 -796
  125. data_management/importers/carrizo_shrubfree_2018.py +0 -268
  126. data_management/importers/carrizo_trail_cam_2017.py +0 -287
  127. data_management/importers/cct_field_adjustments.py +0 -57
  128. data_management/importers/channel_islands_to_cct.py +0 -913
  129. data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  130. data_management/importers/eMammal/eMammal_helpers.py +0 -249
  131. data_management/importers/eMammal/make_eMammal_json.py +0 -223
  132. data_management/importers/ena24_to_json.py +0 -275
  133. data_management/importers/filenames_to_json.py +0 -385
  134. data_management/importers/helena_to_cct.py +0 -282
  135. data_management/importers/idaho-camera-traps.py +0 -1407
  136. data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  137. data_management/importers/jb_csv_to_json.py +0 -150
  138. data_management/importers/mcgill_to_json.py +0 -250
  139. data_management/importers/missouri_to_json.py +0 -489
  140. data_management/importers/nacti_fieldname_adjustments.py +0 -79
  141. data_management/importers/noaa_seals_2019.py +0 -181
  142. data_management/importers/pc_to_json.py +0 -365
  143. data_management/importers/plot_wni_giraffes.py +0 -123
  144. data_management/importers/prepare-noaa-fish-data-for-lila.py +0 -359
  145. data_management/importers/prepare_zsl_imerit.py +0 -131
  146. data_management/importers/rspb_to_json.py +0 -356
  147. data_management/importers/save_the_elephants_survey_A.py +0 -320
  148. data_management/importers/save_the_elephants_survey_B.py +0 -332
  149. data_management/importers/snapshot_safari_importer.py +0 -758
  150. data_management/importers/snapshot_safari_importer_reprise.py +0 -665
  151. data_management/importers/snapshot_serengeti_lila.py +0 -1067
  152. data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  153. data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  154. data_management/importers/sulross_get_exif.py +0 -65
  155. data_management/importers/timelapse_csv_set_to_json.py +0 -490
  156. data_management/importers/ubc_to_json.py +0 -399
  157. data_management/importers/umn_to_json.py +0 -507
  158. data_management/importers/wellington_to_json.py +0 -263
  159. data_management/importers/wi_to_json.py +0 -441
  160. data_management/importers/zamba_results_to_md_results.py +0 -181
  161. data_management/labelme_to_coco.py +0 -548
  162. data_management/labelme_to_yolo.py +0 -272
  163. data_management/lila/__init__.py +0 -0
  164. data_management/lila/add_locations_to_island_camera_traps.py +0 -97
  165. data_management/lila/add_locations_to_nacti.py +0 -147
  166. data_management/lila/create_lila_blank_set.py +0 -557
  167. data_management/lila/create_lila_test_set.py +0 -151
  168. data_management/lila/create_links_to_md_results_files.py +0 -106
  169. data_management/lila/download_lila_subset.py +0 -177
  170. data_management/lila/generate_lila_per_image_labels.py +0 -515
  171. data_management/lila/get_lila_annotation_counts.py +0 -170
  172. data_management/lila/get_lila_image_counts.py +0 -111
  173. data_management/lila/lila_common.py +0 -300
  174. data_management/lila/test_lila_metadata_urls.py +0 -132
  175. data_management/ocr_tools.py +0 -874
  176. data_management/read_exif.py +0 -681
  177. data_management/remap_coco_categories.py +0 -84
  178. data_management/remove_exif.py +0 -66
  179. data_management/resize_coco_dataset.py +0 -189
  180. data_management/wi_download_csv_to_coco.py +0 -246
  181. data_management/yolo_output_to_md_output.py +0 -441
  182. data_management/yolo_to_coco.py +0 -676
  183. detection/__init__.py +0 -0
  184. detection/detector_training/__init__.py +0 -0
  185. detection/detector_training/model_main_tf2.py +0 -114
  186. detection/process_video.py +0 -703
  187. detection/pytorch_detector.py +0 -337
  188. detection/run_detector.py +0 -779
  189. detection/run_detector_batch.py +0 -1219
  190. detection/run_inference_with_yolov5_val.py +0 -917
  191. detection/run_tiled_inference.py +0 -935
  192. detection/tf_detector.py +0 -188
  193. detection/video_utils.py +0 -606
  194. docs/source/conf.py +0 -43
  195. md_utils/__init__.py +0 -0
  196. md_utils/azure_utils.py +0 -174
  197. md_utils/ct_utils.py +0 -612
  198. md_utils/directory_listing.py +0 -246
  199. md_utils/md_tests.py +0 -968
  200. md_utils/path_utils.py +0 -1044
  201. md_utils/process_utils.py +0 -157
  202. md_utils/sas_blob_utils.py +0 -509
  203. md_utils/split_locations_into_train_val.py +0 -228
  204. md_utils/string_utils.py +0 -92
  205. md_utils/url_utils.py +0 -323
  206. md_utils/write_html_image_list.py +0 -225
  207. md_visualization/__init__.py +0 -0
  208. md_visualization/plot_utils.py +0 -293
  209. md_visualization/render_images_with_thumbnails.py +0 -275
  210. md_visualization/visualization_utils.py +0 -1537
  211. md_visualization/visualize_db.py +0 -551
  212. md_visualization/visualize_detector_output.py +0 -406
  213. megadetector-5.0.9.dist-info/RECORD +0 -224
  214. megadetector-5.0.9.dist-info/top_level.txt +0 -8
  215. taxonomy_mapping/__init__.py +0 -0
  216. taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +0 -491
  217. taxonomy_mapping/map_new_lila_datasets.py +0 -154
  218. taxonomy_mapping/prepare_lila_taxonomy_release.py +0 -142
  219. taxonomy_mapping/preview_lila_taxonomy.py +0 -591
  220. taxonomy_mapping/retrieve_sample_image.py +0 -71
  221. taxonomy_mapping/simple_image_download.py +0 -218
  222. taxonomy_mapping/species_lookup.py +0 -834
  223. taxonomy_mapping/taxonomy_csv_checker.py +0 -159
  224. taxonomy_mapping/taxonomy_graph.py +0 -346
  225. taxonomy_mapping/validate_lila_category_mappings.py +0 -83
  226. {megadetector-5.0.9.dist-info → megadetector-5.0.11.dist-info}/WHEEL +0 -0
@@ -1,158 +0,0 @@
1
- """
2
-
3
- animl_results_to_md_results.py
4
-
5
- Convert a .csv file produced by the Animl package:
6
-
7
- https://github.com/conservationtechlab/animl-py
8
-
9
- ...to a MD results file suitable for import into Timelapse.
10
-
11
- Columns are expected to be:
12
-
13
- file
14
- category (MD category identifies: 1==animal, 2==person, 3==vehicle)
15
- detection_conf
16
- bbox1,bbox2,bbox3,bbox4
17
- class
18
- classification_conf
19
-
20
- """
21
-
22
- #%% Imports and constants
23
-
24
- import pandas as pd
25
- import json
26
-
27
- # It's a little icky to hard-code this here rather than importing from elsewhere
28
- # in the MD repo, but it seemed silly to take a dependency on lots of MD code
29
- # just for this, so, hard-coding.
30
- detection_category_id_to_name = {'1':'animal','2':'person','3':'vehicle'}
31
-
32
-
33
- #%% Main function
34
-
35
- def animl_results_to_md_results(input_file,output_file=None):
36
- """
37
- Converts the .csv file [input_file] to the MD-formatted .json file [output_file].
38
-
39
- If [output_file] is None, '.json' will be appended to the input file.
40
- """
41
-
42
- if output_file is None:
43
- output_file = input_file + '.json'
44
-
45
- df = pd.read_csv(input_file)
46
-
47
- expected_columns = ('file','category','detection_conf',
48
- 'bbox1','bbox2','bbox3','bbox4','class','classification_conf')
49
-
50
- for s in expected_columns:
51
- assert s in df.columns,\
52
- 'Expected column {} not found'.format(s)
53
-
54
- classification_category_name_to_id = {}
55
- filename_to_results = {}
56
-
57
- # i_row = 0; row = df.iloc[i_row]
58
- for i_row,row in df.iterrows():
59
-
60
- # Is this the first detection we've seen for this file?
61
- if row['file'] in filename_to_results:
62
- im = filename_to_results[row['file']]
63
- else:
64
- im = {}
65
- im['detections'] = []
66
- im['file'] = row['file']
67
- filename_to_results[im['file']] = im
68
-
69
- assert isinstance(row['category'],int),'Invalid category identifier in row {}'.format(im['file'])
70
- detection_category_id = str(row['category'])
71
- assert detection_category_id in detection_category_id_to_name,\
72
- 'Unrecognized detection category ID {}'.format(detection_category_id)
73
-
74
- detection = {}
75
- detection['category'] = detection_category_id
76
- detection['conf'] = row['detection_conf']
77
- bbox = [row['bbox1'],row['bbox2'],row['bbox3'],row['bbox4']]
78
- detection['bbox'] = bbox
79
- classification_category_name = row['class']
80
-
81
- # Have we seen this classification category before?
82
- if classification_category_name in classification_category_name_to_id:
83
- classification_category_id = \
84
- classification_category_name_to_id[classification_category_name]
85
- else:
86
- classification_category_id = str(len(classification_category_name_to_id))
87
- classification_category_name_to_id[classification_category_name] = \
88
- classification_category_id
89
-
90
- classifications = [[classification_category_id,row['classification_conf']]]
91
- detection['classifications'] = classifications
92
-
93
- im['detections'].append(detection)
94
-
95
- # ...for each row
96
-
97
- info = {}
98
- info['format_version'] = '1.3'
99
- info['detector'] = 'Animl'
100
- info['classifier'] = 'Animl'
101
-
102
- results = {}
103
- results['info'] = info
104
- results['detection_categories'] = detection_category_id_to_name
105
- results['classification_categories'] = \
106
- {v: k for k, v in classification_category_name_to_id.items()}
107
- results['images'] = list(filename_to_results.values())
108
-
109
- with open(output_file,'w') as f:
110
- json.dump(results,f,indent=1)
111
-
112
- # ...animl_results_to_md_results(...)
113
-
114
-
115
- #%% Interactive driver
116
-
117
- if False:
118
-
119
- pass
120
-
121
- #%%
122
-
123
- input_file = r"G:\temp\animl-runs\animl-runs\Coati_v2\manifest.csv"
124
- output_file = None
125
- animl_results_to_md_results(input_file,output_file)
126
-
127
-
128
- #%% Command-line driver
129
-
130
- import sys,argparse
131
-
132
- def main():
133
-
134
- parser = argparse.ArgumentParser(
135
- description='Convert an Animl-formatted .csv results file to MD-formatted .json results file')
136
-
137
- parser.add_argument(
138
- 'input_file',
139
- type=str,
140
- help='input .csv file')
141
-
142
- parser.add_argument(
143
- '--output_file',
144
- type=str,
145
- default=None,
146
- help='output .json file (defaults to input file appended with ".json")')
147
-
148
- if len(sys.argv[1:]) == 0:
149
- parser.print_help()
150
- parser.exit()
151
-
152
- args = parser.parse_args()
153
-
154
- animl_results_to_md_results(args.input_file,args.output_file)
155
-
156
- if __name__ == '__main__':
157
- main()
158
-
@@ -1,372 +0,0 @@
1
- """
2
-
3
- auckland_doc_test_to_json.py
4
-
5
- Convert Auckland DOC data set to COCO camera traps format. This was
6
- for a testing data set where a .csv file was provided with class
7
- information.
8
-
9
- """
10
-
11
- #%% Constants and imports
12
-
13
- import json
14
- import os
15
- import uuid
16
- import pandas as pd
17
- import datetime
18
- import ntpath
19
- import re
20
- import numpy as np
21
- from tqdm import tqdm
22
-
23
- from md_visualization import visualize_db
24
- from data_management.databases import integrity_check_json_db
25
- from md_utils.path_utils import find_images
26
-
27
- input_base_dir = r'e:\auckland-test\2_Testing'
28
-
29
- input_metadata_file = r'G:\auckland-doc\Maukahuka - Auckland Island - Cat camera data Master April 2019 - DOC-5924483.xlsx'
30
-
31
- # Filenames will be stored in the output .json relative to this base dir
32
- output_base_dir = r'g:\auckland-doc'
33
- output_json_filename = os.path.join(output_base_dir, 'auckland-doc-test.json')
34
-
35
- assert os.path.isdir(input_base_dir)
36
- os.makedirs(output_base_dir,exist_ok=True)
37
-
38
- output_encoding = 'utf-8'
39
- read_image_sizes = True
40
-
41
- info = {}
42
- info['year'] = 2020
43
- info['version'] = '1.0'
44
- info['description'] = 'Auckaland DOC Camera Traps (test)'
45
- info['contributor'] = 'Auckland DOC'
46
- info['date_created'] = str(datetime.date.today())
47
-
48
-
49
- #%% Enumerate files
50
-
51
- print('Enumerating files from {}'.format(input_base_dir))
52
- absolute_image_paths = find_images(input_base_dir, recursive=True)
53
- print('Enumerated {} images'.format(len(absolute_image_paths)))
54
-
55
- relative_image_paths = []
56
- for fn in absolute_image_paths:
57
- relative_image_paths.append(os.path.relpath(fn,input_base_dir).replace('\\','/'))
58
-
59
- relative_image_paths_set = set(relative_image_paths)
60
-
61
- assert len(relative_image_paths_set) == len(relative_image_paths)
62
-
63
-
64
- #%% Create unique identifier for each image
65
-
66
- # The ground truth doesn't have full paths in it; create unique identifiers for each image
67
- # based on the camera name and filename.
68
- #
69
- # We store file identifiers as cameraname_filename.
70
- file_identifier_to_relative_paths = {}
71
- camera_names = set()
72
-
73
- # relative_path = relative_image_paths[0]
74
- for relative_path in relative_image_paths:
75
-
76
- # Example relative paths
77
- #
78
- # Summer_Trial_2019/A1_1_42_SD114_20190210/AucklandIsland_A1_1_42_SD114_20190210_01300001.jpg
79
- # Winter_Trial_2019/Installation/10_F4/10_F4_tmp_201908210001.JPG
80
- fn = ntpath.basename(relative_path)
81
-
82
- # Find the camera name
83
- tokens = relative_path.split('/')
84
-
85
- if tokens[1] == 'Installation' or 'Rebait' in tokens[1]:
86
- camera_name = tokens[2]
87
-
88
- else:
89
- # E..g. "A1_1_42_SD114_20190210" in the above example
90
- camera_token = tokens[1]
91
- camera_name = None
92
- m = re.search('^(.+)_SD',camera_token)
93
- if m:
94
- camera_name = m.group(1)
95
- else:
96
- # For camera tokens like C1_5_D_190207
97
- m = re.search('^(.+_.+_.+)',camera_token)
98
- camera_name = m.group(1)
99
-
100
- assert camera_name
101
- camera_names.add(camera_name)
102
-
103
- file_identifier = camera_name + '_' + fn
104
- if file_identifier not in file_identifier_to_relative_paths:
105
- file_identifier_to_relative_paths[file_identifier] = [relative_path]
106
- else:
107
- file_identifier_to_relative_paths[file_identifier].append(relative_path)
108
-
109
- print('Found {} unique camera names'.format(len(camera_names)))
110
-
111
-
112
- #%% Load input data
113
-
114
- input_metadata = pd.read_excel(input_metadata_file)
115
-
116
- print('Read {} columns and {} rows from metadata file'.format(len(input_metadata.columns),
117
- len(input_metadata)))
118
-
119
- # The spreadsheet has a space after "Camera"
120
- input_metadata = input_metadata.rename(columns={'Camera ':'Camera'})
121
-
122
-
123
- #%% Assemble dictionaries
124
-
125
- image_id_to_image = {}
126
- category_name_to_category = {}
127
- annotations = []
128
-
129
- # Force the empty category to be ID 0
130
- empty_category = {}
131
- empty_category['name'] = 'empty'
132
- empty_category['id'] = 0
133
- category_name_to_category['empty'] = empty_category
134
-
135
- rows_not_found_in_folder = []
136
- rows_ambiguous = []
137
- rows_no_filename = []
138
- rows_no_annotation = []
139
-
140
- image_id_to_rows = {}
141
-
142
- next_id = 1
143
-
144
- category_names = ['cat','mouse','unknown','human','pig','sealion','penguin','dog','openadjusted']
145
-
146
- # array([nan, 'Blackbird', 'Bellbird', 'Tomtit', 'Song thrush', 'Pippit',
147
- # 'Pippet', '?', 'Dunnock', 'Song thursh', 'Kakariki', 'Tui', ' ',
148
- # 'Silvereye', 'NZ Pipit', 'Blackbird and Dunnock', 'Unknown',
149
- # 'Pipit', 'Songthrush'], dtype=object)
150
-
151
- def bird_name_to_category_name(bird_name):
152
- bird_name = bird_name.lower().strip().replace(' ','_').replace('song_thursh','song_thrush')
153
- bird_name = bird_name.replace('pippet','pipt').replace('pippit','pipit').replace('nz_pipit','pipit')
154
- if bird_name == '?' or bird_name == '' or bird_name == 'unknown':
155
- category_name = 'unknown_bird'
156
- else:
157
- category_name = bird_name
158
- return category_name
159
-
160
- bird_names = input_metadata.Bird_ID.unique()
161
- for bird_name in bird_names:
162
- if isinstance(bird_name,float):
163
- continue
164
- category_name = bird_name_to_category_name(bird_name)
165
- if category_name not in category_names:
166
- category_names.append(category_name)
167
-
168
- for category_name in category_names:
169
- cat = {}
170
- cat['name'] = category_name
171
- cat['id'] = next_id
172
- next_id = next_id +1
173
- category_name_to_category[category_name] = cat
174
-
175
- def create_annotation(image_id,category_name,count):
176
- assert isinstance(image_id,str)
177
- assert isinstance(category_name,str)
178
- assert isinstance(count,int) or isinstance(count,float)
179
- if isinstance(count,float):
180
- count = int(count)
181
- ann = {}
182
- ann['id'] = str(uuid.uuid1())
183
- ann['image_id'] = image_id
184
- category = category_name_to_category[category_name]
185
- category_id = category['id']
186
- ann['category_id'] = category_id
187
- ann['count'] = count
188
- return ann
189
-
190
- # i_row = 0; row = input_metadata.iloc[i_row]
191
- for i_row,row in tqdm(input_metadata.iterrows(),total=len(input_metadata)):
192
-
193
- # E.g.: AucklandIsland_A1_1_42_SD114_20190210_01300009.jpg
194
- filename = row['File']
195
- if isinstance(filename,float):
196
- rows_no_filename.append(i_row)
197
- continue
198
-
199
- camera_name = row['Camera']
200
- file_identifier = camera_name + '_' + filename
201
- if not file_identifier in file_identifier_to_relative_paths:
202
- rows_not_found_in_folder.append(i_row)
203
- continue
204
-
205
- relative_paths_this_file_id = file_identifier_to_relative_paths[file_identifier]
206
-
207
- if len(relative_paths_this_file_id) == 1:
208
- relative_path = relative_paths_this_file_id[0]
209
- else:
210
-
211
- # We have multiple files matching this identifier, can we uniquely resolve this
212
- # to one of those files based on the camera ID?
213
- matches = [s for s in relative_paths_this_file_id if camera_name in s]
214
- assert len(matches) > 0
215
- if len(matches) > 1:
216
- rows_ambiguous.append(i_row)
217
- continue
218
- relative_path = matches[0]
219
-
220
- assert filename.endswith('.jpg') or filename.endswith('.JPG')
221
- image_id = filename.lower().replace('.jpg','')
222
-
223
- if image_id in image_id_to_rows:
224
- image_id_to_rows[image_id].append(i_row)
225
- continue
226
-
227
- image_id_to_rows[image_id] = [i_row]
228
-
229
- im = {}
230
- im['id'] = image_id
231
- im['file_name'] = relative_path
232
- im['datetime'] = str(row['Date and time'])
233
- im['camera'] = row['Camera']
234
- im['sd_card'] = row['SD_Card']
235
- im['sd_change'] = row['SD_Change']
236
- im['comments'] = row['Comments']
237
-
238
- image_id_to_image[im['id']] = im
239
-
240
- # create_annotation(image_id,category_name,count)
241
-
242
- # 'SD_Change', 'Cat', 'Mouse', 'Bird', 'Bird_ID', 'False_trig', 'Unknown',
243
- # 'Human', 'Collared_cat', 'Cat_ID', 'Pig', 'Sea_lion', 'Open_adjusted',
244
- # 'Penguin', 'Dog', 'Comments', 'Unnamed: 22']
245
-
246
- # Each of these categories is handled a little differently...
247
-
248
- annotations_this_image = []
249
- if (not np.isnan(row['Cat'])):
250
- assert np.isnan(row['Collared_cat'] )
251
- annotations_this_image.append(create_annotation(im['id'],'cat',row['Cat']))
252
-
253
- if (not np.isnan(row['Collared_cat'])):
254
- assert np.isnan(row['Cat'] )
255
- annotations_this_image.append(create_annotation(im['id'],'cat',row['Collared_cat']))
256
-
257
- if (not np.isnan(row['Bird'])):
258
- if isinstance(row['Bird_ID'],str):
259
- category_name = bird_name_to_category_name(row['Bird_ID'])
260
- else:
261
- assert np.isnan(row['Bird_ID'])
262
- category_name = 'unknown_bird'
263
- annotations_this_image.append(create_annotation(im['id'],category_name,row['Bird']))
264
-
265
- if (not np.isnan(row['False_trig'])):
266
- annotations_this_image.append(create_annotation(im['id'],'empty',-1))
267
-
268
- # These are straightforward
269
- for s in ['Mouse','Unknown','Pig','Human','Sea_lion','Penguin','Dog','Open_adjusted']:
270
- if isinstance(row[s],float) or isinstance(row[s],int):
271
- if not np.isnan(row[s]):
272
- annotations_this_image.append(create_annotation(im['id'],s.lower().replace('_',''),row[s]))
273
- elif isinstance(row[s],str):
274
- print('File {}, label {}, value {}'.format(filename,s,row[s]))
275
- else:
276
- raise ValueError('Error handling count value {}'.format(row[s]))
277
-
278
- if len(annotations_this_image) > 1:
279
- print('Multiple annotations for filename {}'.format(filename))
280
-
281
- if len(annotations_this_image) == 0:
282
- rows_no_annotation.append(i_row)
283
-
284
- annotations.extend(annotations_this_image)
285
-
286
- # ...for each image
287
-
288
-
289
- #%% Summarize errors
290
-
291
- print('Of {} rows:\n'.format(len(input_metadata)))
292
-
293
- print('{} images not found in folder'.format(len(rows_not_found_in_folder)))
294
- print('{} images ambiguously mapped'.format(len(rows_ambiguous)))
295
- print('{} images no filename'.format(len(rows_no_filename)))
296
- print('{} images no annotation'.format(len(rows_no_annotation)))
297
- print('{} images handled successfully, {} total annotations'.format(len(image_id_to_image),len(annotations)))
298
-
299
-
300
- #%% Write output .json
301
-
302
- images = list(image_id_to_image.values())
303
- categories = list(category_name_to_category.values())
304
-
305
- data = {}
306
- data['info'] = info
307
- data['images'] = images
308
- data['annotations'] = annotations
309
- data['categories'] = categories
310
-
311
- json.dump(data, open(output_json_filename, 'w'), indent=1)
312
- print('Finished writing json to {}'.format(output_json_filename))
313
-
314
-
315
- #%% Validate .json file
316
-
317
- options = integrity_check_json_db.IntegrityCheckOptions()
318
- options.baseDir = input_base_dir
319
- options.bCheckImageSizes = False
320
- options.bCheckImageExistence = False
321
- options.bFindUnusedImages = False
322
-
323
- sortedCategories, data, _ = integrity_check_json_db.integrity_check_json_db(output_json_filename, options)
324
-
325
-
326
- #%% Preview labels
327
-
328
- viz_options = visualize_db.DbVizOptions()
329
- viz_options.num_to_visualize = 2000
330
- viz_options.trim_to_images_with_bboxes = False
331
- viz_options.add_search_links = False
332
- viz_options.sort_by_filename = False
333
- viz_options.parallelize_rendering = True
334
- viz_options.classes_to_exclude = ['empty']
335
- html_output_file, image_db = visualize_db.visualize_db(db_path=output_json_filename,
336
- output_dir=os.path.join(
337
- output_base_dir, 'preview'),
338
- image_base_dir=input_base_dir,
339
- options=viz_options)
340
- os.startfile(html_output_file)
341
-
342
-
343
- #%% Precision-recall analysis
344
-
345
- from api.batch_processing.postprocessing.postprocess_batch_results import PostProcessingOptions
346
- from api.batch_processing.postprocessing.postprocess_batch_results import process_batch_results
347
-
348
- api_output_file = r'g:\auckland-doc\auckland-doc_20200801\combined_api_outputs\auckland-doc_202008012020.08.01_reformatMaukahuka_Auckland_Island2_TestingSummer_Trial_2019_detections.filtered_rde_0.60_0.85_5_0.05.json'
349
- postprocessing_output_folder = r'G:\auckland-doc\auckland-doc_20200801\postprocessing'
350
- image_base = r'E:\auckland-test\2_Testing'
351
- ground_truth_json_file = output_json_filename
352
-
353
- output_base = os.path.join(postprocessing_output_folder,'pr_analysis')
354
- os.makedirs(output_base,exist_ok=True)
355
-
356
- options = PostProcessingOptions()
357
- options.unlabeled_classes.append('openadjusted')
358
- options.image_base_dir = image_base
359
- options.parallelize_rendering = True
360
- options.include_almost_detections = True
361
- options.num_images_to_sample = 2500
362
- options.confidence_threshold = 0.75
363
- options.almost_detection_confidence_threshold = 0.7
364
- options.ground_truth_json_file = ground_truth_json_file
365
- options.allow_missing_images = True
366
- options.ground_truth_filename_replacements = {}
367
- options.api_output_filename_replacements = {'2020.08.01_reformat\\Maukahuka_Auckland_Island\\2_Testing\\':''}
368
- options.api_output_file = api_output_file
369
- options.output_dir = output_base
370
- ppresults = process_batch_results(options)
371
- os.startfile(ppresults.output_html_file)
372
-