def im_test(im): face_info = lib.align(im[:, :, (2, 1, 0)], front_face_detector, lmark_predictor) # Samples if len(face_info) == 0: logging.warning('No faces are detected.') prob = -1 # we ignore this case else: # Check how many faces in an image logging.info('{} faces are detected.'.format(len(face_info))) max_prob = -1 # If one face is fake, the image is fake for _, point in face_info: rois = [] for i in range(sample_num): roi, _ = lib.cut_head([im], point, i) rois.append(cv2.resize(roi[0], tuple(cfg.IMG_SIZE[:2]))) vis_im(rois, 'tmp/vis.jpg') prob = solver.test(rois) prob = np.mean( np.sort(prob[:, 0])[np.round(sample_num / 2).astype(int):]) if prob >= max_prob: max_prob = prob prob = max_prob return prob
def preprocess(im, willSimulateDeepfake=False): ''' Given an image, attempts to detect a face. If none is found, returns None. Returns the image resized to as specified by IMG_SIZE. If instructed to simulate Deepfake, simulation will be applied before resizing. ''' # list of tuples of (transformation matrix, landmark point) of identified faces faces = lib.align(im[:, :, (2, 1, 0)], front_face_detector, lmark_predictor) if len(faces) == 0: return None trans_matrix, point = faces[0] # take only the first face found if willSimulateDeepfake: im = simulateDeepfake(im, trans_matrix, point) # GENERALIZATION STEP. REMOVED AFTER ACCURACY LOWERED. # crop image, after randomly expanding ROI (minimum bounding box b) in each direction between # [0, h/5] and [0, w/8] where h, w are height and width of b. then resize to 256 x 256 for final training data # rois, _ = lib.cut_head([im], point, random.randint(0, 10)) # cropped_output_im = cv2.resize(rois[0], (IMG_SIZE, IMG_SIZE)) im = cv2.resize(im, (IMG_SIZE, IMG_SIZE)) return im
def preprocess(im): # refactored out of preprocess.py to accommodate the requirements of PyQt5 ''' Given an input image, preprocess it the same way as training/testing samples and return the output image. ''' # image size = input size to model IMG_SIZE = 256 front_face_detector = dlib.get_frontal_face_detector() lmark_predictor = dlib.shape_predictor('./dlib_model/shape_predictor_68_face_landmarks.dat') # list of tuples of (transformation matrix, landmark point) of identified faces faces = lib.align(im[:, :, (2,1,0)], front_face_detector, lmark_predictor) if len(faces) == 0: return None # PART REMOVED DUE TO LOWER ACCURACY # take only the first face found # trans_matrix, _ = faces[0] # face = cv2.warpAffine(im, trans_matrix * FACE_SIZE, (FACE_SIZE, FACE_SIZE)) # simply resizing without cropping in to facial region, as accuracy has been found to have increased im = cv2.resize(im, (IMG_SIZE, IMG_SIZE)) return im
def __init__(self, face_img_dir, cache_path): self.face_img_dir = face_img_dir self.face_img_paths = [ os.path.join(face_img_dir, im_name) for im_name in sorted(os.listdir(face_img_dir)) ] self.data_num = len(self.face_img_paths) self.cache_path = cache_path # Get landmarks face_caches = self._load_cache() if face_caches is None: # Load dlib self._set_up_dlib() face_caches = {} # Align faces print("Aligning faces...") for i, im_path in enumerate(tqdm(self.face_img_paths)): im = cv2.imread(str(im_path)) faces = lib.align(im[:, :, (2, 1, 0)], self.front_face_detector, self.lmark_predictor) if len(faces) == 0: faces = [None, None] else: faces = faces[0] face_caches[self.face_img_paths[i].stem] = faces self._save_cache(face_caches) self.face_caches = face_caches
def im_test(net, im, args): face_info = lib.align(im[:, :, (2, 1, 0)], front_face_detector, lmark_predictor) # Samples if len(face_info) != 1: prob = -1 else: _, point = face_info[0] rois = [] for i in range(sample_num): roi, _ = lib.cut_head([im], point, i) rois.append(cv2.resize(roi[0], (args.input_size, args.input_size))) # vis_ = np.concatenate(rois, 1) # cv2.imwrite('vis.jpg', vis_) bgr_mean = np.array([103.939, 116.779, 123.68]) bgr_mean = bgr_mean[np.newaxis, :, np.newaxis, np.newaxis] bgr_mean = torch.from_numpy(bgr_mean).float().cuda() rois = torch.from_numpy(np.array(rois)).float().cuda() rois = rois.permute((0, 3, 1, 2)) prob = net(rois - bgr_mean) prob = F.softmax(prob, dim=1) prob = prob.data.cpu().numpy() prob = 1 - np.mean( np.sort(prob[:, 0])[np.round(sample_num / 2).astype(int):]) return prob, face_info
def __init__( self, input_vid_path, output_height=300, ): # Input video self.input_vid_path = input_vid_path # parse video print('Parsing video {}'.format(str(self.input_vid_path))) self.imgs, self.frame_num, self.fps, self.img_w, self.img_h = pv.parse_vid( str(self.input_vid_path)) if len(self.imgs) != self.frame_num: warnings.warn( 'Frame number is not consistent with the number of images in video...' ) self.frame_num = len(self.imgs) print('Eye blinking solution is building...') self._set_up_dlib() self.output_height = output_height factor = float(self.output_height) / self.img_h # Resize imgs for final video generation # Resize self.imgs according to self.output_height self.aligned_imgs = [] self.left_eyes = [] self.right_eyes = [] self.resized_imgs = [] print('face aligning...') for i, im in enumerate(tqdm(self.imgs)): face_cache = lib.align(im[:, :, (2, 1, 0)], self.front_face_detector, self.lmark_predictor) if len(face_cache) == 0: self.left_eyes.append(None) self.right_eyes.append(None) continue if len(face_cache) > 1: raise ValueError( '{} faces are in image, we only support one face in image.' ) aligned_img, aligned_shapes_cur = lib.get_aligned_face_and_landmarks( im, face_cache) # crop eyes leye, reye = lib.crop_eye(aligned_img[0], aligned_shapes_cur[0]) self.left_eyes.append(leye) self.right_eyes.append(reye) im_resized = cv2.resize(im, None, None, fx=factor, fy=factor) self.resized_imgs.append(im_resized) # For visualize self.plot_vis_list = [] self.total_eye1_prob = [] self.total_eye2_prob = []