def swap(sF, iF, sT, iT): warp_2d = True ##!! correct_color = True ##!! # Select src face src_points, src_shape, src_face = select_face(sF, iF) viewOriginal(src_face) # Select dst face dst_points, dst_shape, dst_face = select_face(sT, iT) viewOriginal(dst_face) w, h = dst_face.shape[:2] ### Warp Image if not warp_2d: ## 3d warp warped_src_face = warp_image_3d(src_face, src_points[:48], dst_points[:48], (w, h)) else: ## 2d warp src_mask = mask_from_points(src_face.shape[:2], src_points) src_face = apply_mask(src_face, src_mask) # Correct Color for 2d warp if correct_color: warped_dst_img = warp_image_3d(dst_face, dst_points[:48], src_points[:48], src_face.shape[:2]) src_face = correct_colours(warped_dst_img, src_face, src_points) # Warp warped_src_face = warp_image_2d( src_face, transformation_from_points(dst_points, src_points), (w, h, 3)) ## Mask for blending mask = mask_from_points((w, h), dst_points) mask_src = np.mean(warped_src_face, axis=2) > 0 mask = np.asarray(mask * mask_src, dtype=np.uint8) ## Correct color if not warp_2d and correct_color: warped_src_face = apply_mask(warped_src_face, mask) dst_face_masked = apply_mask(dst_face, mask) warped_src_face = correct_colours(dst_face_masked, warped_src_face, dst_points) ## Shrink the mask kernel = np.ones((10, 10), np.uint8) mask = cv2.erode(mask, kernel, iterations=1) ##Poisson Blending r = cv2.boundingRect(mask) center = ((r[0] + int(r[2] / 2), r[1] + int(r[3] / 2))) output = cv2.seamlessClone(warped_src_face, dst_face, mask, center, cv2.NORMAL_CLONE) x, y, w, h = dst_shape dst_img_cp = iT.copy() dst_img_cp[y:y + h, x:x + w] = output output = dst_img_cp return output
def apply_facial_features(src, dst, out, warp_2d = False, correct_color = True): # Read images src_img = cv2.imread(src) dst_img = cv2.imread(dst) # Select src face src_points, src_shape, src_face = select_face(src_img) # Select dst face dst_points, dst_shape, dst_face = select_face(dst_img) w, h = dst_face.shape[:2] # Warp Image if not warp_2d: # 3d warp warped_src_face = warp_image_3d(src_face, src_points[:48], dst_points[:48], (w, h)) else: # 2d warp src_mask = mask_from_points(src_face.shape[:2], src_points) src_face = apply_mask(src_face, src_mask) # Correct Color for 2d warp if correct_color: warped_dst_img = warp_image_3d(dst_face, dst_points[:48], src_points[:48], src_face.shape[:2]) src_face = correct_colours(warped_dst_img, src_face, src_points) # Warp warped_src_face = warp_image_2d(src_face, transformation_from_points(dst_points, src_points), (w, h, 3)) # Mask for blending mask = mask_from_points((w, h), dst_points) mask_src = np.mean(warped_src_face, axis=2) > 0 mask = np.asarray(mask * mask_src, dtype=np.uint8) # Correct color if not warp_2d and correct_color: warped_src_face = apply_mask(warped_src_face, mask) dst_face_masked = apply_mask(dst_face, mask) warped_src_face = correct_colours(dst_face_masked, warped_src_face, dst_points) # Shrink the mask kernel = np.ones((10, 10), np.uint8) mask = cv2.erode(mask, kernel, iterations=1) # Poisson Blending r = cv2.boundingRect(mask) center = ((r[0] + int(r[2] / 2), r[1] + int(r[3] / 2))) output = cv2.seamlessClone(warped_src_face, dst_face, mask, center, cv2.NORMAL_CLONE) x, y, w, h = dst_shape dst_img_cp = dst_img.copy() dst_img_cp[y:y + h, x:x + w] = output output = dst_img_cp dir_path = os.path.dirname(out) if not os.path.isdir(dir_path): os.makedirs(dir_path) cv2.imwrite(out, output)
h, w = dst_face.shape[:2] ### Warp Image if not args.warp_2d: ## 3d warp warped_src_face = warp_image_3d(src_face, src_points[:48], dst_points[:48], (h, w)) else: ## 2d warp src_mask = mask_from_points(src_face.shape[:2], src_points) src_face = apply_mask(src_face, src_mask) # Correct Color for 2d warp if args.correct_color: warped_dst_img = warp_image_3d(dst_face, dst_points[:48], src_points[:48], src_face.shape[:2]) src_face = correct_colours(warped_dst_img, src_face, src_points) # Warp warped_src_face = warp_image_2d(src_face, transformation_from_points(dst_points, src_points), (h, w, 3)) ## Mask for blending mask = mask_from_points((h, w), dst_points) mask_src = np.mean(warped_src_face, axis=2) > 0 mask = np.asarray(mask*mask_src, dtype=np.uint8) ## Correct color if not args.warp_2d and args.correct_color: warped_src_face = apply_mask(warped_src_face, mask) dst_face_masked = apply_mask(dst_face, mask) warped_src_face = correct_colours(dst_face_masked, warped_src_face, dst_points) ## Shrink the mask kernel = np.ones((10, 10), np.uint8) mask = cv2.erode(mask, kernel, iterations=1)
def insert_face(result, CROWD, scale): if result is None: return None, None result_bboxs = [] for faces in result: dst_points, dst_shape, dst_face = faces[0] src_points, src_shape, src_face = faces[1] w, h = dst_face.shape[:2] # 3d warp if face is big enough WARP_2D = True if (h / CROWD.shape[0]) >= FACE_FRAC_3D: WARP_2D = False ### Warp Image if not WARP_2D: ## 3d warp warped_src_face = warp_image_3d(src_face, src_points[:MAX_POINTS], dst_points[:MAX_POINTS], (w, h)) else: ## 2d warp src_mask = mask_from_points(src_face.shape[:2], src_points, radius=2) src_face = apply_mask(src_face, src_mask) # Correct Color for 2d warp if CORRECT_COLOR: warped_dst_img = warp_image_3d(dst_face, dst_points[:MAX_POINTS], src_points[:MAX_POINTS], src_face.shape[:2]) src_face = correct_colours(warped_dst_img, src_face, src_points) # Warp warped_src_face = warp_image_2d( src_face, transformation_from_points(dst_points, src_points), (w, h, 3)) ## Mask for blending mask = mask_from_points((w, h), dst_points, radius=2) mask_src = np.mean(warped_src_face, axis=2) > 0 mask = np.asarray(mask * mask_src, dtype=np.uint8) ## Correct color if not WARP_2D and CORRECT_COLOR: warped_src_face = apply_mask(warped_src_face, mask) dst_face_masked = apply_mask(dst_face, mask) warped_src_face = correct_colours(dst_face_masked, warped_src_face, dst_points) ##Poisson Blending r = cv2.boundingRect(mask) center = ((r[0] + int(r[2] / 2), r[1] + int(r[3] / 2))) output = cv2.seamlessClone(warped_src_face, dst_face, mask, center, cv2.NORMAL_CLONE) x, y, w, h = dst_shape result_bboxs.append([x, y, x + w, y + h]) CROWD[y:y + h, x:x + w] = output return CROWD, result_bboxs