megadetector 5.0.28__py3-none-any.whl → 10.0.0__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 (197) hide show
  1. megadetector/api/batch_processing/integration/digiKam/xmp_integration.py +2 -2
  2. megadetector/api/batch_processing/integration/eMammal/test_scripts/push_annotations_to_emammal.py +1 -1
  3. megadetector/api/batch_processing/integration/eMammal/test_scripts/select_images_for_testing.py +1 -1
  4. megadetector/classification/aggregate_classifier_probs.py +3 -3
  5. megadetector/classification/analyze_failed_images.py +5 -5
  6. megadetector/classification/cache_batchapi_outputs.py +5 -5
  7. megadetector/classification/create_classification_dataset.py +11 -12
  8. megadetector/classification/crop_detections.py +10 -10
  9. megadetector/classification/csv_to_json.py +8 -8
  10. megadetector/classification/detect_and_crop.py +13 -15
  11. megadetector/classification/efficientnet/model.py +8 -8
  12. megadetector/classification/efficientnet/utils.py +6 -5
  13. megadetector/classification/evaluate_model.py +7 -7
  14. megadetector/classification/identify_mislabeled_candidates.py +6 -6
  15. megadetector/classification/json_to_azcopy_list.py +1 -1
  16. megadetector/classification/json_validator.py +29 -32
  17. megadetector/classification/map_classification_categories.py +9 -9
  18. megadetector/classification/merge_classification_detection_output.py +12 -9
  19. megadetector/classification/prepare_classification_script.py +19 -19
  20. megadetector/classification/prepare_classification_script_mc.py +26 -26
  21. megadetector/classification/run_classifier.py +4 -4
  22. megadetector/classification/save_mislabeled.py +6 -6
  23. megadetector/classification/train_classifier.py +1 -1
  24. megadetector/classification/train_classifier_tf.py +9 -9
  25. megadetector/classification/train_utils.py +10 -10
  26. megadetector/data_management/annotations/annotation_constants.py +1 -2
  27. megadetector/data_management/camtrap_dp_to_coco.py +79 -46
  28. megadetector/data_management/cct_json_utils.py +103 -103
  29. megadetector/data_management/cct_to_md.py +49 -49
  30. megadetector/data_management/cct_to_wi.py +33 -33
  31. megadetector/data_management/coco_to_labelme.py +75 -75
  32. megadetector/data_management/coco_to_yolo.py +210 -193
  33. megadetector/data_management/databases/add_width_and_height_to_db.py +86 -12
  34. megadetector/data_management/databases/combine_coco_camera_traps_files.py +40 -40
  35. megadetector/data_management/databases/integrity_check_json_db.py +228 -200
  36. megadetector/data_management/databases/subset_json_db.py +33 -33
  37. megadetector/data_management/generate_crops_from_cct.py +88 -39
  38. megadetector/data_management/get_image_sizes.py +54 -49
  39. megadetector/data_management/labelme_to_coco.py +133 -125
  40. megadetector/data_management/labelme_to_yolo.py +159 -73
  41. megadetector/data_management/lila/create_lila_blank_set.py +81 -83
  42. megadetector/data_management/lila/create_lila_test_set.py +32 -31
  43. megadetector/data_management/lila/create_links_to_md_results_files.py +18 -18
  44. megadetector/data_management/lila/download_lila_subset.py +21 -24
  45. megadetector/data_management/lila/generate_lila_per_image_labels.py +365 -107
  46. megadetector/data_management/lila/get_lila_annotation_counts.py +35 -33
  47. megadetector/data_management/lila/get_lila_image_counts.py +22 -22
  48. megadetector/data_management/lila/lila_common.py +73 -70
  49. megadetector/data_management/lila/test_lila_metadata_urls.py +28 -19
  50. megadetector/data_management/mewc_to_md.py +344 -340
  51. megadetector/data_management/ocr_tools.py +262 -255
  52. megadetector/data_management/read_exif.py +249 -227
  53. megadetector/data_management/remap_coco_categories.py +90 -28
  54. megadetector/data_management/remove_exif.py +81 -21
  55. megadetector/data_management/rename_images.py +187 -187
  56. megadetector/data_management/resize_coco_dataset.py +588 -120
  57. megadetector/data_management/speciesnet_to_md.py +41 -41
  58. megadetector/data_management/wi_download_csv_to_coco.py +55 -55
  59. megadetector/data_management/yolo_output_to_md_output.py +248 -122
  60. megadetector/data_management/yolo_to_coco.py +333 -191
  61. megadetector/detection/change_detection.py +832 -0
  62. megadetector/detection/process_video.py +340 -337
  63. megadetector/detection/pytorch_detector.py +358 -278
  64. megadetector/detection/run_detector.py +399 -186
  65. megadetector/detection/run_detector_batch.py +404 -377
  66. megadetector/detection/run_inference_with_yolov5_val.py +340 -327
  67. megadetector/detection/run_tiled_inference.py +257 -249
  68. megadetector/detection/tf_detector.py +24 -24
  69. megadetector/detection/video_utils.py +332 -295
  70. megadetector/postprocessing/add_max_conf.py +19 -11
  71. megadetector/postprocessing/categorize_detections_by_size.py +45 -45
  72. megadetector/postprocessing/classification_postprocessing.py +468 -433
  73. megadetector/postprocessing/combine_batch_outputs.py +23 -23
  74. megadetector/postprocessing/compare_batch_results.py +590 -525
  75. megadetector/postprocessing/convert_output_format.py +106 -102
  76. megadetector/postprocessing/create_crop_folder.py +347 -147
  77. megadetector/postprocessing/detector_calibration.py +173 -168
  78. megadetector/postprocessing/generate_csv_report.py +508 -499
  79. megadetector/postprocessing/load_api_results.py +48 -27
  80. megadetector/postprocessing/md_to_coco.py +133 -102
  81. megadetector/postprocessing/md_to_labelme.py +107 -90
  82. megadetector/postprocessing/md_to_wi.py +40 -40
  83. megadetector/postprocessing/merge_detections.py +92 -114
  84. megadetector/postprocessing/postprocess_batch_results.py +319 -301
  85. megadetector/postprocessing/remap_detection_categories.py +91 -38
  86. megadetector/postprocessing/render_detection_confusion_matrix.py +214 -205
  87. megadetector/postprocessing/repeat_detection_elimination/find_repeat_detections.py +57 -57
  88. megadetector/postprocessing/repeat_detection_elimination/remove_repeat_detections.py +27 -28
  89. megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +704 -679
  90. megadetector/postprocessing/separate_detections_into_folders.py +226 -211
  91. megadetector/postprocessing/subset_json_detector_output.py +265 -262
  92. megadetector/postprocessing/top_folders_to_bottom.py +45 -45
  93. megadetector/postprocessing/validate_batch_results.py +70 -70
  94. megadetector/taxonomy_mapping/map_lila_taxonomy_to_wi_taxonomy.py +52 -52
  95. megadetector/taxonomy_mapping/map_new_lila_datasets.py +18 -19
  96. megadetector/taxonomy_mapping/prepare_lila_taxonomy_release.py +54 -33
  97. megadetector/taxonomy_mapping/preview_lila_taxonomy.py +67 -67
  98. megadetector/taxonomy_mapping/retrieve_sample_image.py +16 -16
  99. megadetector/taxonomy_mapping/simple_image_download.py +8 -8
  100. megadetector/taxonomy_mapping/species_lookup.py +156 -74
  101. megadetector/taxonomy_mapping/taxonomy_csv_checker.py +14 -14
  102. megadetector/taxonomy_mapping/taxonomy_graph.py +10 -10
  103. megadetector/taxonomy_mapping/validate_lila_category_mappings.py +13 -13
  104. megadetector/utils/ct_utils.py +1049 -211
  105. megadetector/utils/directory_listing.py +21 -77
  106. megadetector/utils/gpu_test.py +22 -22
  107. megadetector/utils/md_tests.py +632 -529
  108. megadetector/utils/path_utils.py +1520 -431
  109. megadetector/utils/process_utils.py +41 -41
  110. megadetector/utils/split_locations_into_train_val.py +62 -62
  111. megadetector/utils/string_utils.py +148 -27
  112. megadetector/utils/url_utils.py +489 -176
  113. megadetector/utils/wi_utils.py +2658 -2526
  114. megadetector/utils/write_html_image_list.py +137 -137
  115. megadetector/visualization/plot_utils.py +34 -30
  116. megadetector/visualization/render_images_with_thumbnails.py +39 -74
  117. megadetector/visualization/visualization_utils.py +487 -435
  118. megadetector/visualization/visualize_db.py +232 -198
  119. megadetector/visualization/visualize_detector_output.py +82 -76
  120. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/METADATA +5 -2
  121. megadetector-10.0.0.dist-info/RECORD +139 -0
  122. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/WHEEL +1 -1
  123. megadetector/api/batch_processing/api_core/__init__.py +0 -0
  124. megadetector/api/batch_processing/api_core/batch_service/__init__.py +0 -0
  125. megadetector/api/batch_processing/api_core/batch_service/score.py +0 -439
  126. megadetector/api/batch_processing/api_core/server.py +0 -294
  127. megadetector/api/batch_processing/api_core/server_api_config.py +0 -97
  128. megadetector/api/batch_processing/api_core/server_app_config.py +0 -55
  129. megadetector/api/batch_processing/api_core/server_batch_job_manager.py +0 -220
  130. megadetector/api/batch_processing/api_core/server_job_status_table.py +0 -149
  131. megadetector/api/batch_processing/api_core/server_orchestration.py +0 -360
  132. megadetector/api/batch_processing/api_core/server_utils.py +0 -88
  133. megadetector/api/batch_processing/api_core_support/__init__.py +0 -0
  134. megadetector/api/batch_processing/api_core_support/aggregate_results_manually.py +0 -46
  135. megadetector/api/batch_processing/api_support/__init__.py +0 -0
  136. megadetector/api/batch_processing/api_support/summarize_daily_activity.py +0 -152
  137. megadetector/api/batch_processing/data_preparation/__init__.py +0 -0
  138. megadetector/api/synchronous/__init__.py +0 -0
  139. megadetector/api/synchronous/api_core/animal_detection_api/__init__.py +0 -0
  140. megadetector/api/synchronous/api_core/animal_detection_api/api_backend.py +0 -151
  141. megadetector/api/synchronous/api_core/animal_detection_api/api_frontend.py +0 -263
  142. megadetector/api/synchronous/api_core/animal_detection_api/config.py +0 -35
  143. megadetector/api/synchronous/api_core/tests/__init__.py +0 -0
  144. megadetector/api/synchronous/api_core/tests/load_test.py +0 -110
  145. megadetector/data_management/importers/add_nacti_sizes.py +0 -52
  146. megadetector/data_management/importers/add_timestamps_to_icct.py +0 -79
  147. megadetector/data_management/importers/animl_results_to_md_results.py +0 -158
  148. megadetector/data_management/importers/auckland_doc_test_to_json.py +0 -373
  149. megadetector/data_management/importers/auckland_doc_to_json.py +0 -201
  150. megadetector/data_management/importers/awc_to_json.py +0 -191
  151. megadetector/data_management/importers/bellevue_to_json.py +0 -272
  152. megadetector/data_management/importers/cacophony-thermal-importer.py +0 -793
  153. megadetector/data_management/importers/carrizo_shrubfree_2018.py +0 -269
  154. megadetector/data_management/importers/carrizo_trail_cam_2017.py +0 -289
  155. megadetector/data_management/importers/cct_field_adjustments.py +0 -58
  156. megadetector/data_management/importers/channel_islands_to_cct.py +0 -913
  157. megadetector/data_management/importers/eMammal/copy_and_unzip_emammal.py +0 -180
  158. megadetector/data_management/importers/eMammal/eMammal_helpers.py +0 -249
  159. megadetector/data_management/importers/eMammal/make_eMammal_json.py +0 -223
  160. megadetector/data_management/importers/ena24_to_json.py +0 -276
  161. megadetector/data_management/importers/filenames_to_json.py +0 -386
  162. megadetector/data_management/importers/helena_to_cct.py +0 -283
  163. megadetector/data_management/importers/idaho-camera-traps.py +0 -1407
  164. megadetector/data_management/importers/idfg_iwildcam_lila_prep.py +0 -294
  165. megadetector/data_management/importers/import_desert_lion_conservation_camera_traps.py +0 -387
  166. megadetector/data_management/importers/jb_csv_to_json.py +0 -150
  167. megadetector/data_management/importers/mcgill_to_json.py +0 -250
  168. megadetector/data_management/importers/missouri_to_json.py +0 -490
  169. megadetector/data_management/importers/nacti_fieldname_adjustments.py +0 -79
  170. megadetector/data_management/importers/noaa_seals_2019.py +0 -181
  171. megadetector/data_management/importers/osu-small-animals-to-json.py +0 -364
  172. megadetector/data_management/importers/pc_to_json.py +0 -365
  173. megadetector/data_management/importers/plot_wni_giraffes.py +0 -123
  174. megadetector/data_management/importers/prepare_zsl_imerit.py +0 -131
  175. megadetector/data_management/importers/raic_csv_to_md_results.py +0 -416
  176. megadetector/data_management/importers/rspb_to_json.py +0 -356
  177. megadetector/data_management/importers/save_the_elephants_survey_A.py +0 -320
  178. megadetector/data_management/importers/save_the_elephants_survey_B.py +0 -329
  179. megadetector/data_management/importers/snapshot_safari_importer.py +0 -758
  180. megadetector/data_management/importers/snapshot_serengeti_lila.py +0 -1067
  181. megadetector/data_management/importers/snapshotserengeti/make_full_SS_json.py +0 -150
  182. megadetector/data_management/importers/snapshotserengeti/make_per_season_SS_json.py +0 -153
  183. megadetector/data_management/importers/sulross_get_exif.py +0 -65
  184. megadetector/data_management/importers/timelapse_csv_set_to_json.py +0 -490
  185. megadetector/data_management/importers/ubc_to_json.py +0 -399
  186. megadetector/data_management/importers/umn_to_json.py +0 -507
  187. megadetector/data_management/importers/wellington_to_json.py +0 -263
  188. megadetector/data_management/importers/wi_to_json.py +0 -442
  189. megadetector/data_management/importers/zamba_results_to_md_results.py +0 -180
  190. megadetector/data_management/lila/add_locations_to_island_camera_traps.py +0 -101
  191. megadetector/data_management/lila/add_locations_to_nacti.py +0 -151
  192. megadetector/utils/azure_utils.py +0 -178
  193. megadetector/utils/sas_blob_utils.py +0 -509
  194. megadetector-5.0.28.dist-info/RECORD +0 -209
  195. /megadetector/{api/batch_processing/__init__.py → __init__.py} +0 -0
  196. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/licenses/LICENSE +0 -0
  197. {megadetector-5.0.28.dist-info → megadetector-10.0.0.dist-info}/top_level.txt +0 -0
