Spaces:
Sleeping
Sleeping
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| from matplotlib.patches import Rectangle | |
| import copy | |
| import tensorflow.keras.backend as K | |
| import cv2 | |
| from face_detection.config import cell_size,idx_to_class,class_to_idx,class_colors | |
| def get_objects(y_pred,p=0.5,decode_preds=True): | |
| global tf_anchors | |
| output_size=y_pred.shape[1] | |
| image_size=cell_size*output_size | |
| y_pred=copy.deepcopy(y_pred) | |
| if decode_preds: | |
| y_pred[...,0]=K.sigmoid(y_pred[...,0]) | |
| y_pred[...,3:5]=np.clip((K.exp(y_pred[...,3:5])*tf_anchors).numpy(),0,output_size) | |
| # y_pred[...,3:5]=np.clip(y_pred[...,3:5],0,output_size) | |
| objs_found=[] | |
| idxs=np.where(y_pred[...,0]>=p) | |
| if np.size(idxs): | |
| for i,obj in enumerate(y_pred[idxs[0],idxs[1],idxs[2],:]): | |
| # obj (p,x,y,w,h,c_1,c_2,c_3,c_4,c_5.......c_n) | |
| if decode_preds: | |
| obj[1:3]=K.sigmoid(obj[1:3]) # x,y | |
| prob=obj[0] | |
| obj=obj[1:] | |
| obj[4]=np.argmax(obj[4:]) | |
| obj=obj[:5] | |
| obj[0]=idxs[1][i]+obj[0] # center x | |
| obj[1]=idxs[0][i]+obj[1] # center y | |
| obj[0]=np.clip(obj[0]-(obj[2]/2),0,output_size) # xmin | |
| obj[1]=np.clip(obj[1]-(obj[3]/2),0,output_size) # ymin | |
| obj_name=idx_to_class[obj[4]] | |
| # obj_details={'p':prob,'xywh':list(obj[:-1]/output_size),'class_idx':int(obj[4]),'class':obj_name} # xywh are scaled 0 to 1 | |
| obj_details=[prob,obj[4],*list(obj[:-1]/output_size)] # xywh are scaled 0 to 1 [P,C_IDX,X,Y,W,H] | |
| objs_found.append(obj_details) | |
| return np.array(objs_found) | |
| def list_get_iou(bboxes1, bboxes2): | |
| # bboxes has xywh => xmin,ymin,width,height | |
| bboxes1 = [bboxes1[0],bboxes1[1],bboxes1[0]+bboxes1[2],bboxes1[1]+bboxes1[3]] | |
| bboxes2 = [bboxes2[0],bboxes2[1],bboxes2[0]+bboxes2[2],bboxes2[1]+bboxes2[3]] | |
| xA = max(bboxes1[0], bboxes2[0]) | |
| yA = max(bboxes1[1], bboxes2[1]) | |
| xB = min(bboxes1[2], bboxes2[2]) | |
| yB = min(bboxes1[3], bboxes2[3]) | |
| intersection_area = max(0, xB - xA ) * max(0, yB - yA ) | |
| box1_area = (bboxes1[2] - bboxes1[0] ) * (bboxes1[3] - bboxes1[1] ) | |
| box2_area = (bboxes2[2] - bboxes2[0] ) * (bboxes2[3] - bboxes2[1] ) | |
| iou = intersection_area / float(box1_area + box2_area - intersection_area+1e-6) | |
| return iou | |
| def np_iou(bboxes1,bboxes2): | |
| # bboxes has xywh => xmin,ymin,width,height | |
| boxes1_x1 = bboxes1[:,0] | |
| boxes1_y1 = bboxes1[:,1] | |
| boxes1_x2 = boxes1_x1 + bboxes1[:,2] | |
| boxes1_y2 = boxes1_y1 + bboxes1[:,3] | |
| boxes2_x1 = bboxes2[:,0] | |
| boxes2_y1 = bboxes2[:,1] | |
| boxes2_x2 = boxes2_x1 + bboxes2[:,2] | |
| boxes2_y2 = boxes2_y1 + bboxes2[:,3] | |
| xmins = np.maximum(boxes1_x1,boxes2_x1) | |
| ymins = np.maximum(boxes1_y1,boxes2_y1) | |
| xmaxs = np.minimum(boxes1_x2,boxes2_x2) | |
| ymaxs = np.minimum(boxes1_y2,boxes2_y2) | |
| intersection = np.clip((xmaxs-xmins),0,None)*np.clip((ymaxs-ymins),0,None) | |
| union = (boxes1_x2-boxes1_x1)*(boxes1_y2-boxes1_y1) + (boxes2_x2-boxes2_x1)*(boxes2_y2-boxes2_y1) | |
| ious=intersection/((union-intersection)+1e-6) | |
| return ious | |
| def nms(objs_found,iou_threshold=0.2): | |
| '''objs_found list of list:[ | |
| [p,c_idx,x,y,w,h], | |
| [p,c_idx,x,y,w,h] | |
| ] | |
| ''' | |
| if objs_found.size<2 or iou_threshold==1: return objs_found | |
| objs_found=objs_found[np.argsort(objs_found[:,0])[::-1] ]# This was very important | |
| best_boxes=[] | |
| while len(objs_found)>0: | |
| obj=objs_found[0] | |
| best_boxes.append(list(obj)) | |
| objs_found=objs_found[1:].reshape(-1,6) | |
| if len(objs_found)>0: | |
| same_class_idxs=np.where(objs_found[:,1]==obj[1])[0] # same class_idx | |
| same_class_objs=objs_found[same_class_idxs].reshape(-1,6) | |
| ious=np_iou(obj[None,2:],same_class_objs[:,2:]) | |
| delete_idxs=same_class_idxs[np.where(ious>= iou_threshold)[0]] | |
| objs_found=np.delete(objs_found,delete_idxs,axis=0) | |
| return best_boxes | |
| def show_objects(img,objs_found,return_img=False): | |
| plt.imshow(img) | |
| for i in range(len(objs_found)): | |
| p=objs_found[i]['p'] | |
| obj=objs_found[i]['xywh'] | |
| obj_name=objs_found[i]['class'] | |
| plt.gca().add_patch(Rectangle((obj[0],obj[1]),(obj[2]),(obj[3]),linewidth=4,edgecolor=class_colors[obj_name],facecolor='none')) | |
| plt.text(obj[0],obj[1],obj_name) | |
| def pred_image(img,objs_found,font_scale=2,thickness=4): | |
| def rescale(obj_found,w,h): | |
| # xywh | |
| obj_found[0]*=w | |
| obj_found[1]*=h | |
| obj_found[2]*=w | |
| obj_found[3]*=h | |
| return obj_found | |
| for i in range(len(objs_found)): | |
| # p,c_idx,x,y,w,h | |
| p=objs_found[i][0] | |
| obj_name=objs_found[i][1] | |
| obj=rescale(objs_found[i][2:],img.shape[1],img.shape[0]) | |
| img=cv2.rectangle(img,(int(obj[0]),int(obj[1])),(int(obj[0]+obj[2]),int(obj[1]+obj[3])),(class_colors[obj_name]*255),thickness) | |
| img=cv2.putText(img,obj_name,(int(obj[0]),int(obj[1])),cv2.FONT_HERSHEY_SIMPLEX,font_scale, (0,0,0), thickness, lineType=cv2.LINE_AA) | |
| # draw_text(img, "world", font_scale=4, pos=(10, 20 + h), text_color_bg=(255, 0, 0)) | |
| return img |