Neslihan commited on
Commit
959b3a8
β€’
1 Parent(s): b2cc13e

download models and colors kypts (#25)

Browse files

- add download and kypts color (15928d774b7b425b3f655591043b4a12ea2bcd44)
- add save results and modelDownload (e9625b30d389a5aa99b4f989f4310bc58d96ce8b)

Files changed (2) hide show
  1. app.py +113 -75
  2. save_results.py +56 -0
app.py CHANGED
@@ -3,21 +3,23 @@
3
  # Built from https://huggingface.co/spaces/Neslihan/megadetector_dlcmodels/blob/main/app.py
4
 
5
 
 
6
  import gradio as gr
7
-
8
  import torch
9
  import torchvision
10
  from dlclive import DLCLive, Processor
11
- from model.models import DownloadModel
12
  from PIL import Image, ImageColor, ImageFont, ImageDraw
13
-
14
  import numpy as np
15
  import math
16
 
17
  # import json
18
  import os
19
  import yaml
20
-
 
21
  import pdb
22
 
23
  #########################################
@@ -31,14 +33,13 @@ FONTS = {'amiko': "font/Amiko-Regular.ttf",
31
  Megadet_Models = {'md_v5a': "megadet_model/md_v5a.0.0.pt",
32
  'md_v5b': "megadet_model/md_v5b.0.0.pt"}
33
 
34
- DLC_models = {'full_cat': "model/DLC_Cat_resnet_50_iteration-0_shuffle-0",
35
- 'full_dog': "model/DLC_Dog_resnet_50_iteration-0_shuffle-0",
36
- 'primate_face': "model/DLC_FacialLandmarks_resnet_50_iteration-1_shuffle-1",
37
- 'full_human': "model/DLC_human_dancing_resnet_101_iteration-0_shuffle-1",
38
- 'full_macaque': 'model/DLC_monkey_resnet_50_iteration-0_shuffle-1'}
39
-
40
- DLC_models_list = ['full_cat', 'full_dog','full_human', 'full_macaque', 'primate_face']
41
-
42
  #########################################
43
  # Draw keypoints on image
44
  def draw_keypoints_on_image(image,
@@ -49,7 +50,8 @@ def draw_keypoints_on_image(image,
49
  font_style='amiko',
50
  font_size=8,
51
  keypt_color="#ff0000",
52
- marker_size='2'):
 
53
  """Draws keypoints on an image.
54
  Modified from:
55
  https://www.programcreek.com/python/?code=fjchange%2Fobject_centric_VAD%2Fobject_centric_VAD-master%2Fobject_detection%2Futils%2Fvisualization_utils.py
@@ -62,25 +64,38 @@ def draw_keypoints_on_image(image,
62
  radius: keypoint radius. Default value is 2.
63
  use_normalized_coordinates: if True (default), treat keypoint values as
64
  relative to the image. Otherwise treat them as absolute.
 
 
65
  """
66
  # get a drawing context
67
- draw = ImageDraw.Draw(image)
68
 
69
  im_width, im_height = image.size
70
  keypoints_x = [k[0] for k in keypoints]
71
  keypoints_y = [k[1] for k in keypoints]
 
 
 
 
 
72
 
73
  # adjust keypoints coords if required
74
  if use_normalized_coordinates:
75
  keypoints_x = tuple([im_width * x for x in keypoints_x])
76
  keypoints_y = tuple([im_height * y for y in keypoints_y])
77
-
78
- # draw ellipses around keypoints and add string labels
 
 
79
  for i, (keypoint_x, keypoint_y) in enumerate(zip(keypoints_x, keypoints_y)):
 
 
 
 
 
80
  draw.ellipse([(keypoint_x - marker_size, keypoint_y - marker_size),
81
  (keypoint_x + marker_size, keypoint_y + marker_size)],
82
- outline=keypt_color,
83
- fill=keypt_color)
84
 
85
  # add string labels around keypoints
86
  if flag_show_str_labels:
@@ -88,7 +103,7 @@ def draw_keypoints_on_image(image,
88
  font_size)
89
  draw.text((keypoint_x + marker_size, keypoint_y + marker_size),#(0.5*im_width, 0.5*im_height), #-------
90
  map_label_id_to_str[i],
91
- ImageColor.getcolor(keypt_color, "RGB"), # rgb
92
  font=font)
93
 
94
  ############################################
@@ -101,29 +116,27 @@ def predict_md(im,
101
  g = (size / max(im.size)) # multipl factor to make max size of the image equal to input size
102
  im = im.resize((int(x * g) for x in im.size),
103
  Image.ANTIALIAS) # resize
104
-
105
- MD_model = torch.hub.load('ultralytics/yolov5',
106
- 'custom',
107
- path = Megadet_Models[mega_model_input],
108
- force_reload = True,
109
- source='github')
110
 
111
  ## detect objects
112
  results = MD_model(im) # inference # vars(results).keys()= dict_keys(['imgs', 'pred', 'names', 'files', 'times', 'xyxy', 'xywh', 'xyxyn', 'xywhn', 'n', 't', 's'])
113
- results.render() # updates results.imgs with boxes and labels
114
-
115
  return results
116
 
117
  ##########################################
118
- def crop_animal_detections(yolo_results,
 
119
  likelihood_th):
120
 
121
  ## Extract animal crops
122
- list_labels_as_str = [i for i in yolo_results.names.values()] # ['animal', 'person', 'vehicle'] # yolo_results.names
123
  list_np_animal_crops = []
124
- # for every image
125
- for img, det_array in zip(yolo_results.ims,
126
- yolo_results.xyxy):
 
 
 
127
 
128
  # for every detection
129
  for j in range(det_array.shape[0]):
@@ -137,14 +150,13 @@ def crop_animal_detections(yolo_results,
137
 
138
  pred_llk = det_array[j,4]
139
  pred_label = det_array[j,5]
140
-
141
  # keep animal crops above threshold
142
- # pdb.set_trace()
143
  if (pred_label == list_labels_as_str.index('animal')) and \
144
  (pred_llk >= likelihood_th):
145
  area = (xmin_rd, ymin_rd, xmax_rd, ymax_rd)
146
 
147
- crop = Image.fromarray(img).crop(area)
 
148
  crop_np = np.asarray(crop)
149
 
150
  # add to list
@@ -152,26 +164,50 @@ def crop_animal_detections(yolo_results,
152
 
153
  return list_np_animal_crops
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  ##########################################
156
  def predict_dlc(list_np_crops,
157
  kpts_likelihood_th,
158
  DLCmodel,
159
  dlc_proc):
160
-
161
  # run dlc thru list of crops
162
  dlc_live = DLCLive(DLCmodel, processor=dlc_proc)
163
  dlc_live.init_inference(list_np_crops[0])
164
 
165
  list_kpts_per_crop = []
 
166
  np_aux = np.empty((1,3)) # can I avoid hardcoding here?
167
  for crop in list_np_crops:
168
  # scale crop here?
169
  keypts_xyp = dlc_live.get_pose(crop) # third column is llk!
170
  # set kpts below threhsold to nan
 
 
171
  keypts_xyp[keypts_xyp[:,-1] < kpts_likelihood_th,:] = np_aux.fill(np.nan)
172
  # add kpts of this crop to list
173
  list_kpts_per_crop.append(keypts_xyp)
174
-
 
175
  return list_kpts_per_crop
176
 
177
 
@@ -193,14 +229,14 @@ def predict_pipeline(img_input,
193
  ## Get DLC model and labels as strings
194
  # TODO: make a dict as for megadetector
195
  # pdb.set_trace()
196
- path_to_DLCmodel = DLC_models[dlc_model_input_str]
197
- pose_cfg_path = os.path.join(path_to_DLCmodel,'pose_cfg.yaml')
198
- #path_to_DLCmodel = DownloadModel(dlc_model_input_str, './model/')
199
- #pose_cfg_path = './model/pose_cfg.yaml'
200
  # extract map label ids to strings
201
  # pose_cfg_dict['all_joints'] is a list of one-element lists,
202
  with open(pose_cfg_path, "r") as stream:
203
  pose_cfg_dict = yaml.safe_load(stream)
 
204
  map_label_id_to_str = dict([(k,v) for k,v in zip([el[0] for el in pose_cfg_dict['all_joints']],
205
  pose_cfg_dict['all_joints_names'])])
206
 
@@ -209,10 +245,12 @@ def predict_pipeline(img_input,
209
  md_results = predict_md(img_input,
210
  mega_model_input,
211
  size=640) #Image.fromarray(results.imgs[0])
212
-
213
  ################################################################
214
  # Obtain animal crops for bboxes with confidence above th
215
- list_crops = crop_animal_detections(md_results,
 
 
216
  bbox_likelihood_th)
217
 
218
  ##############################################################
@@ -226,7 +264,7 @@ def predict_pipeline(img_input,
226
  kpts_likelihood_th,
227
  path_to_DLCmodel,
228
  dlc_proc)
229
- # draw kpts on input img
230
  draw_keypoints_on_image(img_input,
231
  list_kpts_per_crop[0], # a numpy array with shape [num_keypoints, 2].
232
  map_label_id_to_str,
@@ -236,7 +274,8 @@ def predict_pipeline(img_input,
236
  font_size=font_size,
237
  keypt_color=keypt_color,
238
  marker_size=marker_size)
239
- return img_input
 
240
 
241
  else:
242
  # Compute kpts for each crop
@@ -244,18 +283,10 @@ def predict_pipeline(img_input,
244
  kpts_likelihood_th,
245
  path_to_DLCmodel,
246
  dlc_proc)
247
-
248
- # Produce final image
249
- img_background = Image.fromarray(md_results.ims[0]) # img_input or Image.fromarray(md_results.imgs[0])?
250
- # # Image.fromarray(md_results.imgs[0]) --> (640, 479)
251
- # # img_input.size ---> (259, 194)
252
-
253
-
254
- # resize image to match megadetector output
255
- # img_background = img_input
256
- # g = (640 / max(img_background.size)) # gain
257
- # img_background = img_background.resize((int(x * g) for x in img_background.size),
258
- # Image.ANTIALIAS) # resize
259
  for ic, (np_crop, kpts_crop) in enumerate(zip(list_crops,
260
  list_kpts_per_crop)):
261
 
@@ -271,17 +302,24 @@ def predict_pipeline(img_input,
271
  keypt_color=keypt_color,
272
  marker_size=marker_size)
273
 
274
- ## Paste crop in original image
275
- # https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.paste
276
- img_background.paste(img_crop,
277
- box = tuple([int(t) for t in md_results.xyxy[0][ic,:2]]))
278
-
279
- return img_background
 
 
 
 
 
 
 
 
 
280
 
281
  #############################################
282
- # %%
283
  # User interface: inputs
284
-
285
  # Input image
286
  gr_image_input = gr.inputs.Image(type="pil", label="Input Image")
287
 
@@ -301,13 +339,13 @@ gr_dlc_only_checkbox = gr.inputs.Checkbox(False,
301
  gr_str_labels_checkbox = gr.inputs.Checkbox(True,
302
  label='Show bodypart labels?')
303
 
304
- gr_slider_conf_bboxes = gr.inputs.Slider(0,1,.05,0.8,
305
  label='Set confidence threshold for animal detections')
306
- gr_slider_conf_keypoints = gr.inputs.Slider(0,1,.05,0.25,
307
  label='Set confidence threshold for keypoints')
308
 
309
  # Data viz
310
- gr_keypt_color = gr.ColorPicker(value ="#ff0000", label="choose color for keypoint label")
311
 
312
  gr_labels_font_style = gr.inputs.Dropdown(choices=['amiko', 'nature', 'painter', 'animals', 'zen'],
313
  default='amiko',
@@ -315,7 +353,7 @@ gr_labels_font_style = gr.inputs.Dropdown(choices=['amiko', 'nature', 'painter',
315
  label='Select keypoint label font')
316
  gr_slider_font_size = gr.inputs.Slider(5,30,1,8,
317
  label='Set font size')
318
- gr_slider_marker_size = gr.inputs.Slider(0.5,5,0.2,2,
319
  label='Set marker size')
320
 
321
  # list of inputs
@@ -335,12 +373,13 @@ inputs = [gr_image_input,
335
  # %%
336
  # User interface: outputs
337
  gr_image_output = gr.outputs.Image(type="pil", label="Output Image")
338
- outputs = [gr_image_output]
 
339
 
340
  ##############################################
341
  # User interace: description
342
  gr_title = "MegaDetector v5 + DeepLabCut-Live!"
343
- gr_description = "Contributed by Sofia Minano, Neslihan Wittek, Nirel Kadzo, VicShaoChih Chiang -- DLC AI Residents 2022..\
344
  This App detects and estimate the pose of animals in camera trap images using <a href='https://github.com/microsoft/CameraTraps'>MegaDetector v5a</a> + <a href='https://github.com/DeepLabCut/DeepLabCut-live'>DeepLabCut-live</a>. \
345
  We host models from the <a href='http://www.mackenziemathislab.org/dlc-modelzoo'>DeepLabCut ModelZoo Project</a>\, and two <a href='https://github.com/microsoft/CameraTraps/blob/main/megadetector.md'>MegaDetector Models</a>. Please carefully check their licensing information if you use this project. The App additionally builds upon on work from <a href='https://huggingface.co/spaces/hlydecker/MegaDetector_v5'>hlydecker/MegaDetector_v5</a> \
346
  <a href='https://huggingface.co/spaces/sofmi/MegaDetector_DLClive'>sofmi/MegaDetector_DLClive</a> \
@@ -348,10 +387,9 @@ gr_description = "Contributed by Sofia Minano, Neslihan Wittek, Nirel Kadzo, Vic
348
 
349
  # article = "<p style='text-align: center'>This app makes predictions using a YOLOv5x6 model that was trained to detect animals, humans, and vehicles in camera trap images; find out more about the project on <a href='https://github.com/microsoft/CameraTraps'>GitHub</a>. This app was built by Henry Lydecker but really depends on code and models developed by <a href='http://ecologize.org/'>Ecologize</a> and <a href='http://aka.ms/aiforearth'>Microsoft AI for Earth</a>. Find out more about the YOLO model from the original creator, <a href='https://pjreddie.com/darknet/yolo/'>Joseph Redmon</a>. YOLOv5 is a family of compound-scaled object detection models trained on the COCO dataset and developed by Ultralytics, and includes simple functionality for Test Time Augmentation (TTA), model ensembling, hyperparameter evolution, and export to ONNX, CoreML and TFLite. <a href='https://github.com/ultralytics/yolov5'>Source code</a> | <a href='https://pytorch.org/hub/ultralytics_yolov5'>PyTorch Hub</a></p>"
350
 
351
- examples = [['example/monkey_full.jpg', 'md_v5a','full_macaque', False, True, 0.5, 0.3, 'amiko', 5, 'blue', 3],
352
- ['example/dog.jpeg', 'md_v5a', 'full_dog', False, True, 0.5, 0.05, 'amiko', 5, 'yellow', 3],
353
- ['example/cat.jpg', 'md_v5a', 'full_cat', False, True, 0.5, 0.05, 'amiko', 5, 'purple', 3],
354
- ['example/monkey_face.jpeg', 'md_v5a', 'primate_face', False, True, 0.5, 0.05, 'amiko', 5, 'orange', 3]]
355
 
356
  ################################################
357
  # %% Define and launch gradio interface
 
3
  # Built from https://huggingface.co/spaces/Neslihan/megadetector_dlcmodels/blob/main/app.py
4
 
5
 
6
+ from tkinter import W
7
  import gradio as gr
8
+ from matplotlib import cm
9
  import torch
10
  import torchvision
11
  from dlclive import DLCLive, Processor
12
+ import matplotlib
13
  from PIL import Image, ImageColor, ImageFont, ImageDraw
14
+ # check git lfs pull!!
15
  import numpy as np
16
  import math
17
 
18
  # import json
19
  import os
20
  import yaml
21
+ from model.models import DownloadModel
22
+ from save_results import save_results
23
  import pdb
24
 
25
  #########################################
 
33
  Megadet_Models = {'md_v5a': "megadet_model/md_v5a.0.0.pt",
34
  'md_v5b': "megadet_model/md_v5b.0.0.pt"}
35
 
36
+ DLC_folders = {'full_cat': "model/DLC_Cat/",
37
+ 'full_dog': "model/DLC_Dog/",
38
+ 'primate_face': "model/DLC_FacialLandmarks/",
39
+ 'full_human': "model/DLC_human_dancing/",
40
+ 'full_macaque': 'model/DLC_monkey/'}
41
+
42
+ DLC_models_list = ['full_cat', 'full_dog','primate_face', 'full_human', 'full_macaque']
 
43
  #########################################
44
  # Draw keypoints on image
45
  def draw_keypoints_on_image(image,
 
50
  font_style='amiko',
51
  font_size=8,
52
  keypt_color="#ff0000",
53
+ marker_size=2,
54
+ ):
55
  """Draws keypoints on an image.
56
  Modified from:
57
  https://www.programcreek.com/python/?code=fjchange%2Fobject_centric_VAD%2Fobject_centric_VAD-master%2Fobject_detection%2Futils%2Fvisualization_utils.py
 
64
  radius: keypoint radius. Default value is 2.
65
  use_normalized_coordinates: if True (default), treat keypoint values as
66
  relative to the image. Otherwise treat them as absolute.
67
+
68
+
69
  """
70
  # get a drawing context
71
+ draw = ImageDraw.Draw(image,"RGBA")
72
 
73
  im_width, im_height = image.size
74
  keypoints_x = [k[0] for k in keypoints]
75
  keypoints_y = [k[1] for k in keypoints]
76
+ alpha = [k[2] for k in keypoints]
77
+ norm = matplotlib.colors.Normalize(vmin=0, vmax=255)
78
+
79
+ names_for_color = [i for i in map_label_id_to_str.keys()]
80
+ colores = np.linspace(0, 255, num=len(names_for_color),dtype= int)
81
 
82
  # adjust keypoints coords if required
83
  if use_normalized_coordinates:
84
  keypoints_x = tuple([im_width * x for x in keypoints_x])
85
  keypoints_y = tuple([im_height * y for y in keypoints_y])
86
+
87
+ #cmap = matplotlib.cm.get_cmap('hsv')
88
+ cmap2 = matplotlib.cm.get_cmap('Greys')
89
+ # draw ellipses around keypoints
90
  for i, (keypoint_x, keypoint_y) in enumerate(zip(keypoints_x, keypoints_y)):
91
+ round_fill = list(cm.viridis(norm(colores[i]),bytes=True))#[round(num*255) for num in list(cmap(i))[:3]] #check!
92
+ if np.isnan(alpha[i]) == False :
93
+ round_fill[3] = round(alpha[i] *255)
94
+ #print(round_fill)
95
+ #round_outline = [round(num*255) for num in list(cmap2(alpha[i]))[:3]]
96
  draw.ellipse([(keypoint_x - marker_size, keypoint_y - marker_size),
97
  (keypoint_x + marker_size, keypoint_y + marker_size)],
98
+ fill=tuple(round_fill), outline= 'black', width=1) #fill and outline: [0,255]
 
99
 
100
  # add string labels around keypoints
101
  if flag_show_str_labels:
 
103
  font_size)
104
  draw.text((keypoint_x + marker_size, keypoint_y + marker_size),#(0.5*im_width, 0.5*im_height), #-------
105
  map_label_id_to_str[i],
106
+ ImageColor.getcolor(keypt_color, "RGB"), # rgb #
107
  font=font)
108
 
109
  ############################################
 
116
  g = (size / max(im.size)) # multipl factor to make max size of the image equal to input size
117
  im = im.resize((int(x * g) for x in im.size),
118
  Image.ANTIALIAS) # resize
119
+ MD_model = torch.hub.load('ultralytics/yolov5', 'custom', Megadet_Models[mega_model_input])
 
 
 
 
 
120
 
121
  ## detect objects
122
  results = MD_model(im) # inference # vars(results).keys()= dict_keys(['imgs', 'pred', 'names', 'files', 'times', 'xyxy', 'xywh', 'xyxyn', 'xywhn', 'n', 't', 's'])
123
+
 
124
  return results
125
 
126
  ##########################################
127
+ def crop_animal_detections(img_in,
128
+ yolo_results,
129
  likelihood_th):
130
 
131
  ## Extract animal crops
132
+ list_labels_as_str = [i for i in yolo_results.names.values()] # ['animal', 'person', 'vehicle']
133
  list_np_animal_crops = []
134
+
135
+ # image to crop (scale as input for megadetector)
136
+ img_in = img_in.resize((yolo_results.ims[0].shape[1],
137
+ yolo_results.ims[0].shape[0]))
138
+ # for every detection in the img
139
+ for det_array in yolo_results.xyxy:
140
 
141
  # for every detection
142
  for j in range(det_array.shape[0]):
 
150
 
151
  pred_llk = det_array[j,4]
152
  pred_label = det_array[j,5]
 
153
  # keep animal crops above threshold
 
154
  if (pred_label == list_labels_as_str.index('animal')) and \
155
  (pred_llk >= likelihood_th):
156
  area = (xmin_rd, ymin_rd, xmax_rd, ymax_rd)
157
 
158
+ #pdb.set_trace()
159
+ crop = img_in.crop(area) #Image.fromarray(img_in).crop(area)
160
  crop_np = np.asarray(crop)
161
 
162
  # add to list
 
164
 
165
  return list_np_animal_crops
166
 
167
+ def draw_rectangle_text(img,results,font_style='amiko',font_size=8, keypt_color="white",):
168
+ #pdb.set_trace()
169
+ bbxyxy = results
170
+ w, h = bbxyxy[2], bbxyxy[3]
171
+ shape = [(bbxyxy[0], bbxyxy[1]), (w , h)]
172
+ imgR = ImageDraw.Draw(img)
173
+ imgR.rectangle(shape, outline ="red",width=5) ##bb for animal
174
+
175
+ confidence = bbxyxy[4]
176
+ string_bb = 'animal ' + str(round(confidence, 2))
177
+ font = ImageFont.truetype(FONTS[font_style], font_size)
178
+
179
+ text_size = font.getsize(string_bb) # (h,w)
180
+ position = (bbxyxy[0],bbxyxy[1] - text_size[1] -2 )
181
+ left, top, right, bottom = imgR.textbbox(position, string_bb, font=font)
182
+ imgR.rectangle((left, top-5, right+5, bottom+5), fill="red")
183
+ imgR.text((bbxyxy[0] + 3 ,bbxyxy[1] - text_size[1] -2 ), string_bb, font=font, fill="black")
184
+
185
+ return imgR
186
+
187
  ##########################################
188
  def predict_dlc(list_np_crops,
189
  kpts_likelihood_th,
190
  DLCmodel,
191
  dlc_proc):
192
+
193
  # run dlc thru list of crops
194
  dlc_live = DLCLive(DLCmodel, processor=dlc_proc)
195
  dlc_live.init_inference(list_np_crops[0])
196
 
197
  list_kpts_per_crop = []
198
+ all_kypts = []
199
  np_aux = np.empty((1,3)) # can I avoid hardcoding here?
200
  for crop in list_np_crops:
201
  # scale crop here?
202
  keypts_xyp = dlc_live.get_pose(crop) # third column is llk!
203
  # set kpts below threhsold to nan
204
+
205
+ #pdb.set_trace()
206
  keypts_xyp[keypts_xyp[:,-1] < kpts_likelihood_th,:] = np_aux.fill(np.nan)
207
  # add kpts of this crop to list
208
  list_kpts_per_crop.append(keypts_xyp)
209
+ all_kypts.append(keypts_xyp)
210
+
211
  return list_kpts_per_crop
212
 
213
 
 
229
  ## Get DLC model and labels as strings
230
  # TODO: make a dict as for megadetector
231
  # pdb.set_trace()
232
+ path_to_DLCmodel = DownloadModel(dlc_model_input_str, str(DLC_folders[dlc_model_input_str]) )
233
+ pose_cfg_path = str(DLC_folders[dlc_model_input_str]) +'pose_cfg.yaml'
234
+ #pdb.set_trece()
 
235
  # extract map label ids to strings
236
  # pose_cfg_dict['all_joints'] is a list of one-element lists,
237
  with open(pose_cfg_path, "r") as stream:
238
  pose_cfg_dict = yaml.safe_load(stream)
239
+
240
  map_label_id_to_str = dict([(k,v) for k,v in zip([el[0] for el in pose_cfg_dict['all_joints']],
241
  pose_cfg_dict['all_joints_names'])])
242
 
 
245
  md_results = predict_md(img_input,
246
  mega_model_input,
247
  size=640) #Image.fromarray(results.imgs[0])
248
+ #pdb.set_trace()
249
  ################################################################
250
  # Obtain animal crops for bboxes with confidence above th
251
+
252
+ list_crops = crop_animal_detections(img_input,
253
+ md_results,
254
  bbox_likelihood_th)
255
 
256
  ##############################################################
 
264
  kpts_likelihood_th,
265
  path_to_DLCmodel,
266
  dlc_proc)
267
+ # draw kpts on input img #fix!
268
  draw_keypoints_on_image(img_input,
269
  list_kpts_per_crop[0], # a numpy array with shape [num_keypoints, 2].
270
  map_label_id_to_str,
 
274
  font_size=font_size,
275
  keypt_color=keypt_color,
276
  marker_size=marker_size)
277
+
278
+ return img_input, []
279
 
280
  else:
281
  # Compute kpts for each crop
 
283
  kpts_likelihood_th,
284
  path_to_DLCmodel,
285
  dlc_proc)
286
+
287
+ img_background = img_input.resize((md_results.ims[0].shape[1],md_results.ims[0].shape[0]))
288
+ print('I have ' + str(len(list_crops)) + ' bounding box')
289
+
 
 
 
 
 
 
 
 
290
  for ic, (np_crop, kpts_crop) in enumerate(zip(list_crops,
291
  list_kpts_per_crop)):
292
 
 
302
  keypt_color=keypt_color,
303
  marker_size=marker_size)
304
 
305
+ ## Paste crop in original image https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.paste
306
+ img_background.paste(img_crop, box = tuple([int(t) for t in md_results.xyxy[0][ic,:2]]))
307
+
308
+
309
+
310
+ bb_per_animal = md_results.xyxy[0].tolist()[ic]
311
+ pred = md_results.xyxy[0].tolist()[ic][4]
312
+ if bbox_likelihood_th < pred:
313
+ draw_rectangle_text(img_background, bb_per_animal ,font_style=font_style,font_size=font_size, keypt_color=keypt_color)
314
+
315
+
316
+
317
+ download_file = save_results(md_results,list_kpts_per_crop,map_label_id_to_str,bbox_likelihood_th)
318
+
319
+ return img_background, download_file
320
 
321
  #############################################
 
322
  # User interface: inputs
 
323
  # Input image
324
  gr_image_input = gr.inputs.Image(type="pil", label="Input Image")
325
 
 
339
  gr_str_labels_checkbox = gr.inputs.Checkbox(True,
340
  label='Show bodypart labels?')
341
 
342
+ gr_slider_conf_bboxes = gr.inputs.Slider(0,1,.02,0.8,
343
  label='Set confidence threshold for animal detections')
344
+ gr_slider_conf_keypoints = gr.inputs.Slider(0,1,.05,0,
345
  label='Set confidence threshold for keypoints')
346
 
347
  # Data viz
348
+ gr_keypt_color = gr.ColorPicker(label="choose color for keypoint label")
349
 
350
  gr_labels_font_style = gr.inputs.Dropdown(choices=['amiko', 'nature', 'painter', 'animals', 'zen'],
351
  default='amiko',
 
353
  label='Select keypoint label font')
354
  gr_slider_font_size = gr.inputs.Slider(5,30,1,8,
355
  label='Set font size')
356
+ gr_slider_marker_size = gr.inputs.Slider(1,20,1,5,
357
  label='Set marker size')
358
 
359
  # list of inputs
 
373
  # %%
374
  # User interface: outputs
375
  gr_image_output = gr.outputs.Image(type="pil", label="Output Image")
376
+ out_smpl_npy_download = gr.File(label="Download JSON file")
377
+ outputs = [gr_image_output,out_smpl_npy_download]
378
 
379
  ##############################################
380
  # User interace: description
381
  gr_title = "MegaDetector v5 + DeepLabCut-Live!"
382
+ gr_description = "Contributed by Sofia Minano, Neslihan Wittek, Nirel Kadzo, VicShaoChih Chiang, Sabrina Benas -- DLC AI Residents 2022..\
383
  This App detects and estimate the pose of animals in camera trap images using <a href='https://github.com/microsoft/CameraTraps'>MegaDetector v5a</a> + <a href='https://github.com/DeepLabCut/DeepLabCut-live'>DeepLabCut-live</a>. \
384
  We host models from the <a href='http://www.mackenziemathislab.org/dlc-modelzoo'>DeepLabCut ModelZoo Project</a>\, and two <a href='https://github.com/microsoft/CameraTraps/blob/main/megadetector.md'>MegaDetector Models</a>. Please carefully check their licensing information if you use this project. The App additionally builds upon on work from <a href='https://huggingface.co/spaces/hlydecker/MegaDetector_v5'>hlydecker/MegaDetector_v5</a> \
385
  <a href='https://huggingface.co/spaces/sofmi/MegaDetector_DLClive'>sofmi/MegaDetector_DLClive</a> \
 
387
 
388
  # article = "<p style='text-align: center'>This app makes predictions using a YOLOv5x6 model that was trained to detect animals, humans, and vehicles in camera trap images; find out more about the project on <a href='https://github.com/microsoft/CameraTraps'>GitHub</a>. This app was built by Henry Lydecker but really depends on code and models developed by <a href='http://ecologize.org/'>Ecologize</a> and <a href='http://aka.ms/aiforearth'>Microsoft AI for Earth</a>. Find out more about the YOLO model from the original creator, <a href='https://pjreddie.com/darknet/yolo/'>Joseph Redmon</a>. YOLOv5 is a family of compound-scaled object detection models trained on the COCO dataset and developed by Ultralytics, and includes simple functionality for Test Time Augmentation (TTA), model ensembling, hyperparameter evolution, and export to ONNX, CoreML and TFLite. <a href='https://github.com/ultralytics/yolov5'>Source code</a> | <a href='https://pytorch.org/hub/ultralytics_yolov5'>PyTorch Hub</a></p>"
389
 
390
+ examples = [['example/monkey_full.jpg', 'md_v5a','full_macaque', False, True, 0.5, 0.3, 'amiko', 9, 'blue', 3],
391
+ ['example/dog.jpeg', 'md_v5a', 'full_dog', False, True, 0.5, 0.00, 'amiko',9, 'yellow', 3],
392
+ ['example/cat.jpg', 'md_v5a', 'full_cat', False, True, 0.5, 0.05, 'amiko', 9, 'purple', 3]]
 
393
 
394
  ################################################
395
  # %% Define and launch gradio interface
save_results.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import numpy as np
3
+ import pdb
4
+
5
+ dict_pred = {0: 'animal', 1: 'person', 2: 'vehicle'}
6
+
7
+
8
+ def save_results(md_results, dlc_outputs,map_label_id_to_str,thr,output_file = 'dowload_predictions.json'):
9
+
10
+ """
11
+
12
+ write json
13
+
14
+ """
15
+ info = {}
16
+ ## info megaDetector
17
+ info['file']= md_results.files[0]
18
+ number_bb = len(md_results.xyxy[0].tolist())
19
+ info['number_of_bb'] = number_bb
20
+ number_bb_thr = len(dlc_outputs)
21
+ labels = [n for n in map_label_id_to_str.values()]
22
+ #pdb.set_trace()
23
+ new_index = []
24
+ for i in range(number_bb):
25
+ corner_x1,corner_y1,corner_x2,corner_y2,confidence, _ = md_results.xyxy[0].tolist()[i]
26
+
27
+ if confidence > thr:
28
+ new_index.append(i)
29
+
30
+
31
+ for i in range(number_bb_thr):
32
+ aux={}
33
+ corner_x1,corner_y1,corner_x2,corner_y2,confidence, _ = md_results.xyxy[0].tolist()[new_index[i]]
34
+ aux['corner_1'] = (corner_x1,corner_y1)
35
+ aux['corner_2'] = (corner_x2,corner_y2)
36
+ aux['predict MD'] = md_results.names[0]
37
+ aux['confidence MD'] = confidence
38
+
39
+ ## info dlc
40
+ kypts = []
41
+ for s in dlc_outputs[i]:
42
+ aux1 = []
43
+ for j in s:
44
+ aux1.append(float(j))
45
+
46
+ kypts.append(aux1)
47
+ aux['dlc_pred'] = dict(zip(labels,kypts))
48
+ info['bb_' + str(new_index[i]) ]=aux
49
+
50
+
51
+ with open(output_file, 'w') as f:
52
+ json.dump(info, f, indent=1)
53
+ print('Output file saved at {}'.format(output_file))
54
+
55
+ return output_file
56
+