IsshikiHugh commited on
Commit
2e7c76e
·
1 Parent(s): cbc48ce
Files changed (5) hide show
  1. app.py +11 -2
  2. app/demo.py +16 -12
  3. app/entry.py +3 -0
  4. app/gui.py +2 -0
  5. 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
- while True:
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 = make_smplx("supermotion").cuda()
187
- smplx2smpl = torch.load("hmr4d/utils/body_model/smplx2smpl_sparse.pt").cuda()
188
- faces_smpl = make_smplx("smpl").faces
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 = make_smplx("supermotion").cuda()
230
- smplx2smpl = torch.load("hmr4d/utils/body_model/smplx2smpl_sparse.pt").cuda()
231
- faces_smpl = make_smplx("smpl").faces
232
- J_regressor = torch.load("hmr4d/utils/body_model/smpl_neutral_J_regressor.pt").cuda()
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
- if not Path(paths.hmr4d_results).exists():
59
- Log.info("[HMR4D] Predicting")
60
- model: DemoPL = hydra.utils.instantiate(cfg.model, _recursive_=False)
61
- model.load_pretrained_model(cfg.ckpt_path)
62
- model = model.eval().cuda()
63
- tic = Log.sync_time()
64
- pred = model.predict(data, static_cam=cfg.static_cam)
65
- pred = detach_to_cpu(pred)
66
- data_time = data["length"] / 30
67
- Log.info(f"[HMR4D] Elapsed: {Log.sync_time() - tic:.2f}s for data-length={data_time:.1f}s")
68
- torch.save(pred, paths.hmr4d_results)
 
 
69
 
70
  # ===== Render ===== #
71
- render_incam(cfg)
72
- render_global(cfg)
73
- if not Path(paths.incam_global_horiz_video).exists():
74
- Log.info("[Merge Videos]")
75
- merge_videos_horizontal([paths.incam_video, paths.global_video], paths.incam_global_horiz_video)
 
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