Spaces:
Runtime error
Runtime error
Commit
·
2e7c76e
1
Parent(s):
cbc48ce
update
Browse files- app.py +11 -2
- app/demo.py +16 -12
- app/entry.py +3 -0
- app/gui.py +2 -0
- app/handler.py +27 -18
app.py
CHANGED
|
@@ -42,7 +42,16 @@ def prepare_env():
|
|
| 42 |
|
| 43 |
return
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
if __name__ == '__main__':
|
| 46 |
prepare_env()
|
| 47 |
-
|
| 48 |
-
time.sleep(600)
|
|
|
|
| 42 |
|
| 43 |
return
|
| 44 |
|
| 45 |
+
|
| 46 |
+
def server_up():
|
| 47 |
+
server_up_flag = Path(f'{REPO_ROOT}/server_up')
|
| 48 |
+
if server_up_flag.exists():
|
| 49 |
+
while True:
|
| 50 |
+
time.sleep(600)
|
| 51 |
+
else:
|
| 52 |
+
os.system(f'python {REPO_ROOT}/app/entry.py')
|
| 53 |
+
|
| 54 |
+
|
| 55 |
if __name__ == '__main__':
|
| 56 |
prepare_env()
|
| 57 |
+
server_up()
|
|
|
app/demo.py
CHANGED
|
@@ -84,7 +84,7 @@ def parse_args_to_cfg():
|
|
| 84 |
|
| 85 |
|
| 86 |
@torch.no_grad()
|
| 87 |
-
def run_preprocess(cfg):
|
| 88 |
Log.info(f"[Preprocess] Start!")
|
| 89 |
tic = Log.time()
|
| 90 |
video_path = cfg.video_path
|
|
@@ -93,6 +93,7 @@ def run_preprocess(cfg):
|
|
| 93 |
verbose = cfg.verbose
|
| 94 |
|
| 95 |
# Get bbx tracking result
|
|
|
|
| 96 |
if not Path(paths.bbx).exists():
|
| 97 |
tracker = Tracker()
|
| 98 |
bbx_xyxy = tracker.get_one_track(video_path).float() # (L, 4)
|
|
@@ -109,6 +110,7 @@ def run_preprocess(cfg):
|
|
| 109 |
save_video(video_overlay, cfg.paths.bbx_xyxy_video_overlay)
|
| 110 |
|
| 111 |
# Get VitPose
|
|
|
|
| 112 |
if not Path(paths.vitpose).exists():
|
| 113 |
vitpose_extractor = VitPoseExtractor()
|
| 114 |
vitpose = vitpose_extractor.extract(video_path, bbx_xys)
|
|
@@ -123,6 +125,7 @@ def run_preprocess(cfg):
|
|
| 123 |
save_video(video_overlay, paths.vitpose_video_overlay)
|
| 124 |
|
| 125 |
# Get vit features
|
|
|
|
| 126 |
if not Path(paths.vit_features).exists():
|
| 127 |
extractor = Extractor()
|
| 128 |
vit_features = extractor.extract_video_features(video_path, bbx_xys)
|
|
@@ -132,6 +135,7 @@ def run_preprocess(cfg):
|
|
| 132 |
Log.info(f"[Preprocess] vit_features from {paths.vit_features}")
|
| 133 |
|
| 134 |
# Get DPVO results
|
|
|
|
| 135 |
if not static_cam: # use slam to get cam rotation
|
| 136 |
if not Path(paths.slam).exists():
|
| 137 |
length, width, height = get_video_lwh(cfg.video_path)
|
|
@@ -176,16 +180,16 @@ def load_data_dict(cfg):
|
|
| 176 |
return data
|
| 177 |
|
| 178 |
|
| 179 |
-
def render_incam(cfg):
|
| 180 |
incam_video_path = Path(cfg.paths.incam_video)
|
| 181 |
if incam_video_path.exists():
|
| 182 |
Log.info(f"[Render Incam] Video already exists at {incam_video_path}")
|
| 183 |
return
|
| 184 |
|
| 185 |
-
pred = torch.load(cfg.paths.hmr4d_results)
|
| 186 |
-
smplx =
|
| 187 |
-
smplx2smpl =
|
| 188 |
-
faces_smpl =
|
| 189 |
|
| 190 |
# smpl
|
| 191 |
smplx_out = smplx(**to_cuda(pred["smpl_params_incam"]))
|
|
@@ -218,18 +222,18 @@ def render_incam(cfg):
|
|
| 218 |
reader.close()
|
| 219 |
|
| 220 |
|
| 221 |
-
def render_global(cfg):
|
| 222 |
global_video_path = Path(cfg.paths.global_video)
|
| 223 |
if global_video_path.exists():
|
| 224 |
Log.info(f"[Render Global] Video already exists at {global_video_path}")
|
| 225 |
return
|
| 226 |
|
| 227 |
debug_cam = False
|
| 228 |
-
pred = torch.load(cfg.paths.hmr4d_results)
|
| 229 |
-
smplx =
|
| 230 |
-
smplx2smpl =
|
| 231 |
-
faces_smpl =
|
| 232 |
-
J_regressor =
|
| 233 |
|
| 234 |
# smpl
|
| 235 |
smplx_out = smplx(**to_cuda(pred["smpl_params_global"]))
|
|
|
|
| 84 |
|
| 85 |
|
| 86 |
@torch.no_grad()
|
| 87 |
+
def run_preprocess(cfg, progress):
|
| 88 |
Log.info(f"[Preprocess] Start!")
|
| 89 |
tic = Log.time()
|
| 90 |
video_path = cfg.video_path
|
|
|
|
| 93 |
verbose = cfg.verbose
|
| 94 |
|
| 95 |
# Get bbx tracking result
|
| 96 |
+
progress(0, '[Preprocess] YoloV8 Tracking')
|
| 97 |
if not Path(paths.bbx).exists():
|
| 98 |
tracker = Tracker()
|
| 99 |
bbx_xyxy = tracker.get_one_track(video_path).float() # (L, 4)
|
|
|
|
| 110 |
save_video(video_overlay, cfg.paths.bbx_xyxy_video_overlay)
|
| 111 |
|
| 112 |
# Get VitPose
|
| 113 |
+
progress(1/4, '[Preprocess] ViTPose')
|
| 114 |
if not Path(paths.vitpose).exists():
|
| 115 |
vitpose_extractor = VitPoseExtractor()
|
| 116 |
vitpose = vitpose_extractor.extract(video_path, bbx_xys)
|
|
|
|
| 125 |
save_video(video_overlay, paths.vitpose_video_overlay)
|
| 126 |
|
| 127 |
# Get vit features
|
| 128 |
+
progress(2/4, '[Preprocess] HMR2 Feature')
|
| 129 |
if not Path(paths.vit_features).exists():
|
| 130 |
extractor = Extractor()
|
| 131 |
vit_features = extractor.extract_video_features(video_path, bbx_xys)
|
|
|
|
| 135 |
Log.info(f"[Preprocess] vit_features from {paths.vit_features}")
|
| 136 |
|
| 137 |
# Get DPVO results
|
| 138 |
+
progress(3/4, '[Preprocess] DPVO')
|
| 139 |
if not static_cam: # use slam to get cam rotation
|
| 140 |
if not Path(paths.slam).exists():
|
| 141 |
length, width, height = get_video_lwh(cfg.video_path)
|
|
|
|
| 180 |
return data
|
| 181 |
|
| 182 |
|
| 183 |
+
def render_incam(cfg, pred, smpl_utils):
|
| 184 |
incam_video_path = Path(cfg.paths.incam_video)
|
| 185 |
if incam_video_path.exists():
|
| 186 |
Log.info(f"[Render Incam] Video already exists at {incam_video_path}")
|
| 187 |
return
|
| 188 |
|
| 189 |
+
# pred = torch.load(cfg.paths.hmr4d_results)
|
| 190 |
+
smplx = smpl_utils['smplx']
|
| 191 |
+
smplx2smpl = smpl_utils['smplx2smpl']
|
| 192 |
+
faces_smpl = smpl_utils['faces_smpl']
|
| 193 |
|
| 194 |
# smpl
|
| 195 |
smplx_out = smplx(**to_cuda(pred["smpl_params_incam"]))
|
|
|
|
| 222 |
reader.close()
|
| 223 |
|
| 224 |
|
| 225 |
+
def render_global(cfg, pred, smpl_utils):
|
| 226 |
global_video_path = Path(cfg.paths.global_video)
|
| 227 |
if global_video_path.exists():
|
| 228 |
Log.info(f"[Render Global] Video already exists at {global_video_path}")
|
| 229 |
return
|
| 230 |
|
| 231 |
debug_cam = False
|
| 232 |
+
# pred = torch.load(cfg.paths.hmr4d_results)
|
| 233 |
+
smplx = smpl_utils['smplx']
|
| 234 |
+
smplx2smpl = smpl_utils['smplx2smpl']
|
| 235 |
+
faces_smpl = smpl_utils['faces_smpl']
|
| 236 |
+
J_regressor = smpl_utils['J_regressor']
|
| 237 |
|
| 238 |
# smpl
|
| 239 |
smplx_out = smplx(**to_cuda(pred["smpl_params_global"]))
|
app/entry.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
|
| 3 |
from app.gui import get_inputs_components, get_outputs_components, get_examples, get_desc
|
|
@@ -5,6 +6,8 @@ from app.handler import handler
|
|
| 5 |
|
| 6 |
|
| 7 |
def entry():
|
|
|
|
|
|
|
| 8 |
demo = gr.Interface(
|
| 9 |
fn = handler,
|
| 10 |
inputs = get_inputs_components(),
|
|
|
|
| 1 |
+
import os
|
| 2 |
import gradio as gr
|
| 3 |
|
| 4 |
from app.gui import get_inputs_components, get_outputs_components, get_examples, get_desc
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
def entry():
|
| 9 |
+
os.system('touch {REPO_ROOT}/server_up')
|
| 10 |
+
|
| 11 |
demo = gr.Interface(
|
| 12 |
fn = handler,
|
| 13 |
inputs = get_inputs_components(),
|
app/gui.py
CHANGED
|
@@ -67,4 +67,6 @@ def get_desc():
|
|
| 67 |
[Ruizhen Hu](https://csse.szu.edu.cn/staff/ruizhenhu/),
|
| 68 |
[Xiaowei Zhou](https://xzhou.me/)
|
| 69 |
> SIGGRAPH Asia 2024
|
|
|
|
|
|
|
| 70 |
'''
|
|
|
|
| 67 |
[Ruizhen Hu](https://csse.szu.edu.cn/staff/ruizhenhu/),
|
| 68 |
[Xiaowei Zhou](https://xzhou.me/)
|
| 69 |
> SIGGRAPH Asia 2024
|
| 70 |
+
|
| 71 |
+
**Tips: since the GPU quota is limited, we suggest to use short videos (< 5s) for demo.** For longer videos or moving camera videos, please refer to the [colab demo](https://colab.research.google.com/drive/1N9WSchizHv2bfQqkE9Wuiegw_OT7mtGj?usp=sharing).
|
| 72 |
'''
|
app/handler.py
CHANGED
|
@@ -44,35 +44,44 @@ def prepare_cfg(is_static:bool, video_path:str, demo_id:str):
|
|
| 44 |
def run_demo(cfg, progress, GPU_quota):
|
| 45 |
''' Allow user to adjust GPU quota. '''
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
@spaces.GPU(duration=int(GPU_quota))
|
| 48 |
def run_GPU_task():
|
| 49 |
-
paths = cfg.paths
|
| 50 |
Log.info(f"[GPU]: {torch.cuda.get_device_name()}")
|
| 51 |
Log.info(f'[GPU]: {torch.cuda.get_device_properties("cuda")}')
|
| 52 |
|
| 53 |
# ===== Preprocess and save to disk ===== #
|
| 54 |
-
run_preprocess(cfg)
|
| 55 |
data = load_data_dict(cfg)
|
| 56 |
|
| 57 |
# ===== HMR4D ===== #
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
| 69 |
|
| 70 |
# ===== Render ===== #
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
|
|
|
| 76 |
|
| 77 |
run_GPU_task()
|
| 78 |
return
|
|
|
|
| 44 |
def run_demo(cfg, progress, GPU_quota):
|
| 45 |
''' Allow user to adjust GPU quota. '''
|
| 46 |
|
| 47 |
+
smpl_utils = {
|
| 48 |
+
'smplx' : make_smplx("supermotion"),
|
| 49 |
+
'J_regressor' : torch.load("hmr4d/utils/body_model/smpl_neutral_J_regressor.pt"),
|
| 50 |
+
'smplx2smpl' : torch.load("hmr4d/utils/body_model/smplx2smpl_sparse.pt"),
|
| 51 |
+
'faces_smpl' : make_smplx("smpl").faces,
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
@spaces.GPU(duration=int(GPU_quota))
|
| 55 |
def run_GPU_task():
|
|
|
|
| 56 |
Log.info(f"[GPU]: {torch.cuda.get_device_name()}")
|
| 57 |
Log.info(f'[GPU]: {torch.cuda.get_device_properties("cuda")}')
|
| 58 |
|
| 59 |
# ===== Preprocess and save to disk ===== #
|
| 60 |
+
run_preprocess(cfg, progress)
|
| 61 |
data = load_data_dict(cfg)
|
| 62 |
|
| 63 |
# ===== HMR4D ===== #
|
| 64 |
+
Log.info("[HMR4D] Predicting")
|
| 65 |
+
progress(0, '[GVHMR] Initializing pipeline...')
|
| 66 |
+
model: DemoPL = hydra.utils.instantiate(cfg.model, _recursive_=False)
|
| 67 |
+
model.load_pretrained_model(cfg.ckpt_path)
|
| 68 |
+
model = model.eval().cuda()
|
| 69 |
+
tic = Log.sync_time()
|
| 70 |
+
progress(1/3, '[GVHMR] Predicting...')
|
| 71 |
+
pred = model.predict(data, static_cam=cfg.static_cam)
|
| 72 |
+
pred = detach_to_cpu(pred)
|
| 73 |
+
data_time = data["length"] / 30
|
| 74 |
+
Log.info(f"[HMR4D] Elapsed: {Log.sync_time() - tic:.2f}s for data-length={data_time:.1f}s")
|
| 75 |
+
|
| 76 |
+
progress(2/3, '[GVHMR] Rendering...')
|
| 77 |
|
| 78 |
# ===== Render ===== #
|
| 79 |
+
smpl_utils['smplx'] = smpl_utils['smplx'].cuda()
|
| 80 |
+
smpl_utils['J_regressor'] = smpl_utils['J_regressor'].cuda()
|
| 81 |
+
smpl_utils['smplx2smpl'] = smpl_utils['smplx2smpl'].cuda()
|
| 82 |
+
render_incam(cfg, pred, smpl_utils)
|
| 83 |
+
render_global(cfg, pred, smpl_utils)
|
| 84 |
+
return
|
| 85 |
|
| 86 |
run_GPU_task()
|
| 87 |
return
|