|
|
"""This script is to load 3D face model for Deep3DFaceRecon_pytorch |
|
|
""" |
|
|
import os.path as osp |
|
|
from array import array |
|
|
|
|
|
import numpy as np |
|
|
from PIL import Image |
|
|
from scipy.io import loadmat |
|
|
from scipy.io import savemat |
|
|
|
|
|
|
|
|
def LoadExpBasis(bfm_folder="BFM"): |
|
|
n_vertex = 53215 |
|
|
Expbin = open(osp.join(bfm_folder, "Exp_Pca.bin"), "rb") |
|
|
exp_dim = array("i") |
|
|
exp_dim.fromfile(Expbin, 1) |
|
|
expMU = array("f") |
|
|
expPC = array("f") |
|
|
expMU.fromfile(Expbin, 3 * n_vertex) |
|
|
expPC.fromfile(Expbin, 3 * exp_dim[0] * n_vertex) |
|
|
Expbin.close() |
|
|
|
|
|
expPC = np.array(expPC) |
|
|
expPC = np.reshape(expPC, [exp_dim[0], -1]) |
|
|
expPC = np.transpose(expPC) |
|
|
|
|
|
expEV = np.loadtxt(osp.join(bfm_folder, "std_exp.txt")) |
|
|
|
|
|
return expPC, expEV |
|
|
|
|
|
|
|
|
|
|
|
def transferBFM09(bfm_folder="BFM"): |
|
|
print("Transfer BFM09 to BFM_model_front......") |
|
|
original_BFM = loadmat(osp.join(bfm_folder, "01_MorphableModel.mat")) |
|
|
shapePC = original_BFM["shapePC"] |
|
|
shapeEV = original_BFM["shapeEV"] |
|
|
shapeMU = original_BFM["shapeMU"] |
|
|
texPC = original_BFM["texPC"] |
|
|
texEV = original_BFM["texEV"] |
|
|
texMU = original_BFM["texMU"] |
|
|
|
|
|
expPC, expEV = LoadExpBasis() |
|
|
|
|
|
|
|
|
|
|
|
idBase = shapePC * np.reshape(shapeEV, [-1, 199]) |
|
|
idBase = idBase / 1e5 |
|
|
idBase = idBase[:, :80] |
|
|
|
|
|
exBase = expPC * np.reshape(expEV, [-1, 79]) |
|
|
exBase = exBase / 1e5 |
|
|
exBase = exBase[:, :64] |
|
|
|
|
|
texBase = texPC * np.reshape(texEV, [-1, 199]) |
|
|
texBase = texBase[:, :80] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
index_exp = loadmat(osp.join(bfm_folder, "BFM_front_idx.mat")) |
|
|
index_exp = index_exp["idx"].astype(np.int32) - 1 |
|
|
|
|
|
index_shape = loadmat(osp.join(bfm_folder, "BFM_exp_idx.mat")) |
|
|
index_shape = index_shape["trimIndex"].astype(np.int32) - 1 |
|
|
index_shape = index_shape[index_exp] |
|
|
|
|
|
idBase = np.reshape(idBase, [-1, 3, 80]) |
|
|
idBase = idBase[index_shape, :, :] |
|
|
idBase = np.reshape(idBase, [-1, 80]) |
|
|
|
|
|
texBase = np.reshape(texBase, [-1, 3, 80]) |
|
|
texBase = texBase[index_shape, :, :] |
|
|
texBase = np.reshape(texBase, [-1, 80]) |
|
|
|
|
|
exBase = np.reshape(exBase, [-1, 3, 64]) |
|
|
exBase = exBase[index_exp, :, :] |
|
|
exBase = np.reshape(exBase, [-1, 64]) |
|
|
|
|
|
meanshape = np.reshape(shapeMU, [-1, 3]) / 1e5 |
|
|
meanshape = meanshape[index_shape, :] |
|
|
meanshape = np.reshape(meanshape, [1, -1]) |
|
|
|
|
|
meantex = np.reshape(texMU, [-1, 3]) |
|
|
meantex = meantex[index_shape, :] |
|
|
meantex = np.reshape(meantex, [1, -1]) |
|
|
|
|
|
|
|
|
|
|
|
other_info = loadmat(osp.join(bfm_folder, "facemodel_info.mat")) |
|
|
frontmask2_idx = other_info["frontmask2_idx"] |
|
|
skinmask = other_info["skinmask"] |
|
|
keypoints = other_info["keypoints"] |
|
|
point_buf = other_info["point_buf"] |
|
|
tri = other_info["tri"] |
|
|
tri_mask2 = other_info["tri_mask2"] |
|
|
|
|
|
|
|
|
savemat( |
|
|
osp.join(bfm_folder, "BFM_model_front.mat"), |
|
|
{ |
|
|
"meanshape": meanshape, |
|
|
"meantex": meantex, |
|
|
"idBase": idBase, |
|
|
"exBase": exBase, |
|
|
"texBase": texBase, |
|
|
"tri": tri, |
|
|
"point_buf": point_buf, |
|
|
"tri_mask2": tri_mask2, |
|
|
"keypoints": keypoints, |
|
|
"frontmask2_idx": frontmask2_idx, |
|
|
"skinmask": skinmask, |
|
|
}, |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
def load_lm3d(bfm_folder): |
|
|
|
|
|
Lm3D = loadmat(osp.join(bfm_folder, "similarity_Lm3D_all.mat")) |
|
|
Lm3D = Lm3D["lm"] |
|
|
|
|
|
|
|
|
lm_idx = np.array([31, 37, 40, 43, 46, 49, 55]) - 1 |
|
|
Lm3D = 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 = Lm3D[[1, 2, 0, 3, 4], :] |
|
|
|
|
|
return Lm3D |
|
|
|