21 Authors: Giacomo Colosio, Sebastiano Colosio, Patrizio Acquadro, Tito Nicola Drugman
26 import tensorflow
as tf
32 Post-process for the single pose estimation heatmaps use-case
35 tensor (tf.Tensor): shape (batch, res, res, keypoints) FLOAT32 heatmaps outputs of the single pose estimation models
38 detection (tf.Tensor): shape (batch, 1, keypoints*3) FLOAT32 the (x,y,conf) values of all keypoints for the single person
43 predictions_flat = tf.reshape(tensor,[sh[0],sh[1]*sh[2],-1])
44 arg_pred = tf.argmax(predictions_flat,1)
45 val_pred = tf.reduce_max(predictions_flat,1)
47 arg_pred_x = (tf.cast(arg_pred//sh[2],dtype=tf.float32)+0.5) / sh[1]
48 arg_pred_y = (tf.cast(arg_pred%sh[2],dtype=tf.float32)+0.5) / sh[2]
50 detection = tf.stack([arg_pred_y,arg_pred_x,val_pred],1)
51 detection = tf.transpose(detection,[0,2,1])
52 detection = tf.reshape(detection,[sh[0],-1])
53 detection = detection[:,
None,:]
59 Post-process for the single pose estimation use-case
62 tensor (tf.Tensor): shape (batch, 1, keypoints, 3) FLOAT32 the (x,y,conf) values of all keypoints but in a different format
65 detection (tf.Tensor): shape (batch, 1, keypoints*3) FLOAT32 the (x,y,conf) values of all keypoints for the single person
74 detection = tf.stack([x,y,v],-1)
76 detection = tf.reshape(detection,[sh[0],1,-1])
80 def _padded_nms(tensor:tf.Tensor,max_output_size:int,iou_threshold:float,score_threshold:float):
82 Function used to apply NMS on each image of the batch independently
85 tensor (tf.Tensor): shape (5+keypoints*3, num_boxes) FLOAT32 outputs of the YOLO multi pose estimation models
86 max_output_size (tf.Tensor): shape (1,) INT32 max number of detections per image
87 iou_threshold (tf.Tensor): shape (1,) FLOAT32 threshold for NMS iou
88 score_threshold (tf.Tensor): shape (1,) FLOAT32 threshold to filter detections under a certain score
91 detection (tf.Tensor): shape (max_output_size, 5+keypoints*3) FLOAT32 bounding boxes + (x,y,conf) values for all keypoints of all detected persons
96 keypoints = tensor[5:]
101 x1 = boxes[0] - boxes[2]/2
102 y1 = boxes[1] - boxes[3]/2
103 x2 = boxes[0] + boxes[2]/2
104 y2 = boxes[1] + boxes[3]/2
106 yxboxes = tf.stack([y1, x1, y2, x2])
107 yxboxes = tf.transpose(yxboxes,[1,0])
109 selected_indices = tf.image.non_max_suppression(yxboxes,scores,
110 max_output_size = max_output_size,
111 iou_threshold = iou_threshold,
112 score_threshold = score_threshold)
113 indices = selected_indices.shape[0]
116 detection = tf.gather(tensor,selected_indices,axis=1)
117 detection = tf.transpose(detection,[1,0])
119 detection = tf.zeros((indices,tensor.shape[0]))
121 zero_padding = tf.zeros((max_output_size-indices,tensor.shape[0]))
123 detection = tf.concat([detection,zero_padding],0)
127 def yolo_mpe_postprocess(tensor:tf.Tensor,max_output_size:int=20,iou_threshold:float=0.7,score_threshold:float=0.25):
129 Post-process for the multi pose estimation use-case
132 tensor (tf.Tensor): shape (batch, 5+keypoints*3, num_boxes) FLOAT32 outputs of the YOLO multi pose estimation models
133 max_output_size (tf.Tensor): shape (1,) INT32 max number of detections per image
134 iou_threshold (tf.Tensor): shape (1,) FLOAT32 threshold for NMS iou
135 score_threshold (tf.Tensor): shape (1,) FLOAT32 threshold to filter detections under a certain score
138 detections (tf.Tensor): shape (batch, max_output_size, 5+keypoints*3) FLOAT32 values for all keypoints of all detected persons
142 tensor = tf.constant(tensor,tf.float32)
144 args = {
'max_output_size':max_output_size,
145 'iou_threshold':iou_threshold,
146 'score_threshold':score_threshold}
148 detections = tf.map_fn(
lambda x :
_padded_nms(x,**args),tensor)
155 Post-process for the hand landmarks use-case
158 tensor list(tf.Tensor): shape [(batch,1),(batch, keypoints*3),(batch,1),(batch, keypoints*3)] FLOAT32 outputs of the hand landmarks
161 det (tf.Tensor): shape (batch, keypoints*3) FLOAT32 3D detections of the hand landmarks in pixels
162 norm_det (tf.Tensor): shape (batch, keypoints*3) FLOAT32 3D detections of the hand landmarks centered reduced (invariant of hand size and position)
163 htype (tf.Tensor): shape (batch,) FLOAT32 type of hand (right or left) if near 0 -> left, if near 1 -> right
164 hprob (tf.Tensor): shape (batch,) FLOAT32 presence probability of the hand
170 x_sc = tf.reduce_sum((norm_det[:,0::3]-tf.reduce_mean(norm_det[:,0::3],-1))*(det[:,0::3]-tf.reduce_mean(det[:,0::3],-1)),-1) / tf.reduce_sum((norm_det[:,0::3]-tf.reduce_mean(norm_det[:,0::3],-1))**2,-1)
171 y_sc = tf.reduce_sum((norm_det[:,1::3]-tf.reduce_mean(norm_det[:,1::3],-1))*(det[:,1::3]-tf.reduce_mean(det[:,1::3],-1)),-1) / tf.reduce_sum((norm_det[:,1::3]-tf.reduce_mean(norm_det[:,1::3],-1))**2,-1)
172 z_sc = tf.reduce_sum((norm_det[:,2::3]-tf.reduce_mean(norm_det[:,2::3],-1))*(det[:,2::3]-tf.reduce_mean(det[:,2::3],-1)),-1) / tf.reduce_sum((norm_det[:,2::3]-tf.reduce_mean(norm_det[:,2::3],-1))**2,-1)
174 x_off = tf.reduce_mean(det[:,0::3],-1) - x_sc*tf.reduce_mean(norm_det[:,0::3],-1)
175 y_off = tf.reduce_mean(det[:,1::3],-1) - x_sc*tf.reduce_mean(norm_det[:,1::3],-1)
176 z_off = tf.reduce_mean(det[:,2::3],-1) - x_sc*tf.reduce_mean(norm_det[:,2::3],-1)
178 norm_det[:,0::3] *= x_sc
179 norm_det[:,1::3] *= y_sc
180 norm_det[:,2::3] *= z_sc
182 norm_det[:,0::3] += x_off
183 norm_det[:,1::3] += y_off
184 norm_det[:,2::3] += z_off
186 htype = tensor[0][:,0]
187 hprob = tensor[2][:,0]
189 return det, norm_det, htype, hprob
194 Post-process for the head landmarks use-case
197 tensor list(tf.Tensor): shape [(batch,1,1,keypoints*3),(batch,1,1),(batch,1)] FLOAT32 outputs of the head landmarks
200 det (tf.Tensor): shape (batch, keypoints*3) FLOAT32 3D detections of the head landmarks in pixels
201 hprob (tf.Tensor): shape (batch,) FLOAT32 presence probability of the head
204 det = tensor[0][:,0,0]
205 hprob = tensor[2][:,0]
def heatmaps_spe_postprocess(tf.Tensor tensor)
def yolo_mpe_postprocess(tf.Tensor tensor, int max_output_size=20, float iou_threshold=0.7, float score_threshold=0.25)
def _padded_nms(tf.Tensor tensor, int max_output_size, float iou_threshold, float score_threshold)
def head_landmarks_postprocess([tf.Tensor] tensor)
def hand_landmarks_postprocess([tf.Tensor] tensor)
def spe_postprocess(tf.Tensor tensor)