Spaces:
Running
Running
fix first version
Browse files- app.py +45 -126
- deps/{statistics_bodilex.npy → statistics_motionfix.npy} +1 -1
- download_deps.py +60 -0
- normalization.py +1 -1
- renderer/humor_render_tools/mesh_viewer.py +1 -1
- transform3d.py +3 -9
- website.py +49 -0
app.py
CHANGED
|
@@ -3,12 +3,15 @@ from geometry_utils import diffout2motion
|
|
| 3 |
import gradio as gr
|
| 4 |
import spaces
|
| 5 |
import torch
|
| 6 |
-
import random
|
| 7 |
import os
|
| 8 |
from pathlib import Path
|
| 9 |
import smplx
|
| 10 |
from body_renderer import get_render
|
| 11 |
-
import
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
# import cv2
|
| 13 |
# import moderngl
|
| 14 |
# ctx = moderngl.create_context(standalone=True)
|
|
@@ -21,60 +24,7 @@ print(zero.device) # <-- 'cuda:0' 🤗
|
|
| 21 |
|
| 22 |
DEFAULT_TEXT = "do it slower "
|
| 23 |
|
| 24 |
-
|
| 25 |
-
REPO_ID = 'athn-nik/smpl_models'
|
| 26 |
-
from huggingface_hub import snapshot_download
|
| 27 |
-
return snapshot_download(repo_id=REPO_ID, allow_patterns="smplh*",
|
| 28 |
-
token=access_token_smpl)
|
| 29 |
-
|
| 30 |
-
WEBSITE = ("""<div class="embed_hidden" style="text-align: center;">
|
| 31 |
-
<h1>MotionFix: Text-Driven 3D Human Motion Editing</h1>
|
| 32 |
-
<h3>
|
| 33 |
-
<a href="https://is.mpg.de/person/~nathanasiou" target="_blank" rel="noopener noreferrer">Nikos Athanasiou</a><sup>1</sup>,
|
| 34 |
-
<a href="https://is.mpg.de/person/acseke" target="_blank" rel="noopener noreferrer">Alpar Cseke</a><sup>1</sup>,
|
| 35 |
-
<br>
|
| 36 |
-
<a href="https://ps.is.mpg.de/person/mdiomataris" target="_blank" rel="noopener noreferrer">Markos Diomataris</a><sup>1, 3</sup>,
|
| 37 |
-
<a href="https://is.mpg.de/person/black" target="_blank" rel="noopener noreferrer">Michael J. Black</a><sup>1</sup>,
|
| 38 |
-
<a href="https://imagine.enpc.fr/~varolg/" target="_blank" rel="noopener noreferrer">Gül Varol</a><sup>2</sup>
|
| 39 |
-
</h3>
|
| 40 |
-
<h3>
|
| 41 |
-
<sup>1</sup>Max Planck Institute for Intelligent Systems, Tübingen, Germany;
|
| 42 |
-
<sup>2</sup>LIGM, École des Ponts, Univ Gustave Eiffel, CNRS, France,
|
| 43 |
-
<sup>3</sup>ETH Zürich, Switzerland
|
| 44 |
-
</h3>
|
| 45 |
-
</div>
|
| 46 |
-
<div style="display:flex; gap: 0.3rem; justify-content: center; align-items: center;" align="center">
|
| 47 |
-
<a href='https://arxiv.org/pdf/2408.00712'><img src='https://img.shields.io/badge/Arxiv-2405.20340-A42C25?style=flat&logo=arXiv&logoColor=A42C25'></a>
|
| 48 |
-
<a href='https://motionfix.is.tue.mpg.de'><img src='https://img.shields.io/badge/Project-Page-%23df5b46?style=flat&logo=Google%20chrome&logoColor=%23df5b46'></a>
|
| 49 |
-
<a href='https://www.youtube.com/watch?v=cFa6V6Ua-TY'><img src='https://img.shields.io/badge/YouTube-red?style=flat&logo=youtube&logoColor=white'></a>
|
| 50 |
-
</div>
|
| 51 |
-
""")
|
| 52 |
-
|
| 53 |
-
CREDITS=("""<div class="embed_hidden" style="text-align: center;">
|
| 54 |
-
<h3>
|
| 55 |
-
The renderer of this demo is adapted from the render of
|
| 56 |
-
<a href="https://geometry.stanford.edu/projects/humor/" target="_blank" rel="noopener noreferrer">HuMoR</a>
|
| 57 |
-
with the help of <a href="https://ps.is.mpg.de/person/trakshit" target="_blank" rel="noopener noreferrer">Tithi Rakshit</a> :)
|
| 58 |
-
</h3>
|
| 59 |
-
""")
|
| 60 |
-
|
| 61 |
-
WEB_source = ("""<div class="embed_hidden" style="text-align: center;">
|
| 62 |
-
<h1>Pick a motion to edit!</h1>
|
| 63 |
-
<h3>
|
| 64 |
-
Here you should pick a source motion
|
| 65 |
-
<hr class="double">
|
| 66 |
-
</h3>
|
| 67 |
-
</div>
|
| 68 |
-
""")
|
| 69 |
-
|
| 70 |
-
WEB_target = ("""<div class="embed_hidden" style="text-align: center;">
|
| 71 |
-
<h1>Now type the text to edit that motion!</h1>
|
| 72 |
-
<h3>
|
| 73 |
-
Here you should get the generated motion!
|
| 74 |
-
<hr class="double">
|
| 75 |
-
</h3>
|
| 76 |
-
</div>
|
| 77 |
-
""")
|
| 78 |
@spaces.GPU
|
| 79 |
def greet(n):
|
| 80 |
print(zero.device) # <-- 'cuda:0' 🤗
|
|
@@ -100,16 +50,17 @@ def show_video(input_text, key_to_use):
|
|
| 100 |
# ds_sample = joblib.load(motion_to_edit)
|
| 101 |
ds_sample = MFIX_DATASET_DICT[key_to_use]
|
| 102 |
from feature_extractor import FEAT_GET_METHODS
|
| 103 |
-
data_dict_source = {f'{feat}_source': FEAT_GET_METHODS[feat](ds_sample['motion_source'])
|
| 104 |
for feat in infeats}
|
| 105 |
-
data_dict_target = {f'{feat}_target': FEAT_GET_METHODS[feat](ds_sample['motion_target'])
|
| 106 |
for feat in infeats}
|
| 107 |
full_batch = data_dict_source | data_dict_target
|
| 108 |
-
import ipdb; ipdb.set_trace()
|
| 109 |
in_batch = normalizer.norm_and_cat(full_batch, infeats)
|
| 110 |
-
source_motion_norm =
|
| 111 |
-
|
| 112 |
-
|
|
|
|
|
|
|
| 113 |
# import ipdb; ipdb.set_trace()
|
| 114 |
checkpoint = {k.replace('denoiser.', ''): v for k, v in checkpoint.items()}
|
| 115 |
tmed_denoiser = TMED_denoiser().to('cuda')
|
|
@@ -128,8 +79,8 @@ def show_video(input_text, key_to_use):
|
|
| 128 |
texts_cond = ['']*no_of_texts + texts_cond
|
| 129 |
texts_cond = ['']*no_of_texts + texts_cond
|
| 130 |
text_emb, text_mask = text_encoder(texts_cond)
|
| 131 |
-
|
| 132 |
-
cond_emb_motion = source_motion_norm
|
| 133 |
cond_motion_mask = torch.ones((bsz, seqlen_src),
|
| 134 |
dtype=bool, device='cuda')
|
| 135 |
mask_target = torch.ones((bsz, seqlen_tgt),
|
|
@@ -145,7 +96,9 @@ def show_video(input_text, key_to_use):
|
|
| 145 |
gd_text=2.0,
|
| 146 |
gd_motion=2.0,
|
| 147 |
steps_num=300)
|
| 148 |
-
edited_motion = diffout2motion(diff_out, normalizer).squeeze()
|
|
|
|
|
|
|
| 149 |
# import ipdb; ipdb.set_trace()
|
| 150 |
# aitrenderer = get_renderer()
|
| 151 |
# SMPL_LAYER = SMPLLayer(model_type='smplh', ext='npz', gender='neutral')
|
|
@@ -158,26 +111,43 @@ def show_video(input_text, key_to_use):
|
|
| 158 |
gender='neutral',ext='npz')
|
| 159 |
|
| 160 |
# run_smpl_fwd_verticesbody_model, body_transl, body_orient, body_pose,
|
| 161 |
-
import random
|
| 162 |
-
xx = random.randint(1, 1000)
|
| 163 |
# edited_mot_to_render
|
| 164 |
from body_renderer import get_render
|
| 165 |
from transform3d import transform_body_pose
|
|
|
|
| 166 |
edited_motion_aa = transform_body_pose(edited_motion[:, 3:],
|
| 167 |
'6d->aa')
|
|
|
|
|
|
|
|
|
|
| 168 |
if os.path.exists('./output_movie.mp4'):
|
| 169 |
os.remove('./output_movie.mp4')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
fname = get_render(body_model,
|
| 171 |
-
[
|
| 172 |
-
[
|
| 173 |
-
[
|
| 174 |
output_path='./output_movie.mp4',
|
| 175 |
-
text='', colors=['sky blue'])
|
| 176 |
-
|
| 177 |
-
# import ipdb; ipdb.set_trace()
|
| 178 |
-
|
| 179 |
|
| 180 |
-
|
| 181 |
# fname = render_motion(AIT_RENDERER, [edited_mot_to_render],
|
| 182 |
# f"movie_example--{str(xx)}",
|
| 183 |
# pose_repr='aa',
|
|
@@ -187,57 +157,6 @@ def show_video(input_text, key_to_use):
|
|
| 187 |
print(os.path.abspath(fname))
|
| 188 |
return fname
|
| 189 |
|
| 190 |
-
from huggingface_hub import hf_hub_download
|
| 191 |
-
|
| 192 |
-
def download_models():
|
| 193 |
-
REPO_ID = 'athn-nik/example-model'
|
| 194 |
-
return hf_hub_download(REPO_ID, filename="tmed_compressed.ckpt")
|
| 195 |
-
|
| 196 |
-
def download_model_config():
|
| 197 |
-
REPO_ID = 'athn-nik/example-model'
|
| 198 |
-
path_to_config = hf_hub_download(REPO_ID, filename="tmed/.hydra/config.yaml")
|
| 199 |
-
from omegaconf import OmegaConf
|
| 200 |
-
model_cfg = OmegaConf.to_yaml(path_to_config)
|
| 201 |
-
return model_cfg.model.input_feats
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
def download_motion_from_dataset(key_to_dl):
|
| 205 |
-
REPO_ID = 'athn-nik/example-model'
|
| 206 |
-
from huggingface_hub import snapshot_download
|
| 207 |
-
keytodl = key_to_dl
|
| 208 |
-
keytodl = '000008'
|
| 209 |
-
path_for_ds = snapshot_download(repo_id=REPO_ID,
|
| 210 |
-
allow_patterns=f"dataset_inputs/{keytodl}",
|
| 211 |
-
token=access_token_smpl)
|
| 212 |
-
path_for_ds_sample = path_for_ds + f'/dataset_inputs/{keytodl}.pth.tar'
|
| 213 |
-
return path_for_ds_sample
|
| 214 |
-
|
| 215 |
-
def download_tmr():
|
| 216 |
-
REPO_ID = 'athn-nik/example-model'
|
| 217 |
-
# return hf_hub_download(REPO_ID, filename="min_checkpoint.ckpt")
|
| 218 |
-
from huggingface_hub import snapshot_download
|
| 219 |
-
return snapshot_download(repo_id=REPO_ID, allow_patterns="tmr*",
|
| 220 |
-
token=access_token_smpl)
|
| 221 |
-
|
| 222 |
-
def download_motionfix():
|
| 223 |
-
REPO_ID = 'athn-nik/example-model'
|
| 224 |
-
# return hf_hub_download(REPO_ID, filename="min_checkpoint.ckpt")
|
| 225 |
-
from huggingface_hub import snapshot_download
|
| 226 |
-
return snapshot_download(repo_id=REPO_ID, allow_patterns="motionfix*",
|
| 227 |
-
token=access_token_smpl)
|
| 228 |
-
|
| 229 |
-
def download_motionfix_dataset():
|
| 230 |
-
REPO_ID = 'athn-nik/example-model'
|
| 231 |
-
dataset_downloaded_path = hf_hub_download(REPO_ID, filename="motionfix.pth.tar")
|
| 232 |
-
dataset_dict = joblib.load(dataset_downloaded_path)
|
| 233 |
-
return dataset_dict
|
| 234 |
-
|
| 235 |
-
def download_embeddings():
|
| 236 |
-
REPO_ID = 'athn-nik/example-model'
|
| 237 |
-
# return hf_hub_download(REPO_ID, filename="min_checkpoint.ckpt")
|
| 238 |
-
from huggingface_hub import snapshot_download
|
| 239 |
-
return snapshot_download(repo_id=REPO_ID, allow_patterns="embeddings*",
|
| 240 |
-
token=access_token_smpl)
|
| 241 |
|
| 242 |
|
| 243 |
MFIX_p = download_motionfix() + '/motionfix'
|
|
|
|
| 3 |
import gradio as gr
|
| 4 |
import spaces
|
| 5 |
import torch
|
|
|
|
| 6 |
import os
|
| 7 |
from pathlib import Path
|
| 8 |
import smplx
|
| 9 |
from body_renderer import get_render
|
| 10 |
+
import numpy as np
|
| 11 |
+
from download_deps import get_smpl_models, download_models, download_model_config
|
| 12 |
+
from download_deps import download_tmr, download_motionfix, download_motionfix_dataset
|
| 13 |
+
from download_deps import download_embeddings
|
| 14 |
+
from website import CREDITS, WEB_source, WEB_target, WEBSITE
|
| 15 |
# import cv2
|
| 16 |
# import moderngl
|
| 17 |
# ctx = moderngl.create_context(standalone=True)
|
|
|
|
| 24 |
|
| 25 |
DEFAULT_TEXT = "do it slower "
|
| 26 |
|
| 27 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
@spaces.GPU
|
| 29 |
def greet(n):
|
| 30 |
print(zero.device) # <-- 'cuda:0' 🤗
|
|
|
|
| 50 |
# ds_sample = joblib.load(motion_to_edit)
|
| 51 |
ds_sample = MFIX_DATASET_DICT[key_to_use]
|
| 52 |
from feature_extractor import FEAT_GET_METHODS
|
| 53 |
+
data_dict_source = {f'{feat}_source': FEAT_GET_METHODS[feat](ds_sample['motion_source'])[None].to('cuda')
|
| 54 |
for feat in infeats}
|
| 55 |
+
data_dict_target = {f'{feat}_target': FEAT_GET_METHODS[feat](ds_sample['motion_target'])[None].to('cuda')
|
| 56 |
for feat in infeats}
|
| 57 |
full_batch = data_dict_source | data_dict_target
|
|
|
|
| 58 |
in_batch = normalizer.norm_and_cat(full_batch, infeats)
|
| 59 |
+
source_motion_norm = in_batch['source']
|
| 60 |
+
target_motion_norm = in_batch['target']
|
| 61 |
+
|
| 62 |
+
seqlen_tgt = source_motion_norm.shape[0]
|
| 63 |
+
seqlen_src = target_motion_norm.shape[0]
|
| 64 |
# import ipdb; ipdb.set_trace()
|
| 65 |
checkpoint = {k.replace('denoiser.', ''): v for k, v in checkpoint.items()}
|
| 66 |
tmed_denoiser = TMED_denoiser().to('cuda')
|
|
|
|
| 79 |
texts_cond = ['']*no_of_texts + texts_cond
|
| 80 |
texts_cond = ['']*no_of_texts + texts_cond
|
| 81 |
text_emb, text_mask = text_encoder(texts_cond)
|
| 82 |
+
|
| 83 |
+
cond_emb_motion = source_motion_norm
|
| 84 |
cond_motion_mask = torch.ones((bsz, seqlen_src),
|
| 85 |
dtype=bool, device='cuda')
|
| 86 |
mask_target = torch.ones((bsz, seqlen_tgt),
|
|
|
|
| 96 |
gd_text=2.0,
|
| 97 |
gd_motion=2.0,
|
| 98 |
steps_num=300)
|
| 99 |
+
edited_motion = diffout2motion(diff_out.permute(1,0,2), normalizer).squeeze()
|
| 100 |
+
gt_source = diffout2motion(source_motion_norm.permute(1,0,2),
|
| 101 |
+
normalizer).squeeze()
|
| 102 |
# import ipdb; ipdb.set_trace()
|
| 103 |
# aitrenderer = get_renderer()
|
| 104 |
# SMPL_LAYER = SMPLLayer(model_type='smplh', ext='npz', gender='neutral')
|
|
|
|
| 111 |
gender='neutral',ext='npz')
|
| 112 |
|
| 113 |
# run_smpl_fwd_verticesbody_model, body_transl, body_orient, body_pose,
|
|
|
|
|
|
|
| 114 |
# edited_mot_to_render
|
| 115 |
from body_renderer import get_render
|
| 116 |
from transform3d import transform_body_pose
|
| 117 |
+
# import ipdb; ipdb.set_trace()
|
| 118 |
edited_motion_aa = transform_body_pose(edited_motion[:, 3:],
|
| 119 |
'6d->aa')
|
| 120 |
+
gt_source_aa = transform_body_pose(gt_source[:, 3:],
|
| 121 |
+
'6d->aa')
|
| 122 |
+
|
| 123 |
if os.path.exists('./output_movie.mp4'):
|
| 124 |
os.remove('./output_movie.mp4')
|
| 125 |
+
from transform3d import rotate_body_degrees
|
| 126 |
+
gen_motion_trans = edited_motion[..., :3].detach().cpu()
|
| 127 |
+
gen_motion_rots_aa = edited_motion_aa.detach().cpu()
|
| 128 |
+
source_motion_trans = gt_source[..., :3].detach().cpu()
|
| 129 |
+
source_motion_rots_aa = gt_source_aa.detach().cpu()
|
| 130 |
+
|
| 131 |
+
gen_rots_rotated, gen_trans_rotated = rotate_body_degrees(transform_body_pose(
|
| 132 |
+
gen_motion_rots_aa,
|
| 133 |
+
'aa->rot'),
|
| 134 |
+
gen_motion_trans, offset=np.pi)
|
| 135 |
+
src_rots_rotated, src_trans_rotated = rotate_body_degrees(transform_body_pose(
|
| 136 |
+
source_motion_rots_aa,
|
| 137 |
+
'aa->rot'),
|
| 138 |
+
source_motion_trans, offset=np.pi)
|
| 139 |
+
|
| 140 |
+
src_rots_rotated_aa = transform_body_pose(src_rots_rotated,
|
| 141 |
+
'rot->aa')
|
| 142 |
+
gen_rots_rotated_aa = transform_body_pose(gen_rots_rotated,
|
| 143 |
+
'rot->aa')
|
| 144 |
fname = get_render(body_model,
|
| 145 |
+
[gen_trans_rotated, src_trans_rotated],
|
| 146 |
+
[gen_rots_rotated_aa[:, 0], src_rots_rotated_aa[:, 0]],
|
| 147 |
+
[gen_rots_rotated_aa[:, 1:], src_rots_rotated_aa[:, 1:]],
|
| 148 |
output_path='./output_movie.mp4',
|
| 149 |
+
text='', colors=['sky blue', 'red'])
|
|
|
|
|
|
|
|
|
|
| 150 |
|
|
|
|
| 151 |
# fname = render_motion(AIT_RENDERER, [edited_mot_to_render],
|
| 152 |
# f"movie_example--{str(xx)}",
|
| 153 |
# pose_repr='aa',
|
|
|
|
| 157 |
print(os.path.abspath(fname))
|
| 158 |
return fname
|
| 159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
|
| 162 |
MFIX_p = download_motionfix() + '/motionfix'
|
deps/{statistics_bodilex.npy → statistics_motionfix.npy}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
size 4826
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:dee69fd95d6bda36218e81cf36671a3e61988a358afce8338e771bcd3f14cef1
|
| 3 |
size 4826
|
download_deps.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import joblib
|
| 3 |
+
from huggingface_hub import hf_hub_download
|
| 4 |
+
access_token_smpl = os.environ.get('HF_SMPL_TOKEN')
|
| 5 |
+
|
| 6 |
+
def get_smpl_models():
|
| 7 |
+
REPO_ID = 'athn-nik/smpl_models'
|
| 8 |
+
from huggingface_hub import snapshot_download
|
| 9 |
+
return snapshot_download(repo_id=REPO_ID, allow_patterns="smplh*",
|
| 10 |
+
token=access_token_smpl)
|
| 11 |
+
|
| 12 |
+
def download_models():
|
| 13 |
+
REPO_ID = 'athn-nik/example-model'
|
| 14 |
+
return hf_hub_download(REPO_ID, filename="tmed_compressed.ckpt")
|
| 15 |
+
|
| 16 |
+
def download_model_config():
|
| 17 |
+
REPO_ID = 'athn-nik/example-model'
|
| 18 |
+
path_to_config = hf_hub_download(REPO_ID, filename="tmed/.hydra/config.yaml")
|
| 19 |
+
from omegaconf import OmegaConf
|
| 20 |
+
model_cfg = OmegaConf.load(path_to_config)
|
| 21 |
+
return model_cfg.model.input_feats
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def download_motion_from_dataset(key_to_dl):
|
| 25 |
+
REPO_ID = 'athn-nik/example-model'
|
| 26 |
+
from huggingface_hub import snapshot_download
|
| 27 |
+
keytodl = key_to_dl
|
| 28 |
+
keytodl = '000008'
|
| 29 |
+
path_for_ds = snapshot_download(repo_id=REPO_ID,
|
| 30 |
+
allow_patterns=f"dataset_inputs/{keytodl}",
|
| 31 |
+
token=access_token_smpl)
|
| 32 |
+
path_for_ds_sample = path_for_ds + f'/dataset_inputs/{keytodl}.pth.tar'
|
| 33 |
+
return path_for_ds_sample
|
| 34 |
+
|
| 35 |
+
def download_tmr():
|
| 36 |
+
REPO_ID = 'athn-nik/example-model'
|
| 37 |
+
# return hf_hub_download(REPO_ID, filename="min_checkpoint.ckpt")
|
| 38 |
+
from huggingface_hub import snapshot_download
|
| 39 |
+
return snapshot_download(repo_id=REPO_ID, allow_patterns="tmr*",
|
| 40 |
+
token=access_token_smpl)
|
| 41 |
+
|
| 42 |
+
def download_motionfix():
|
| 43 |
+
REPO_ID = 'athn-nik/example-model'
|
| 44 |
+
# return hf_hub_download(REPO_ID, filename="min_checkpoint.ckpt")
|
| 45 |
+
from huggingface_hub import snapshot_download
|
| 46 |
+
return snapshot_download(repo_id=REPO_ID, allow_patterns="motionfix*",
|
| 47 |
+
token=access_token_smpl)
|
| 48 |
+
|
| 49 |
+
def download_motionfix_dataset():
|
| 50 |
+
REPO_ID = 'athn-nik/example-model'
|
| 51 |
+
dataset_downloaded_path = hf_hub_download(REPO_ID, filename="motionfix.pth.tar")
|
| 52 |
+
dataset_dict = joblib.load(dataset_downloaded_path)
|
| 53 |
+
return dataset_dict
|
| 54 |
+
|
| 55 |
+
def download_embeddings():
|
| 56 |
+
REPO_ID = 'athn-nik/example-model'
|
| 57 |
+
# return hf_hub_download(REPO_ID, filename="min_checkpoint.ckpt")
|
| 58 |
+
from huggingface_hub import snapshot_download
|
| 59 |
+
return snapshot_download(repo_id=REPO_ID, allow_patterns="embeddings*",
|
| 60 |
+
token=access_token_smpl)
|
normalization.py
CHANGED
|
@@ -7,7 +7,7 @@ import torch
|
|
| 7 |
import numpy as np
|
| 8 |
|
| 9 |
class Normalizer:
|
| 10 |
-
def __init__(self, statistics_path: str='deps/
|
| 11 |
input_feats: List[str] = ["body_transl_delta_pelv",
|
| 12 |
"body_orient_xy",
|
| 13 |
"z_orient_delta", "body_pose",
|
|
|
|
| 7 |
import numpy as np
|
| 8 |
|
| 9 |
class Normalizer:
|
| 10 |
+
def __init__(self, statistics_path: str='deps/statistics_motionfix.npy', nfeats: int=207,
|
| 11 |
input_feats: List[str] = ["body_transl_delta_pelv",
|
| 12 |
"body_orient_xy",
|
| 13 |
"z_orient_delta", "body_pose",
|
renderer/humor_render_tools/mesh_viewer.py
CHANGED
|
@@ -640,7 +640,7 @@ class MeshViewer(object):
|
|
| 640 |
|
| 641 |
camera_pose = self.get_init_cam_pose()
|
| 642 |
camera_pose[:3, 3] = camera_pose[:3, 3] + np.array(
|
| 643 |
-
[coord_to_add_camera[0], coord_to_add_camera[1]+1.5, 0.5]
|
| 644 |
)
|
| 645 |
self.scene.set_pose(cam_node, camera_pose)
|
| 646 |
|
|
|
|
| 640 |
|
| 641 |
camera_pose = self.get_init_cam_pose()
|
| 642 |
camera_pose[:3, 3] = camera_pose[:3, 3] + np.array(
|
| 643 |
+
[coord_to_add_camera[0], coord_to_add_camera[1] + 1.5, 0.5]
|
| 644 |
)
|
| 645 |
self.scene.set_pose(cam_node, camera_pose)
|
| 646 |
|
transform3d.py
CHANGED
|
@@ -48,12 +48,11 @@ def rotate_trans(trans, rotZ, inverse=False):
|
|
| 48 |
return trans_local
|
| 49 |
|
| 50 |
|
| 51 |
-
def
|
| 52 |
|
| 53 |
-
|
| 54 |
Rotate the whole body
|
| 55 |
-
|
| 56 |
-
|
| 57 |
# rots, trans = data.rots.clone(), data.trans.clone()
|
| 58 |
global_poses = rots[..., 0, :, :]
|
| 59 |
global_euler = matrix_to_euler_angles(global_poses, "ZYX")
|
|
@@ -80,11 +79,6 @@ def rotate_body_canonic(rots, trans, offset=0.0):
|
|
| 80 |
# return RotTransDatastruct(rots=rots, trans=trans)
|
| 81 |
return rots, trans
|
| 82 |
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
"""
|
| 89 |
The transformation matrices returned from the functions in this file assume
|
| 90 |
the points on which the transformation will be applied are column vectors.
|
|
|
|
| 48 |
return trans_local
|
| 49 |
|
| 50 |
|
| 51 |
+
def rotate_body_degrees(rots, trans, offset=0.0):
|
| 52 |
|
| 53 |
+
"""
|
| 54 |
Rotate the whole body
|
| 55 |
+
"""
|
|
|
|
| 56 |
# rots, trans = data.rots.clone(), data.trans.clone()
|
| 57 |
global_poses = rots[..., 0, :, :]
|
| 58 |
global_euler = matrix_to_euler_angles(global_poses, "ZYX")
|
|
|
|
| 79 |
# return RotTransDatastruct(rots=rots, trans=trans)
|
| 80 |
return rots, trans
|
| 81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
"""
|
| 83 |
The transformation matrices returned from the functions in this file assume
|
| 84 |
the points on which the transformation will be applied are column vectors.
|
website.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
WEBSITE = ("""<div class="embed_hidden" style="text-align: center;">
|
| 3 |
+
<h1>MotionFix: Text-Driven 3D Human Motion Editing</h1>
|
| 4 |
+
<h3>
|
| 5 |
+
<a href="https://is.mpg.de/person/~nathanasiou" target="_blank" rel="noopener noreferrer">Nikos Athanasiou</a><sup>1</sup>,
|
| 6 |
+
<a href="https://is.mpg.de/person/acseke" target="_blank" rel="noopener noreferrer">Alpar Cseke</a><sup>1</sup>,
|
| 7 |
+
<br>
|
| 8 |
+
<a href="https://ps.is.mpg.de/person/mdiomataris" target="_blank" rel="noopener noreferrer">Markos Diomataris</a><sup>1, 3</sup>,
|
| 9 |
+
<a href="https://is.mpg.de/person/black" target="_blank" rel="noopener noreferrer">Michael J. Black</a><sup>1</sup>,
|
| 10 |
+
<a href="https://imagine.enpc.fr/~varolg/" target="_blank" rel="noopener noreferrer">Gül Varol</a><sup>2</sup>
|
| 11 |
+
</h3>
|
| 12 |
+
<h3>
|
| 13 |
+
<sup>1</sup>Max Planck Institute for Intelligent Systems, Tübingen, Germany;
|
| 14 |
+
<sup>2</sup>LIGM, École des Ponts, Univ Gustave Eiffel, CNRS, France,
|
| 15 |
+
<sup>3</sup>ETH Zürich, Switzerland
|
| 16 |
+
</h3>
|
| 17 |
+
</div>
|
| 18 |
+
<div style="display:flex; gap: 0.3rem; justify-content: center; align-items: center;" align="center">
|
| 19 |
+
<a href='https://arxiv.org/pdf/2408.00712'><img src='https://img.shields.io/badge/Arxiv-2405.20340-A42C25?style=flat&logo=arXiv&logoColor=A42C25'></a>
|
| 20 |
+
<a href='https://motionfix.is.tue.mpg.de'><img src='https://img.shields.io/badge/Project-Page-%23df5b46?style=flat&logo=Google%20chrome&logoColor=%23df5b46'></a>
|
| 21 |
+
<a href='https://www.youtube.com/watch?v=cFa6V6Ua-TY'><img src='https://img.shields.io/badge/YouTube-red?style=flat&logo=youtube&logoColor=white'></a>
|
| 22 |
+
</div>
|
| 23 |
+
""")
|
| 24 |
+
|
| 25 |
+
CREDITS=("""<div class="embed_hidden" style="text-align: center;">
|
| 26 |
+
<h3>
|
| 27 |
+
The renderer of this demo is adapted from the render of
|
| 28 |
+
<a href="https://geometry.stanford.edu/projects/humor/" target="_blank" rel="noopener noreferrer">HuMoR</a>
|
| 29 |
+
with the help of <a href="https://ps.is.mpg.de/person/trakshit" target="_blank" rel="noopener noreferrer">Tithi Rakshit</a> :)
|
| 30 |
+
</h3>
|
| 31 |
+
""")
|
| 32 |
+
|
| 33 |
+
WEB_source = ("""<div class="embed_hidden" style="text-align: center;">
|
| 34 |
+
<h1>Pick a motion to edit!</h1>
|
| 35 |
+
<h3>
|
| 36 |
+
Here you should pick a source motion
|
| 37 |
+
<hr class="double">
|
| 38 |
+
</h3>
|
| 39 |
+
</div>
|
| 40 |
+
""")
|
| 41 |
+
|
| 42 |
+
WEB_target = ("""<div class="embed_hidden" style="text-align: center;">
|
| 43 |
+
<h1>Now type the text to edit that motion!</h1>
|
| 44 |
+
<h3>
|
| 45 |
+
Here you should get the generated motion!
|
| 46 |
+
<hr class="double">
|
| 47 |
+
</h3>
|
| 48 |
+
</div>
|
| 49 |
+
""")
|