alexnasa commited on
Commit
47be277
·
verified ·
1 Parent(s): 453fdfc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +2 -194
app.py CHANGED
@@ -17,10 +17,8 @@ os.environ["PIXEL3DMM_TRACKING_OUTPUT"] = f"{os.getcwd()}/tracking_results"
17
 
18
  def sh(cmd): subprocess.check_call(cmd, shell=True)
19
 
20
- os.system(f"pip install -e {os.getcwd()}")
21
-
22
- from pixel3dmm import env_paths
23
 
 
24
  sh("cd src/pixel3dmm/preprocessing/facer && pip install -e .")
25
  sh("cd src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils && sh make.sh")
26
 
@@ -44,194 +42,4 @@ def install_cuda_toolkit():
44
 
45
  install_cuda_toolkit()
46
 
47
- import os
48
- import torch
49
- import numpy as np
50
- import trimesh
51
- from pytorch3d.io import load_obj
52
- from pixel3dmm.tracking.renderer_nvdiffrast import NVDRenderer
53
- from pixel3dmm.tracking.flame.FLAME import FLAME
54
- from pixel3dmm.tracking.tracker import Tracker
55
- from omegaconf import OmegaConf
56
-
57
-
58
- DEVICE = "cuda"
59
-
60
- base_conf = OmegaConf.load(f'{env_paths.CODE_BASE}/configs/tracking.yaml')
61
-
62
- _mesh_file = env_paths.head_template
63
- flame_model = FLAME(base_conf).to(DEVICE)
64
-
65
- _obj_faces = load_obj(_mesh_file)[1]
66
-
67
- diff_renderer = NVDRenderer(
68
- image_size=base_conf.size,
69
- obj_filename=_mesh_file,
70
- no_sh=False,
71
- white_bg=True
72
- ).to(DEVICE)
73
-
74
-
75
- # Utility to select first image from a folder
76
- def first_image_from_dir(directory):
77
- patterns = ["*.jpg", "*.png", "*.jpeg"]
78
- files = []
79
- for p in patterns:
80
- files.extend(glob.glob(os.path.join(directory, p)))
81
- if not files:
82
- return None
83
- return sorted(files)[0]
84
-
85
- # Function to reset the UI and state
86
- def reset_all():
87
- return (
88
- None, # crop_img
89
- None, # normals_img
90
- None, # uv_img
91
- None, # track_img
92
- "Awaiting new image upload...", # status
93
- {}, # state
94
- gr.update(interactive=True), # preprocess_btn
95
- gr.update(interactive=False), # normals_btn
96
- gr.update(interactive=False), # uv_map_btn
97
- gr.update(interactive=False) # track_btn
98
- )
99
-
100
- # Step 1: Preprocess the input image (Save and Crop)
101
- # @spaces.GPU()
102
- def preprocess_image(image_array, state):
103
- if image_array is None:
104
- return "❌ Please upload an image first.", None, state, gr.update(interactive=True), gr.update(interactive=False)
105
-
106
- session_id = str(uuid.uuid4())
107
- base_dir = os.path.join(os.environ["PIXEL3DMM_PREPROCESSED_DATA"], session_id)
108
- os.makedirs(base_dir, exist_ok=True)
109
- state.update({"session_id": session_id, "base_dir": base_dir})
110
-
111
- img = Image.fromarray(image_array)
112
- saved_image_path = os.path.join(base_dir, f"{session_id}.png")
113
- img.save(saved_image_path)
114
- state["image_path"] = saved_image_path
115
-
116
- try:
117
- p = subprocess.run([
118
- "python", "scripts/run_preprocessing.py", "--video_or_images_path", saved_image_path
119
- ], check=True, capture_output=True, text=True)
120
- except subprocess.CalledProcessError as e:
121
- err = f"❌ Preprocess failed (exit {e.returncode}).\n\n{e.stdout}\n{e.stderr}"
122
- shutil.rmtree(base_dir)
123
- return err, None, {}, gr.update(interactive=True), gr.update(interactive=False)
124
-
125
- crop_dir = os.path.join(base_dir, "cropped")
126
- image = first_image_from_dir(crop_dir)
127
- return "✅ Step 1 complete. Ready for Normals.", image, state, gr.update(interactive=False), gr.update(interactive=True)
128
-
129
- # Step 2: Normals inference → normals image
130
- @spaces.GPU()
131
- def step2_normals(state):
132
- session_id = state.get("session_id")
133
- if not session_id:
134
- return "❌ State lost. Please start from Step 1.", None, state, gr.update(interactive=False), gr.update(interactive=False)
135
-
136
- try:
137
- p = subprocess.run([
138
- "python", "scripts/network_inference.py", "model.prediction_type=normals", f"video_name={session_id}"
139
- ], check=True, capture_output=True, text=True)
140
- except subprocess.CalledProcessError as e:
141
- err = f"❌ Normal map failed (exit {e.returncode}).\n\n{e.stdout}\n{e.stderr}"
142
- return err, None, state, gr.update(interactive=True), gr.update(interactive=False)
143
-
144
- normals_dir = os.path.join(state["base_dir"], "p3dmm", "normals")
145
- image = first_image_from_dir(normals_dir)
146
- return "✅ Step 2 complete. Ready for UV Map.", image, state, gr.update(interactive=False), gr.update(interactive=True)
147
-
148
- # Step 3: UV map inference → uv map image
149
- @spaces.GPU()
150
- def step3_uv_map(state):
151
- session_id = state.get("session_id")
152
- if not session_id:
153
- return "❌ State lost. Please start from Step 1.", None, state, gr.update(interactive=False), gr.update(interactive=False)
154
-
155
- try:
156
- p = subprocess.run([
157
- "python", "scripts/network_inference.py", "model.prediction_type=uv_map", f"video_name={session_id}"
158
- ], check=True, capture_output=True, text=True)
159
- except subprocess.CalledProcessError as e:
160
- err = f"❌ UV map failed (exit {e.returncode}).\n\n{e.stdout}\n{e.stderr}"
161
- return err, None, state, gr.update(interactive=True), gr.update(interactive=False)
162
-
163
- uv_dir = os.path.join(state["base_dir"], "p3dmm", "uv_map")
164
- image = first_image_from_dir(uv_dir)
165
- return "✅ Step 3 complete. Ready for Tracking.", image, state, gr.update(interactive=False), gr.update(interactive=True)
166
-
167
- # Step 4: Tracking → final tracking image
168
- @spaces.GPU()
169
- def step4_track(state):
170
- session_id = state.get("session_id")
171
- base_conf.video_name = f'{session_id}'
172
- tracker = Tracker(base_conf, flame_model, diff_renderer)
173
- tracker.run()
174
-
175
- tracking_dir = os.path.join(os.environ["PIXEL3DMM_TRACKING_OUTPUT"], session_id, "frames")
176
- image = first_image_from_dir(tracking_dir)
177
-
178
- return "✅ Pipeline complete!", image, state, gr.update(interactive=False)
179
-
180
- # Build Gradio UI
181
- demo = gr.Blocks()
182
-
183
- with demo:
184
- gr.Markdown("## Image Processing Pipeline")
185
- gr.Markdown("Upload an image, then click the buttons in order. Uploading a new image will reset the process.")
186
- with gr.Row():
187
- with gr.Column():
188
- image_in = gr.Image(label="Upload Image", type="numpy", height=512)
189
- status = gr.Textbox(label="Status", lines=2, interactive=False, value="Upload an image to start.")
190
- state = gr.State({})
191
- with gr.Column():
192
- with gr.Row():
193
- crop_img = gr.Image(label="Preprocessed", height=256)
194
- normals_img = gr.Image(label="Normals", height=256)
195
- with gr.Row():
196
- uv_img = gr.Image(label="UV Map", height=256)
197
- track_img = gr.Image(label="Tracking", height=256)
198
-
199
- with gr.Row():
200
- preprocess_btn = gr.Button("Step 1: Preprocess", interactive=True)
201
- normals_btn = gr.Button("Step 2: Normals", interactive=False)
202
- uv_map_btn = gr.Button("Step 3: UV Map", interactive=False)
203
- track_btn = gr.Button("Step 4: Track", interactive=False)
204
-
205
- # Define component list for reset
206
- outputs_for_reset = [crop_img, normals_img, uv_img, track_img, status, state, preprocess_btn, normals_btn, uv_map_btn, track_btn]
207
-
208
- # Pipeline execution logic
209
- preprocess_btn.click(
210
- fn=preprocess_image,
211
- inputs=[image_in, state],
212
- outputs=[status, crop_img, state, preprocess_btn, normals_btn]
213
- )
214
- normals_btn.click(
215
- fn=step2_normals,
216
- inputs=[state],
217
- outputs=[status, normals_img, state, normals_btn, uv_map_btn]
218
- )
219
- uv_map_btn.click(
220
- fn=step3_uv_map,
221
- inputs=[state],
222
- outputs=[status, uv_img, state, uv_map_btn, track_btn]
223
- )
224
- track_btn.click(
225
- fn=step4_track,
226
- inputs=[state],
227
- outputs=[status, track_img, state, track_btn]
228
- )
229
-
230
- # Event to reset everything when a new image is uploaded
231
- image_in.upload(fn=reset_all, inputs=None, outputs=outputs_for_reset)
232
-
233
- # ------------------------------------------------------------------
234
- # START THE GRADIO SERVER
235
- # ------------------------------------------------------------------
236
- demo.queue()
237
- demo.launch(share=True, ssr_mode=False)
 
17
 
18
  def sh(cmd): subprocess.check_call(cmd, shell=True)
19
 
 
 
 
20
 
21
+ sh("pip install -e .")
22
  sh("cd src/pixel3dmm/preprocessing/facer && pip install -e .")
23
  sh("cd src/pixel3dmm/preprocessing/PIPNet/FaceBoxesV2/utils && sh make.sh")
24
 
 
42
 
43
  install_cuda_toolkit()
44
 
45
+ sh("python app_photo.py")