def warpAddTemplate( self, before_img, after_img, after_mask, use_stasm=True, ): before_shape = before_img.shape after_shape = after_img.shape if use_stasm: before_points = locator.face_points(before_img) after_points = locator.face_points(after_img) else: before_points = self.facePoints(before_img) after_points = self.facePoints(after_img) before_points = np.clip(before_points, 0, min(np.array(before_shape[:2]) - 2)) after_points = np.clip(after_points, 0, min(np.array(after_shape[:2]) - 2)) mask_transformed = warp_image(after_mask, after_points, before_points, before_shape) result = before_img.astype(float) + (mask_transformed.astype(float) - 127) * 2 result = np.clip(result, 0, 255).astype(np.uint8) # return result return result, mask_transformed
def load_image_points(path, size): img = cv2.imread(path) points = locator.face_points(img) if len(points) == 0: print('No face in %s' % path) return None, None else: center_fore_head = points[14] center_tip_of_chin = points[6] angle = calc_angle(center_fore_head, center_tip_of_chin) img = rotate(img, -angle, ((center_fore_head[0] + center_tip_of_chin[0]) // 2, (center_fore_head[1] + center_tip_of_chin[1]) // 2)) points = locator.face_points(img) return aligner.resize_align(img, points, size)
def load_image_points(path, size): img = cv2.imread(path) points = locator.face_points(img) if len(points) == 0: print('No face in %s' % path) return None, None else: return aligner.resize_align(img, points, size)
def load_image_points(path, size): img = scipy.ndimage.imread(path)[..., :3] points = locator.face_points(path) if len(points) == 0: print('No face in %s' % path) return None, None else: return aligner.resize_align(img, points, size)
def alignment(content, style): content_img = np.array(Image.from_file(content).data) style_img = np.array(Image.from_file(style).data) content_name = os.path.splitext(content)[0] style_name = os.path.splitext(style)[0] # extraction of facial landmarks content_pts = locator.face_points(content_img, add_boundary_points=True) style_pts = locator.face_points(style_img, add_boundary_points=True) # translation in terms of coordinates content_coords = warper.grid_coordinates(content_pts) style_coords = warper.grid_coordinates(style_pts) # warp the face from the style image, given the extracted landmarks style_aligned_img = warper.warp_image(style_img, style_pts, content_pts, \ content_img.shape) PIL.Image.fromarray(style_aligned_img).save(style_name+"_aligned.png") # apply the warped face from the style image on the content image mask = np.ma.masked_greater(style_aligned_img, 0) content_img[(mask!=0)] = 0 content_aligned_img = style_aligned_img + content_img PIL.Image.fromarray(content_aligned_img).save(content_name+"_aligned.png") # obtain a delaunay triangulation of the style image's facial landmarks delaunay_style = spatial.Delaunay(style_pts) # visualize the delaunay triangulation of the style image's facial landmarks plt.triplot(style_pts[:,0], style_pts[:,1], delaunay_style.simplices.copy()) plt.imshow(style_img) plt.plot(style_pts[:,0], style_pts[:,1], 'o') plt.savefig(style_name+"_delaunay.png") # apply the same triangulation to the new image, warped to fit the content # and visualize it plt.figure() plt.triplot(content_pts[:,0], content_pts[:,1], delaunay_style.simplices.copy()) plt.imshow(content_aligned_img) plt.plot(content_pts[:,0], content_pts[:,1], 'o') plt.savefig(content_name+"_aligned_delaunay.png")
def load_image_points(path, size): if os.path.isfile(path): img = cv2.imread(path) points = locator.face_points(img) if len(points) == 0: print('No face in %s' % path) return None, None else: return aligner.resize_align(img, points, size) else: print("load_image_points cannot find image [{}]".format(path)) return None, None
def check_for_image_points(path): points = [] try: print("check_for_image_points 1") if os.path.isfile(path): img = cv2.imread(path) print("check_for_image_points 2: read image") points = locator.face_points(img) print("check_for_image_points 3: {}".format(len(points))) else: print("check_for_image_points - file does not exist: {}".format( path)) except: sMsg = get_error_message() DoError("check_for_image_points: ") return (len(points) > 0)
def warpFace(self, before_img, after_img, before_points = None, after_points = None, use_poisson = True, use_stasm = True, additional_gaussian = False, clone_method = cv2.NORMAL_CLONE, use_tps = False, extra_blending_for_extreme = False, hue_threshold = 0.15, extra_blending_weight = 0.6, adjust_value = False ): before_shape = before_img.shape after_shape = after_img.shape if use_stasm: if before_points is None: before_points = locator.face_points(before_img) if after_points is None: after_points = locator.face_points(after_img) else: if before_points is None: before_points = self.facePoints(before_img) if after_points is None: after_points = self.facePoints(after_img) # before_points = np.clip(before_points, 0, min(np.array(before_shape[:2]) - 2)) # after_points = np.clip(after_points, 0, min(np.array(after_shape[:2]) - 2)) result_points = before_points if additional_gaussian: norm = before_points[52] std = np.linalg.norm(before_points[14] - before_points[6]) / 3 x, y = np.mgrid[0:before_shape[0]:1, 0:before_shape[1]:1] pos = np.empty(x.shape + (2,)) pos[:, :, 0] = x; pos[:, :, 1] = y rv = multivariate_normal(norm[::-1], [[std**2,0], [0,std**2]]) gauss_mask = rv.pdf(pos) gauss_mask /= gauss_mask.max() gauss_mask = np.expand_dims(gauss_mask, axis=2) x,y,w,h = cv2.boundingRect(np.array([before_points], np.int32)) # (x, y, w, h) from the top-left coordinates size = (w,h) if use_tps: if before_shape[0] > after_shape[0] or before_shape[1] > after_shape[1]: expanded = np.zeros( (max(before_shape[0], after_shape[0]), max(before_shape[1], after_shape[1]), 3), dtype = np.uint8) expanded[:after_shape[0], :after_shape[1], :] = after_img else: expanded = after_img after_transformed = warpImageTPS(after_points, result_points, cropImageByPointsConvex(expanded, after_points)) after_transformed = after_transformed[:before_shape[0], :before_shape[1], :] self.after_transformed = after_transformed else: after_transformed = warp_image(after_img, after_points, result_points, before_shape) self.after_transformed = after_transformed # black_mask = after_transformed.astype(np.float).sum(axis=2) == 0 # face_mask = after_transformed.astype(np.float).sum(axis=2) != 0 black_mask = after_transformed.astype(np.float).sum(axis=2) == 0 black_mask = np.logical_or(black_mask, before_img.astype(np.float).sum(axis=2) == 0) face_mask = np.logical_not(black_mask) nonzero_x, nonzero_y = face_mask.nonzero() x1, x2 = nonzero_x.min(), nonzero_x.max() y1, y2 = nonzero_y.min(), nonzero_y.max() # print(y1, x1, y2, x2) # print(x, y, x+w, y+h) x = y1 y = x1 w = (y2-y1) h = (x2-x1) poisson_face = cv2.seamlessClone(after_transformed, before_img, face_mask.astype(np.uint8) * 255, (x+w//2,y+h//2), clone_method) self.poisson_face = poisson_face self.face_mask_binary = face_mask self.face_mask = np.repeat(np.expand_dims(face_mask, 2), 3, axis = 2).astype(np.uint8) * 255 black_mask = np.expand_dims(black_mask, axis=2) face_mask = np.expand_dims(face_mask, axis=2) if additional_gaussian: result_img = before_img.astype(np.float) * (black_mask + face_mask * (1-gauss_mask)) \ + poisson_face.astype(np.float) * gauss_mask * face_mask else: result_img = before_img * (black_mask) + poisson_face * face_mask result_img = result_img.astype(np.uint8) '''extra image blending to fix the color blending effect''' if extra_blending_for_extreme: before_hue_mask = faceMaskByHue(before_img[:,:,::-1], threshold = hue_threshold) after_hue_mask = faceMaskByHue(after_transformed[:,:,::-1], threshold = hue_threshold) before_face_mask = getConvexMask(before_img, before_points)[:,:,0] after_face_mask = getConvexMask(after_transformed, after_points)[:,:,0] before_combined_mask = np.logical_and(before_hue_mask, before_face_mask) after_combined_mask = ~after_hue_mask self.after_combined_mask = after_combined_mask before_combined_mask = np.expand_dims(before_combined_mask, axis = 2) after_combined_mask = np.expand_dims(after_combined_mask, axis = 2) combined = (after_combined_mask * extra_blending_weight) * after_transformed.astype(float) + \ (after_combined_mask * (1 - extra_blending_weight) + (~after_combined_mask)) * result_img.astype(float) combined = combined.astype(np.uint8) result_img = combined if adjust_value: result_hsv = matplotlib.colors.rgb_to_hsv(result_img[:,:,::-1]) before_hsv = matplotlib.colors.rgb_to_hsv(before_img[:,:,::-1]) result_value = result_hsv[:,:,2] before_value = before_hsv[:,:,2] result_value[result_value > before_value] = before_value[result_value > before_value] result_hsv[:,:,2] = result_value # Convert back to the BGR space result_img = matplotlib.colors.hsv_to_rgb(result_hsv).astype(np.uint8)[:,:,::-1] return result_img, result_points
def facePointsStasm(self, img): return locator.face_points(img)