@@ -30,11 +30,11 @@ def crop_image_with_normalized_coordinates(
30
30
  bounding_box (tuple): tuple formatted as (x,y,w,h), where (0,0) is the
31
31
  upper-left of the image, and coordinates are normalized
32
32
  (so (0,0,1,1) is a box containing the entire image).
33
-
33
+
34
34
  Returns:
35
35
  PIL.Image: cropped image
36
36
  """
37
-
37
+
38
38
  im_width, im_height = image.size
39
39
  (x_norm, y_norm, w_norm, h_norm) = bounding_box
40
40
  (x, y, w, h) = (x_norm * im_width,
@@ -57,7 +57,7 @@ def render_images_with_thumbnails(
57
57
  """
58
58
  Given a primary image filename and a list of secondary images, writes to
59
59
  the provided output_image_filename an image where the one
60
- side is the primary image, and the other side is a grid of the
60
+ side is the primary image, and the other side is a grid of the
61
61
  secondary images, cropped according to the provided list of bounding
62
62
  boxes.
63
63
 
@@ -65,11 +65,11 @@ def render_images_with_thumbnails(
65
65
  wide.
66
66
 
67
67
  The height of the output image will be determined by the original aspect
68
- ratio of the primary image.
69
-
68
+ ratio of the primary image.
69
+
70
70
  Args:
71
71
  primary_image_filename (str): filename of the primary image to load as str
72
- primary_image_width (int): width at which to render the primary image; if this is
72
+ primary_image_width (int): width at which to render the primary image; if this is
73
73
  None, will render at the original image width
74
74
  secondary_image_filename_list (list): list of filenames of the secondary images
75
75
  secondary_image_bounding_box_list (list): list of tuples, one per secondary
@@ -78,7 +78,7 @@ def render_images_with_thumbnails(
78
78
  and coordinates are normalized (so (0,0,1,1) is a box containing
79
79
  the entire image.
80
80
  cropped_grid_width (int): width of the cropped-image area
81
- output_image_filename (str): filename to write the output image
81
+ output_image_filename (str): filename to write the output image
82
82
  primary_image_location (str, optional): 'right' or left'; reserving 'top', 'bottom', etc.
83
83
  for future use
84
84
  """
@@ -89,11 +89,11 @@ def render_images_with_thumbnails(
89
89
  'Length of secondary image list and bounding box list should be equal'
90
90
 
91
91
  assert primary_image_location in ['left','right']
92
-
92
+
93
93
  # Load primary image and resize to desired width
94
94
  primary_image = vis_utils.load_image(primary_image_filename)
95
95
  if primary_image_width is not None:
96
- primary_image = vis_utils.resize_image(primary_image, primary_image_width,
96
+ primary_image = vis_utils.resize_image(primary_image, primary_image_width,
97
97
  target_height=-1)
98
98
 
99
99
  # Compute the number of grid elements for the secondary images
@@ -101,15 +101,15 @@ def render_images_with_thumbnails(
101
101
  grid_width = cropped_grid_width
102
102
  grid_height = primary_image.size[1]
103
103
  grid_aspect = grid_width / grid_height
104
-
104
+
105
105
  sample_crop_width = secondary_image_bounding_box_list[0][2]
106
106
  sample_crop_height = secondary_image_bounding_box_list[0][3]
107
-
107
+
108
108
  n_crops = len(secondary_image_filename_list)
109
-
109
+
110
110
  optimal_n_rows = None
111
111
  optimal_aspect_error = None
112
-
112
+
113
113
  for candidate_n_rows in range(1,n_crops+1):
114
114
  candidate_n_cols = math.ceil(n_crops / candidate_n_rows)
115
115
  candidate_grid_aspect = (candidate_n_cols*sample_crop_width) / \
@@ -118,39 +118,40 @@ def render_images_with_thumbnails(
118
118
  if optimal_n_rows is None or aspect_error < optimal_aspect_error:
119
119
  optimal_n_rows = candidate_n_rows
120
120
  optimal_aspect_error = aspect_error
121
-
121
+
122
122
  assert optimal_n_rows is not None
123
123
  grid_rows = optimal_n_rows
124
- grid_columns = math.ceil(n_crops/grid_rows)
125
-
124
+ grid_columns = math.ceil(n_crops/grid_rows)
125
+
126
126
  # Compute the width of each grid cell
127
127
  grid_cell_width = math.floor(grid_width / grid_columns)
128
128
  grid_cell_height = math.floor(grid_height / grid_rows)
129
-
129
+
130
130
  # Load secondary images and their associated bounding boxes. Iterate
131
131
  # through them, crop them, and save them to a list of cropped_images
132
132
  cropped_images = []
133
133
  for (name, box) in zip(secondary_image_filename_list,
134
- secondary_image_bounding_box_list):
135
-
134
+ secondary_image_bounding_box_list,
135
+ strict=True):
136
+
136
137
  other_image = vis_utils.load_image(name)
137
138
  cropped_image = crop_image_with_normalized_coordinates(
138
139
  other_image, box)
139
-
140
+
140
141
  # Rescale this crop to fit within the desired grid cell size
141
142
  width_scale_factor = grid_cell_width / cropped_image.size[0]
142
143
  height_scale_factor = grid_cell_height / cropped_image.size[1]
143
144
  scale_factor = min(width_scale_factor,height_scale_factor)
144
-
145
+
145
146
  # Resize the cropped image, whether we're making it larger or smaller
146
147
  cropped_image = cropped_image.resize(
147
148
  ((int)(cropped_image.size[0] * scale_factor),
148
- (int)(cropped_image.size[1] * scale_factor)))
149
+ (int)(cropped_image.size[1] * scale_factor)))
149
150
 
150
- cropped_images.append(cropped_image)
151
+ cropped_images.append(cropped_image)
151
152
 
152
153
  # ...for each crop
153
-
154
+
154
155
  # Compute the final output image size. This will depend upon the aspect
155
156
  # ratio of the crops.
156
157
  output_image_width = primary_image.size[0] + grid_width
@@ -164,80 +165,45 @@ def render_images_with_thumbnails(
164
165
  primary_image_x = grid_width
165
166
  else:
166
167
  primary_image_x = 0
167
-
168
+
168
169
  output_image.paste(primary_image, (primary_image_x, 0))
169
170
 
170
171
  # Compute the final locations of the secondary images in the output image
171
172
  i_row = 0; i_col = 0
172
173
  for image in cropped_images:
173
-
174
+
174
175
  x = i_col * grid_cell_width
175
176
  if primary_image_location == 'left':
176
177
  x += primary_image.size[0]
177
- y = i_row * grid_cell_height
178
+ y = i_row * grid_cell_height
178
179
  output_image.paste(image, (x,y))
179
180
  i_col += 1
180
181
  if i_col >= grid_columns:
181
182
  i_col = 0
182
183
  i_row += 1
183
-
184
+
184
185
  # ...for each crop
185
186
 
186
187
  # Write output image to disk
187
- output_image.save(output_image_filename)
188
+ output_image.save(output_image_filename)
188
189
 
189
190
  # ...def render_images_with_thumbnails(...)
190
191
 
191
192
 
192
- #%% Interactive driver
193
-
194
- if False:
195
-
196
- pass
197
-
198
- #%%
199
-
200
- primary_image_filename = '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0035.JPG'
201
-
202
- primary_image_width = 5152
203
-
204
- secondary_image_filename_list = ['/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0035.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0040.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0007.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0041.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0008.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0048.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0031.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0006.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0004.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0026.JPG', '/home/user/data/KRU/KRU_public/KRU_S1/13/13_R1/KRU_S1_13_R1_IMAG0005.JPG']
205
-
206
- secondary_image_bounding_box_list = [[0, 0, 0.1853, 0.6552], [0, 0, 0.1855, 0.6527], [0, 0.000252, 0.1991, 0.6925], [0, 0, 0.1855, 0.6527], [0, 0.001008, 0.1902, 0.6774], [0, 0, 0.1845, 0.658], [0, 0, 0.1824, 0.6711], [0, 0.00252, 0.2005, 0.6857], [0, 0.002268, 0.1983, 0.6852], [0, 0, 0.1752, 0.6897], [0, 0.001764, 0.1989, 0.6887]]
207
-
208
- # cropped_grid_width = 3091
209
- cropped_grid_width = 500
210
-
211
- primary_image_location = 'right'
212
-
213
- output_image_filename = os.path.expanduser('~/tmp/grid-test.jpg')
214
-
215
- render_images_with_thumbnails(
216
- primary_image_filename,
217
- primary_image_width,
218
- secondary_image_filename_list,
219
- secondary_image_bounding_box_list,
220
- cropped_grid_width,
221
- output_image_filename,
222
- primary_image_location='right')
223
-
224
- path_utils.open_file(output_image_filename)
225
-
226
-
227
193
  #%% Command-line driver
228
194
 
229
195
  # This is just a test driver, this module is not meant to be run from the command line.
230
196
 
231
- def main():
232
-
197
+ def main(): # noqa
198
+
233
199
  # Load images from a test directory.
234
200
  #
235
- # Make the first image in the directory the primary image,
236
- # the remaining ones the comparison images.
201
+ # Make the first image in the directory the primary image,
202
+ # the remaining ones the comparison images.
237
203
  test_input_folder = os.path.expanduser('~/data/KRU-test')
238
204
  output_image_filename = os.path.expanduser('~/tmp/thumbnail_test.jpg')
239
-
240
- files = path_utils.find_images(test_input_folder)
205
+
206
+ files = path_utils.find_images(test_input_folder)
241
207
 
242
208
  random.seed(0); random.shuffle(files)
243
209
  primary_image_filename = files[0]
@@ -256,7 +222,7 @@ def main():
256
222
  box[1] + random.uniform(-0.001, 0.001),
257
223
  0.2,
258
224
  0.2))
259
-
225
+
260
226
  primary_image_width = 1000
261
227
  cropped_grid_width = 1000
262
228
 
@@ -267,9 +233,8 @@ def main():
267
233
  secondary_image_bounding_box_list,
268
234
  cropped_grid_width,
269
235
  output_image_filename, 'right')
270
-
271
- from megadetector.utils import path_utils
236
+
272
237
  path_utils.open_file(output_image_filename)
273
-
238
+
274
239
  if __name__ == '__main__':
275
240
  main()