|
import os.path as osp |
|
from PIL import Image |
|
import numpy as np |
|
|
|
from additional_modules.deep3dfacerecon.util.load_mats import load_lm3d |
|
from additional_modules.deep3dfacerecon.util.preprocess import align_img |
|
|
|
|
|
TARGET_SIZE = 1024. |
|
RESCALE_FACTOR = 300 |
|
CENTER_CROP_SIZE = 700 |
|
OUTPUT_SIZE = 512 |
|
|
|
|
|
class ImageCropper: |
|
def __init__(self, lm3d=None): |
|
bfm_folder = osp.join('additional_modules/deep3dfacerecon/BFM') |
|
if lm3d is None: |
|
self.lm3d_std = load_lm3d(bfm_folder) |
|
else: |
|
|
|
lm_idx = np.array([31, 37, 40, 43, 46, 49, 55]) - 1 |
|
lm3d_5p = np.stack([lm3d[lm_idx[0], :], np.mean(lm3d[lm_idx[[1, 2]], :], 0), np.mean( |
|
lm3d[lm_idx[[3, 4]], :], 0), lm3d[lm_idx[5], :], lm3d[lm_idx[6], :]], axis=0) |
|
lm3d_5p = lm3d_5p[[1, 2, 0, 3, 4], :] |
|
self.lm3d_std = lm3d_5p |
|
|
|
def __call__(self, im, lm): |
|
_, H = im.size |
|
lm = lm.copy() |
|
lm_orig = lm.copy() |
|
lm[:, -1] = H - 1 - lm[:, -1] |
|
|
|
_, im_high, _, lm_high, _, _ = align_img( |
|
im, lm, lm_orig, self.lm3d_std, target_size=TARGET_SIZE, rescale_factor=RESCALE_FACTOR |
|
) |
|
|
|
left = int(im_high.size[0]/2 - CENTER_CROP_SIZE/2) |
|
upper = int(im_high.size[1]/2 - CENTER_CROP_SIZE/2) |
|
right = left + CENTER_CROP_SIZE |
|
lower = upper + CENTER_CROP_SIZE |
|
im_cropped = im_high.crop((left, upper, right, lower)) |
|
|
|
lm_cropped = lm_high.copy() |
|
lm_cropped[..., 0] -= left |
|
lm_cropped[..., 1] -= upper |
|
lm_cropped[..., 0] *= OUTPUT_SIZE / im_cropped.size[0] |
|
lm_cropped[..., 1] *= OUTPUT_SIZE / im_cropped.size[1] |
|
|
|
im_cropped = im_cropped.resize((OUTPUT_SIZE, OUTPUT_SIZE), resample=Image.LANCZOS) |
|
|
|
return im_cropped, lm_cropped |
|
|