Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7b7795d
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
4c69896
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
ad7847a
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
c2b9a96
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
d5c313d
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
9132cfd
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
0045a05
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
d777c06
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
443a83c
Fixes to run in 2025
gaurav-cointab Jul 29, 2025
c28dad2
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
408cf19
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
8bd5ccb
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
ab5f1b2
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
05958df
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
a6304f4
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
62c3d7c
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
0090287
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
eee2289
Fixes to run in 2025
gaurav-cointab Jul 30, 2025
73a647d
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
3e7cb91
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
02e3cc4
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
dc5ff0b
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
deb6bde
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
f874c88
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
97513c8
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
75b94fd
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
9020df2
Fixes to run in 2025
gaurav-cointab Aug 6, 2025
e5f858a
Changes to run demo teaser (#1)
gaurav-cointab Aug 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*.rar
*.tar
*.zip
.idea
data

# OS generated files #
######################
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
# Update to run in 2025

OS: Ubuntu 20.04<br/>
GPU: L4<br/>
CUDA: 12.4v<br/>

Step 1: Setup Env
>add-apt-repository ppa:deadsnakes/ppa -y<br/>
add-apt-repository ppa:ubuntu-toolchain-r/test -y<br/>
apt update<br/>
apt-get install python3.10 python3.10-venv python3.10-distutils libgl1 python3.10-dev gcc-11 g++-11<br/>

Step 2: Clone Repo & Setup DECA
>cd ~/DECA<br/>
python3.10 -m venv --without-pip deca<br/>
source deca/bin/activate<br/>
python --version<br/>
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py <br/>
python get-pip.py <br/>
pip install --upgrade pip setuptools wheel build cython<br/>
pip install torch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117 <br/>
pip install -r requirements.txt<br/>
bash fetch_data.sh<br/>

Step 4: Copy Relevant Data
1. Download file from "https://drive.usercontent.google.com/download?id=1rp8kdyLPvErw2dTmqtjISRVvQLj6Yzje&export=download&authuser=0"
2. Move it to data folder.
3. Follow https://github.com/TimoBolkart/BFM_to_FLAME to get FLAME_albedo_from_BFM.npz and copy to data folder. This is required to run demo_teaser.

Step 5: Run Reconstruct
>python demos/demo_reconstruct.py -i TestSamples/personal --saveDepth True --saveObj True -s TestSamples/personal/output --saveVis true --saveKpt true <br/>

Use Meshlab to view the output .obj files.<br/>
Or any other use case you want to. Other usecases, I have not tried, you are welcome to try them and fix them in your own forks.

# DECA: Detailed Expression Capture and Animation (SIGGRAPH2021)

<p align="center">
Expand Down
4 changes: 2 additions & 2 deletions decalib/datasets/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def video2sequence(video_path, sample_step=10):
return imagepath_list

class TestData(Dataset):
def __init__(self, testpath, iscrop=True, crop_size=224, scale=1.25, face_detector='fan', sample_step=10):
def __init__(self, testpath, iscrop=True, crop_size=224, scale=1.25, face_detector='fan', sample_step=10, device='cuda'):
'''
testpath: folder, imagepath_list, image path, video path
'''
Expand All @@ -68,7 +68,7 @@ def __init__(self, testpath, iscrop=True, crop_size=224, scale=1.25, face_detect
self.iscrop = iscrop
self.resolution_inp = crop_size
if face_detector == 'fan':
self.face_detector = detectors.FAN()
self.face_detector = detectors.FAN(device)
# elif face_detector == 'mtcnn':
# self.face_detector = detectors.MTCNN()
else:
Expand Down
21 changes: 11 additions & 10 deletions decalib/datasets/detectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
import torch

class FAN(object):
def __init__(self):
def __init__(self, device='cuda'):
import face_alignment
self.model = face_alignment.FaceAlignment(face_alignment.LandmarksType._2D, flip_input=False)
self.model = face_alignment.FaceAlignment(face_alignment.LandmarksType.TWO_D, flip_input=False, device=device)

def run(self, image):
'''
Expand All @@ -31,30 +31,31 @@ def run(self, image):
return [0], 'kpt68'
else:
kpt = out[0].squeeze()
left = np.min(kpt[:,0]); right = np.max(kpt[:,0]);
top = np.min(kpt[:,1]); bottom = np.max(kpt[:,1])
bbox = [left,top, right, bottom]
left = np.min(kpt[:, 0]);
right = np.max(kpt[:, 0]);
top = np.min(kpt[:, 1]);
bottom = np.max(kpt[:, 1])
bbox = [left, top, right, bottom]
return bbox, 'kpt68'


class MTCNN(object):
def __init__(self, device = 'cpu'):
def __init__(self, device='cpu'):
'''
https://github.com/timesler/facenet-pytorch/blob/master/examples/infer.ipynb
'''
from facenet_pytorch import MTCNN as mtcnn
self.device = device
self.model = mtcnn(keep_all=True)

def run(self, input):
'''
image: 0-255, uint8, rgb, [h, w, 3]
return: detected box
'''
out = self.model.detect(input[None,...])
out = self.model.detect(input[None, ...])
if out[0][0] is None:
return [0]
else:
bbox = out[0][0].squeeze()
return bbox, 'bbox'



5 changes: 4 additions & 1 deletion decalib/deca.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ def _create_model(self, model_cfg):
model_path = self.cfg.pretrained_modelpath
if os.path.exists(model_path):
print(f'trained model found. load {model_path}')
checkpoint = torch.load(model_path)
if self.device == 'cpu':
checkpoint = torch.load(model_path, map_location='cpu')
else:
checkpoint = torch.load(model_path)
self.checkpoint = checkpoint
util.copy_state_dict(self.E_flame.state_dict(), checkpoint['E_flame'])
util.copy_state_dict(self.E_detail.state_dict(), checkpoint['E_detail'])
Expand Down
28 changes: 16 additions & 12 deletions decalib/utils/config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'''
Default config for DECA
'''
from yacs.config import CfgNode as CN
import argparse
import yaml
import os
import yaml

from yacs.config import CfgNode as CN

cfg = CN()

Expand All @@ -24,13 +25,13 @@
# texture data original from http://files.is.tue.mpg.de/tbolkart/FLAME/FLAME_texture_data.zip
cfg.model.dense_template_path = os.path.join(cfg.deca_dir, 'data', 'texture_data_256.npy')
cfg.model.fixed_displacement_path = os.path.join(cfg.deca_dir, 'data', 'fixed_displacement_256.npy')
cfg.model.flame_model_path = os.path.join(cfg.deca_dir, 'data', 'generic_model.pkl')
cfg.model.flame_lmk_embedding_path = os.path.join(cfg.deca_dir, 'data', 'landmark_embedding.npy')
cfg.model.face_mask_path = os.path.join(cfg.deca_dir, 'data', 'uv_face_mask.png')
cfg.model.face_eye_mask_path = os.path.join(cfg.deca_dir, 'data', 'uv_face_eye_mask.png')
cfg.model.mean_tex_path = os.path.join(cfg.deca_dir, 'data', 'mean_texture.jpg')
cfg.model.tex_path = os.path.join(cfg.deca_dir, 'data', 'FLAME_albedo_from_BFM.npz')
cfg.model.tex_type = 'BFM' # BFM, FLAME, albedoMM
cfg.model.flame_model_path = os.path.join(cfg.deca_dir, 'data', 'generic_model.pkl')
cfg.model.flame_lmk_embedding_path = os.path.join(cfg.deca_dir, 'data', 'landmark_embedding.npy')
cfg.model.face_mask_path = os.path.join(cfg.deca_dir, 'data', 'uv_face_mask.png')
cfg.model.face_eye_mask_path = os.path.join(cfg.deca_dir, 'data', 'uv_face_eye_mask.png')
cfg.model.mean_tex_path = os.path.join(cfg.deca_dir, 'data', 'mean_texture.jpg')
cfg.model.tex_path = os.path.join(cfg.deca_dir, 'data', 'FLAME_albedo_from_BFM.npz')
cfg.model.tex_type = 'BFM' # BFM, FLAME, albedoMM
cfg.model.uv_size = 256
cfg.model.param_list = ['shape', 'tex', 'exp', 'pose', 'cam', 'light']
cfg.model.n_shape = 100
Expand All @@ -40,7 +41,8 @@
cfg.model.n_pose = 6
cfg.model.n_light = 27
cfg.model.use_tex = True
cfg.model.jaw_type = 'aa' # default use axis angle, another option: euler. Note that: aa is not stable in the beginning
cfg.model.extract_tex = True
cfg.model.jaw_type = 'aa' # default use axis angle, another option: euler. Note that: aa is not stable in the beginning
# face recognition model
cfg.model.fr_model_path = os.path.join(cfg.deca_dir, 'data', 'resnet50_ft_weight.pkl')

Expand Down Expand Up @@ -100,7 +102,7 @@
cfg.loss.reg_exp = 1e-04
cfg.loss.reg_tex = 1e-04
cfg.loss.reg_light = 1.
cfg.loss.reg_jaw_pose = 0. #1.
cfg.loss.reg_jaw_pose = 0. # 1.
cfg.loss.use_gender_prior = False
cfg.loss.shape_consistency = True
# loss for detail
Expand All @@ -119,14 +121,16 @@ def get_cfg_defaults():
# This is for the "local variable" use pattern
return cfg.clone()


def update_cfg(cfg, cfg_file):
cfg.merge_from_file(cfg_file)
return cfg.clone()


def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('--cfg', type=str, help='cfg file path')
parser.add_argument('--mode', type=str, default = 'train', help='deca mode')
parser.add_argument('--mode', type=str, default='train', help='deca mode')

args = parser.parse_args()
print(args, end='\n\n')
Expand Down
Loading