Exemple #1
0
    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
Exemple #2
0
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)
Exemple #4
0
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)
Exemple #5
0
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")
Exemple #6
0
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
Exemple #7
0
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)
Exemple #8
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
Exemple #9
0
 def facePointsStasm(self, img):
     return locator.face_points(img)