File size: 1,849 Bytes
03da825
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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:
            # calculate 5 facial landmarks using 68 landmarks
            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