def detect_faces(args, img, min_face_size=MIN_FACE_SIZE, thresholds=THRESHOLDS, nms_thresholds=NMS_THRESHOLDS): pnet, rnet, onet = load_net(args, 'pnet'), load_net(args, 'rnet'), load_net(args, 'onet') # STAGE 1 bounding_boxes = pnet_boxes(img, pnet, show_boxes=False) # STAGE 2 bounding_boxes = rnet_boxes(img, rnet, bounding_boxes, show_boxes=False) # STAGE 3 bounding_boxes, landmarks = onet_boxes(img, onet, bounding_boxes, show_boxes=True) return bounding_boxes, landmarks
def onet_test(args, img_path): img = load_img(img_path) net = load_net(args, 'pnet') output = net((transforms.ToTensor()(img.resize( (12, 12), Image.BILINEAR))).unsqueeze(0)) print('prob:', output[0]) show_bboxes(img, [[(250 * t.item() + 250 * (i > 1)) for i, t in enumerate(output[1][0])]]).show()
def img_face_detect(args, img_path, th=[0.6, 0.7, 0.8]): img = None try: print('===> loading the img...') img = Image.open(img_path) img = img.convert('RGB') except Exception: print('*** warning loading fail!') return img_tensor = transforms.ToTensor()(img).unsqueeze(0) pnet, rnet, onet = load_net(args, 'pnet'), load_net(args, 'rnet'), load_net( args, 'onet') resize_ratio = 0.7071 det, box, _ = pnet(img_tensor) det_faces = det.ge(th[0]) print(det)
def create_rnet_data(save_dir_name='R_net_dataset', crop_size=24, use_rnet=False): def img2tensor(img): from torchvision import transforms pass def get_name_from_path(img_path): return osp.splitext(osp.split(img_path)[1])[0] def make_dir(save_dir): if not osp.exists(save_dir): os.makedirs(save_dir) def crop_img(img_np, crop_box, crop_size): # print('img_np:{}, crop_box:{}'.format(img_np, crop_box)) # print('img_np.shape:{}'.format(img_np.shape)) crop_img_np = img_np[crop_box[1]:crop_box[3], crop_box[0]:crop_box[2], :] # print('crop_img_np size:{}'.format(crop_img_np)) crop_img = Image.fromarray(crop_img_np) crop_img = crop_img.resize((crop_size, crop_size), resample=PIL.Image.BILINEAR) return crop_img def limit_box(box): new_box = [ min(max(0, int(box[i])), width if i % 2 == 0 else hight) for i in range(4) ] return new_box def cal_offset(face, box): offset = [ (face[0] - box[0]) / float(box[2] - box[0]), (face[1] - box[1]) / float(box[3] - box[1]), (face[2] - box[2]) / float(box[2] - box[0]), (face[3] - box[3]) / float(box[3] - box[1]), ] return offset def cal_landmark_offset(box, ldmk): if ldmk is None: return [] else: minx, miny = box[0], box[1] w, h = box[2] - box[0], box[3] - box[1] ldmk_offset = [ (ldmk[i] - [minx, miny][i % 2]) / float([w, h][i % 2]) for i in range(len(ldmk)) ] # print('box:{},ldmk:{},ldmk_offset:{}'.format(box, ldmk, ldmk_offset)) return ldmk_offset def txt_to_write(path, label, offset, ldmk_offset): s = '' s += '{} '.format(path) s += '{} '.format(label) for i in offset: s += '{} '.format(i) for i in ldmk_offset: s += '{} '.format(i) s += '\n' print(s) return s from train import load_net, config from config import DEVICE import torch # args = config() dataset_args = dataset_config() pnet = load_net(dataset_args, net_name='pnet').to(torch.device('cpu')) # dataset_args = dataset_config() # [img_num*[absolute_img_path,[faces_num*4(which is x1,y1,w,h)]]] cls_img_faces = create_pnet_data_txt_parser( txt_path=dataset_args.class_data_txt_path, img_dir=dataset_args.class_data_dir) # [absolute_img_path,[x1,x2,y1,y2],(x,y)of[left_eye,right_eye,nose,mouse_left, mouse_right]] ldmk_img_faces = landmark_dataset_txt_parser( txt_path=dataset_args.landmark_data_txt_path, img_dir=dataset_args.landmark_data_dir) img_faces = ldmk_img_faces + cls_img_faces # img_faces = cls_img_faces + ldmk_img_faces output_path = osp.join(dataset_args.output_path, save_dir_name) make_dir(output_path) txt_path = osp.join(output_path, '{}.txt'.format(save_dir_name)) txt = open(txt_path, 'a') for img_face in tqdm(img_faces): # print('img_face:{}'.format(img_face)) img_path = img_face[0] img_name = get_name_from_path(img_path) save_dir = osp.join(output_path, img_name) make_dir(save_dir) faces = np.array(img_face[1]) # print('faces.ndim:{}'.format(faces.ndim)) if faces.ndim is 1: faces = np.expand_dims(faces, 0) faces[:, :] = faces[:, (0, 2, 1, 3)] else: faces[:, 2] += faces[:, 0] faces[:, 3] += faces[:, 1] # print('faces:{}'.format(faces)) ldmk = None if len(img_face) < 3 else [int(i) for i in img_face[2]] img = load_img(img_path) width, hight = img.size # print('width:{}, hight:{}'.format(width, hight)) img_np = np.array(img) # print('img_np:{}'.format(img_np)) bounding_boxes = pnet_boxes(img, pnet, show_boxes=1) bounding_boxes = rnet_boxes(img, rnet, bounding_boxes) if use_rnet: rnet = load_net(args, net_name='rnet').to(torch.device('cpu')) bounding_boxes = rnet_boxes(img, rnet, bounding_boxes) # print('bounding_boxes:{}'.format(bounding_boxes[:, 4])) # ioumax = 0.0 for id, box in enumerate(bounding_boxes, start=1): # box[(4+1)float] # print('box:{}'.format(box)) box = limit_box(box) # print('box:{},faces:{}'.format(box, faces)) iou = IoU(box, faces) iou_max = iou.max() iou_index = iou.argmax() closet_face = faces[iou_index] # print('iou_max:{}, iou_index:{}'.format(iou_max, iou_index)) # ioumax = max(iou, iou_max) img_box = crop_img(img_np=img_np, crop_box=box, crop_size=crop_size) # img_box.show() label = None # [(0, 0.3), (0.4, 0.65), (0.65, 1.0)] if iou <= 0.3: label = 'n' img_box_path = osp.join(save_dir, '{}_{:.8f}.jpg'.format(id, iou_max)) img_box.save(img_box_path, format='jpeg') txt.write( txt_to_write( osp.relpath(img_box_path, osp.split(txt_path)[0]), label, [], [])) pass elif 0.4 <= iou <= 0.65: label = 'pf' if ldmk is None else 'l' img_box_path = osp.join(save_dir, '{}_{:.8f}.jpg'.format(id, iou_max)) img_box.save(img_box_path, format='jpeg') offset = cal_offset(closet_face, box) ldmk_offset = cal_landmark_offset(box, ldmk) txt.write( txt_to_write( osp.relpath(img_box_path, osp.split(txt_path)[0]), label, offset, ldmk_offset)) pass elif 0.65 < iou: label = 'p' if ldmk is None else 'l' img_box_path = osp.join(save_dir, '{}_{:.8f}.jpg'.format(id, iou_max)) img_box.save(img_box_path, format='jpeg') offset = cal_offset(closet_face, box) ldmk_offset = cal_landmark_offset(box, ldmk) txt.write( txt_to_write( osp.relpath(img_box_path, osp.split(txt_path)[0]), label, offset, ldmk_offset)) # print('iou:{}'.format(iou)) txt.close()
crop_img, label, offset, ldmk = self.get_crop_img_label_offset_ldmk(img, faces, ldmk, index) if crop_img is None: return self.__getitem__(random.randint(0, self.__len__())) img_tensor = transforms.ToTensor()(crop_img) # label = torch.tensor([1.0]) if item[1] in ['p', 'pf', 'l'] else torch.tensor([0.0]) landmark_flag = torch.FloatTensor([1.0 if label == 'l' else 0.0]) label = torch.FloatTensor([1.0 if label in ['p', 'pf', 'l'] else 0.0]) offset = torch.FloatTensor(offset if 4 == len(offset) else 4 * [0.0]) landmark = torch.FloatTensor(ldmk if 10 == len(ldmk) else 10 * [0.0]) # print('label type:', label.type()) # print('data_imformation:', label, offset, landmark_flag, landmark) return (img_tensor, label, offset, landmark_flag, landmark) def __len__(self): # self.ct += 1 # return self.ct return len(self.img_faces) if __name__ == '__main__': from create_dataset import create_pnet_data_txt_parser, landmark_dataset_txt_parser, dataset_config args = dataset_config() img_faces = create_pnet_data_txt_parser(args.class_data_txt_path, args.class_data_dir) img_face_landmark = landmark_dataset_txt_parser(args.landmark_data_txt_path, args.landmark_data_dir) IDS = InplaceDataset(img_face_landmark, img_faces, cropsize=48, pnet=load_net(args, 'pnet'), rnet=load_net(args, 'rnet')) for i, (img_tensor, label, offset, landmark_flag, landmark) in enumerate(IDS): print(label, offset, landmark_flag, landmark) print(i) pass