def random_warp(img, mult_f=1):
    """
    Get pair of random warped images from aligned face image.
    For now assumes input image to be 256x256, and base returning size of 64x64
    :param img:
    :param mult_f: determines size of returned images (multiply each dimension, e.g. 2 for 128x128)
    :return:
    """
    assert img.shape == (256, 256, 3)
    #range_ = np.linspace(128 - 80, 128 + 80, 5)
    range_ = np.linspace(128 - 110, 128 + 110, 5)
    mapx = np.broadcast_to(range_, (5, 5))
    mapy = mapx.T

    mapx = mapx + np.random.normal(size=(5, 5), scale=5)
    mapy = mapy + np.random.normal(size=(5, 5), scale=5)

    interp_mapx = cv2.resize(mapx, (80*mult_f, 80*mult_f))[8*mult_f:72*mult_f, 8*mult_f:72*mult_f].astype('float32')
    interp_mapy = cv2.resize(mapy, (80*mult_f, 80*mult_f))[8*mult_f:72*mult_f, 8*mult_f:72*mult_f].astype('float32')

    warped_image = cv2.remap(img, interp_mapx, interp_mapy, cv2.INTER_LINEAR)

    src_points = np.stack([mapx.ravel(), mapy.ravel()], axis=-1)
    dst_points = np.mgrid[0:65*mult_f:16*mult_f, 0:65*mult_f:16*mult_f].T.reshape(-1, 2)
    mat = _umeyama(src_points, dst_points, True)[0:2]

    target_image = cv2.warpAffine(img, mat, (64*mult_f, 64*mult_f))

    target_image = cv2.resize(target_image, (64*mult_f, 64*mult_f))
    warped_image = cv2.resize(warped_image, (64*mult_f, 64*mult_f))

    return warped_image, target_image
Beispiel #2
0
def get_align_matrix(src_landmarks, target_landmarks, translation: tuple = None):
    align_matrix = _umeyama(src_landmarks, target_landmarks, True)[:2]

    if translation:
        align_matrix[0, 2] -= translation[0]//2
        align_matrix[1, 2] -= translation[1]//2

    return align_matrix
Beispiel #3
0
 def _umeyama(self):
     """For this class we want to have _umeyama without scaling."""
     # the call signature for _umeyama is (src, dst)
     # which is the reverse of ours
     return _umeyama(self.Y, self.X, False)
Beispiel #4
0
 def _umeyama(self):
     """Calculate Umeyama: for similarity we want to have scaling."""
     # the call signature for _umeyama is (src, dst)
     # which is the reverse of ours
     return _umeyama(self.Y, self.X, True)