Spaces:
Running
on
Zero
Running
on
Zero
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
|