alvinichi commited on
Commit
6be96f1
·
1 Parent(s): dff2739
Files changed (1) hide show
  1. app.py +115 -48
app.py CHANGED
@@ -16,6 +16,8 @@ subprocess.check_call([sys.executable, "-m", "pip", "install", "scikit-image==0.
16
  subprocess.check_call([sys.executable, "-m", "pip", "install", "face-alignment==1.3.5"])
17
  subprocess.check_call([sys.executable, "-m", "pip", "install", "PyYAML==5.3.1"])
18
  subprocess.check_call([sys.executable, "-m", "pip", "install", "imageio-ffmpeg==0.4.5"])
 
 
19
 
20
  # Cài đặt ffmpeg trong môi trường Ubuntu
21
  os.system("apt-get update && apt-get install -y ffmpeg")
@@ -93,23 +95,77 @@ def normalize_kp(kp_source, kp_driving, kp_driving_initial,
93
  # Import hàm load_checkpoints từ file helper
94
  from load_helper import load_checkpoints, normalize_kp
95
 
96
- # Tải mô hình pre-trained
97
  def download_model():
98
- model_path = 'checkpoints/vox-cpk.pth.tar'
99
- if not os.path.exists('checkpoints'):
100
- os.makedirs('checkpoints', exist_ok=True)
101
-
102
- if not os.path.exists(model_path):
103
- os.system('wget -O checkpoints/vox-cpk.pth.tar https://drive.google.com/uc?export=download&id=1PyQJmkdCsAkOYwUyaj_l-l0as-iLDgeH')
104
-
105
- config_path = 'first_order_model/config/vox-256.yaml'
106
- if not os.path.exists('first_order_model/config'):
107
- os.makedirs('first_order_model/config', exist_ok=True)
108
-
109
- if not os.path.exists(config_path):
110
- os.system('wget -O first_order_model/config/vox-256.yaml https://drive.google.com/uc?export=download&id=1pZUMNRjkBiuBEM68oj9nskuWgJR-5QMn')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- return config_path, model_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
  # Hàm tạo animation
115
  def make_animation(source_image, driving_video, relative=True, adapt_movement_scale=True):
@@ -167,7 +223,7 @@ def make_animation(source_image, driving_video, relative=True, adapt_movement_sc
167
  predictions.append(np.transpose(out['prediction'].data.cpu().numpy(), [0, 2, 3, 1])[0])
168
 
169
  # Lưu video kết quả
170
- output_path = 'result.mp4'
171
  if os.path.exists(output_path):
172
  os.remove(output_path) # Xóa video nếu tồn tại
173
 
@@ -179,33 +235,41 @@ def make_animation(source_image, driving_video, relative=True, adapt_movement_sc
179
 
180
  # Định nghĩa giao diện Gradio
181
  def animate_fomm(source_image, driving_video_file, relative=True, adapt_scale=True):
182
- if source_image is None or driving_video_file is None:
183
- return None, "Vui lòng tải lên cả ảnh nguồn và video tham chiếu."
184
 
185
  try:
186
  # Lưu tạm ảnh nguồn
187
- source_path = "source_image.jpg"
188
  source_image.save(source_path)
189
 
190
- # Xử lý video tham chiếu - Sửa lỗi "a bytes-like object is required, not 'str'"
191
  print(f"Type of driving_video: {type(driving_video_file)}")
192
 
193
  # Tạo file tạm cho video
194
- driving_path = "driving_video.mp4"
195
 
196
- # Kiểm tra loại dữ liệu của driving_video_file
197
- if isinstance(driving_video_file, str):
198
- # Nếu đường dẫn, sử dụng video mẫu hoặc copy file
199
- if os.path.exists(driving_video_file):
200
- import shutil
201
- shutil.copyfile(driving_video_file, driving_path)
202
- else:
203
- # Tải video mẫu
204
- os.system("wget -O driving_video.mp4 https://github.com/AliaksandrSiarohin/first-order-model/raw/master/driving.mp4")
205
  else:
206
- # Ghi dữ liệu nhị phân vào file
207
- with open(driving_path, 'wb') as f:
208
- f.write(driving_video_file)
 
 
 
 
 
 
 
 
 
209
 
210
  # Tạo animation
211
  result_path = make_animation(
@@ -215,6 +279,13 @@ def animate_fomm(source_image, driving_video_file, relative=True, adapt_scale=Tr
215
  adapt_movement_scale=adapt_scale
216
  )
217
 
 
 
 
 
 
 
 
218
  return result_path, "Video được tạo thành công!"
219
  except Exception as e:
220
  import traceback
@@ -229,16 +300,16 @@ with gr.Blocks(title="First Order Motion Model - Tạo video người chuyển
229
  with gr.Column():
230
  source_image = gr.Image(type="pil", label="Tải lên ảnh nguồn")
231
 
 
 
 
232
  # Thay đổi từ gr.Video sang gr.File để xử lý lỗi binary
233
- driving_video_file = gr.File(label="Tải lên video tham chiếu (.mp4)")
234
 
235
  with gr.Row():
236
  relative = gr.Checkbox(value=True, label="Chuyển động tương đối")
237
  adapt_scale = gr.Checkbox(value=True, label="Điều chỉnh tỷ lệ chuyển động")
238
 
239
- # Thêm tùy chọn sử dụng video mẫu
240
- use_sample = gr.Checkbox(label="Sử dụng video mẫu (nếu bạn không muốn tải lên video)")
241
-
242
  submit_btn = gr.Button("Tạo video")
243
 
244
  with gr.Column():
@@ -247,36 +318,32 @@ with gr.Blocks(title="First Order Motion Model - Tạo video người chuyển
247
 
248
  # Xử lý sự kiện khi checkbox được chọn
249
  def toggle_video_upload(use_sample_video):
250
- return gr.update(interactive=not use_sample_video)
251
 
252
  use_sample.change(fn=toggle_video_upload, inputs=[use_sample], outputs=[driving_video_file])
253
 
254
  # Cập nhật hàm xử lý khi nhấn nút
255
- def process_inputs(source_img, driving_vid, use_sample_vid, rel, adapt):
256
  if use_sample_vid:
257
- # Tải video mẫu nếu cần
258
- sample_path = "sample_driving.mp4"
259
- if not os.path.exists(sample_path):
260
- os.system("wget -O sample_driving.mp4 https://github.com/AliaksandrSiarohin/first-order-model/raw/master/driving.mp4")
261
- return animate_fomm(source_img, sample_path, rel, adapt)
262
  else:
263
  return animate_fomm(source_img, driving_vid, rel, adapt)
264
 
265
  submit_btn.click(
266
  fn=process_inputs,
267
- inputs=[source_image, driving_video_file, use_sample, relative, adapt_scale],
268
  outputs=[output_video, output_message]
269
  )
270
 
271
  gr.Markdown("### Cách sử dụng")
272
  gr.Markdown("1. Tải lên **ảnh nguồn** - ảnh chứa người/đối tượng bạn muốn làm chuyển động")
273
- gr.Markdown("2. Tải lên **video tham chiếu** - video chuyển động bạn muốn áp dụng")
274
- gr.Markdown("3. Hoặc chọn sử dụng video mẫu có sẵn")
275
- gr.Markdown("4. Nhấn **Tạo video** và chờ kết quả")
276
 
277
  gr.Markdown("### Lưu ý")
278
  gr.Markdown("- Ảnh nguồn và video tham chiếu nên có đối tượng tương tự (người với người, mặt với mặt)")
279
  gr.Markdown("- Đối tượng nên ở vị trí tương tự trong cả ảnh nguồn và khung đầu tiên của video tham chiếu")
280
  gr.Markdown("- Quá trình tạo video có thể mất vài phút")
 
281
 
282
  demo.launch()
 
16
  subprocess.check_call([sys.executable, "-m", "pip", "install", "face-alignment==1.3.5"])
17
  subprocess.check_call([sys.executable, "-m", "pip", "install", "PyYAML==5.3.1"])
18
  subprocess.check_call([sys.executable, "-m", "pip", "install", "imageio-ffmpeg==0.4.5"])
19
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "gdown"])
20
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "huggingface_hub"])
21
 
22
  # Cài đặt ffmpeg trong môi trường Ubuntu
23
  os.system("apt-get update && apt-get install -y ffmpeg")
 
95
  # Import hàm load_checkpoints từ file helper
96
  from load_helper import load_checkpoints, normalize_kp
97
 
98
+ # Tải mô hình pre-trained với phương pháp cải tiến
99
  def download_model():
100
+ try:
101
+ # Thử phương pháp sử dụng gdown trước
102
+ model_path = 'checkpoints/vox-cpk.pth.tar'
103
+ if not os.path.exists('checkpoints'):
104
+ os.makedirs('checkpoints', exist_ok=True)
105
+
106
+ # Kiểm tra xem file đã tồn tại và đủ lớn chưa
107
+ if not os.path.exists(model_path) or os.path.getsize(model_path) < 1000000:
108
+ print("Đang tải mô hình từ Google Drive...")
109
+ import gdown
110
+ file_id = '1PyQJmkdCsAkOYwUyaj_l-l0as-iLDgeH'
111
+ gdown.download(f"https://drive.google.com/uc?id={file_id}", model_path, quiet=False)
112
+
113
+ config_path = 'first_order_model/config/vox-256.yaml'
114
+ if not os.path.exists('first_order_model/config'):
115
+ os.makedirs('first_order_model/config', exist_ok=True)
116
+
117
+ if not os.path.exists(config_path) or os.path.getsize(config_path) < 1000:
118
+ print("Đang tải file cấu hình từ Google Drive...")
119
+ import gdown
120
+ file_id = '1pZUMNRjkBiuBEM68oj9nskuWgJR-5QMn'
121
+ gdown.download(f"https://drive.google.com/uc?id={file_id}", config_path, quiet=False)
122
+
123
+ # Kiểm tra lại kích thước file
124
+ if os.path.exists(model_path) and os.path.getsize(model_path) > 1000000 and os.path.exists(config_path) and os.path.getsize(config_path) > 1000:
125
+ return config_path, model_path
126
+
127
+ # Nếu gdown không thành công, thử phương pháp sử dụng Hugging Face
128
+ raise Exception("Tải mô hình từ Google Drive không thành công. Chuyển sang sử dụng Hugging Face...")
129
 
130
+ except Exception as e:
131
+ print(f"Lỗi khi tải từ Google Drive: {str(e)}")
132
+ return download_model_alternative()
133
+
134
+ def download_model_alternative():
135
+ try:
136
+ print("Đang tải mô hình từ Hugging Face...")
137
+ from huggingface_hub import hf_hub_download
138
+
139
+ model_path = hf_hub_download(
140
+ repo_id="ycyunwei/first-order-motion-model",
141
+ filename="vox-cpk.pth.tar"
142
+ )
143
+
144
+ config_path = hf_hub_download(
145
+ repo_id="ycyunwei/first-order-motion-model",
146
+ filename="vox-256.yaml"
147
+ )
148
+
149
+ return config_path, model_path
150
+ except Exception as e:
151
+ print(f"Lỗi khi tải từ Hugging Face: {str(e)}")
152
+ # Thử phương pháp cuối cùng - sử dụng direct link
153
+ model_path = 'checkpoints/vox-cpk.pth.tar'
154
+ if not os.path.exists('checkpoints'):
155
+ os.makedirs('checkpoints', exist_ok=True)
156
+
157
+ os.system(f'wget -O {model_path} https://github.com/AliaksandrSiarohin/first-order-model/releases/download/v1.0.0/vox-cpk.pth.tar')
158
+
159
+ config_path = 'first_order_model/config/vox-256.yaml'
160
+ if not os.path.exists('first_order_model/config'):
161
+ os.makedirs('first_order_model/config', exist_ok=True)
162
+
163
+ os.system(f'wget -O {config_path} https://raw.githubusercontent.com/AliaksandrSiarohin/first-order-model/master/config/vox-256.yaml')
164
+
165
+ if os.path.exists(model_path) and os.path.getsize(model_path) > 1000000 and os.path.exists(config_path) and os.path.getsize(config_path) > 1000:
166
+ return config_path, model_path
167
+ else:
168
+ raise Exception("Không thể tải mô hình b���ng cả ba phương pháp. Vui lòng thử lại sau.")
169
 
170
  # Hàm tạo animation
171
  def make_animation(source_image, driving_video, relative=True, adapt_movement_scale=True):
 
223
  predictions.append(np.transpose(out['prediction'].data.cpu().numpy(), [0, 2, 3, 1])[0])
224
 
225
  # Lưu video kết quả
226
+ output_path = f'result_{int(np.random.rand() * 10000)}.mp4'
227
  if os.path.exists(output_path):
228
  os.remove(output_path) # Xóa video nếu tồn tại
229
 
 
235
 
236
  # Định nghĩa giao diện Gradio
237
  def animate_fomm(source_image, driving_video_file, relative=True, adapt_scale=True):
238
+ if source_image is None:
239
+ return None, "Vui lòng tải lên ảnh nguồn."
240
 
241
  try:
242
  # Lưu tạm ảnh nguồn
243
+ source_path = f"source_image_{int(np.random.rand() * 10000)}.jpg"
244
  source_image.save(source_path)
245
 
246
+ # Xử lý video tham chiếu
247
  print(f"Type of driving_video: {type(driving_video_file)}")
248
 
249
  # Tạo file tạm cho video
250
+ driving_path = f"driving_video_{int(np.random.rand() * 10000)}.mp4"
251
 
252
+ # Kiểm tra nếu đã chọn sử dụng video mẫu
253
+ if driving_video_file is None:
254
+ # Tải sử dụng video mẫu
255
+ sample_path = "sample_driving.mp4"
256
+ if not os.path.exists(sample_path) or os.path.getsize(sample_path) < 10000:
257
+ print("Đang tải video mẫu...")
258
+ os.system("wget -O sample_driving.mp4 https://github.com/AliaksandrSiarohin/first-order-model/raw/master/driving.mp4")
259
+ driving_path = sample_path
 
260
  else:
261
+ # Xử video được tải lên
262
+ if isinstance(driving_video_file, str):
263
+ # Nếu là đường dẫn, copy file
264
+ if os.path.exists(driving_video_file):
265
+ import shutil
266
+ shutil.copyfile(driving_video_file, driving_path)
267
+ else:
268
+ return None, f"Không tìm thấy file video tại đường dẫn: {driving_video_file}"
269
+ else:
270
+ # Ghi dữ liệu nhị phân vào file
271
+ with open(driving_path, 'wb') as f:
272
+ f.write(driving_video_file)
273
 
274
  # Tạo animation
275
  result_path = make_animation(
 
279
  adapt_movement_scale=adapt_scale
280
  )
281
 
282
+ # Xóa file tạm nếu cần
283
+ if os.path.exists(source_path) and source_path != "source_image.jpg":
284
+ os.remove(source_path)
285
+
286
+ if os.path.exists(driving_path) and driving_path != "sample_driving.mp4" and driving_path != "driving_video.mp4":
287
+ os.remove(driving_path)
288
+
289
  return result_path, "Video được tạo thành công!"
290
  except Exception as e:
291
  import traceback
 
300
  with gr.Column():
301
  source_image = gr.Image(type="pil", label="Tải lên ảnh nguồn")
302
 
303
+ # Thêm tùy chọn sử dụng video mẫu
304
+ use_sample = gr.Checkbox(label="Sử dụng video mẫu có sẵn", value=True)
305
+
306
  # Thay đổi từ gr.Video sang gr.File để xử lý lỗi binary
307
+ driving_video_file = gr.File(label="Tải lên video tham chiếu (.mp4)", visible=False)
308
 
309
  with gr.Row():
310
  relative = gr.Checkbox(value=True, label="Chuyển động tương đối")
311
  adapt_scale = gr.Checkbox(value=True, label="Điều chỉnh tỷ lệ chuyển động")
312
 
 
 
 
313
  submit_btn = gr.Button("Tạo video")
314
 
315
  with gr.Column():
 
318
 
319
  # Xử lý sự kiện khi checkbox được chọn
320
  def toggle_video_upload(use_sample_video):
321
+ return gr.update(visible=not use_sample_video)
322
 
323
  use_sample.change(fn=toggle_video_upload, inputs=[use_sample], outputs=[driving_video_file])
324
 
325
  # Cập nhật hàm xử lý khi nhấn nút
326
+ def process_inputs(source_img, use_sample_vid, driving_vid, rel, adapt):
327
  if use_sample_vid:
328
+ return animate_fomm(source_img, None, rel, adapt)
 
 
 
 
329
  else:
330
  return animate_fomm(source_img, driving_vid, rel, adapt)
331
 
332
  submit_btn.click(
333
  fn=process_inputs,
334
+ inputs=[source_image, use_sample, driving_video_file, relative, adapt_scale],
335
  outputs=[output_video, output_message]
336
  )
337
 
338
  gr.Markdown("### Cách sử dụng")
339
  gr.Markdown("1. Tải lên **ảnh nguồn** - ảnh chứa người/đối tượng bạn muốn làm chuyển động")
340
+ gr.Markdown("2. Chọn sử dụng video mẫu sẵn hoặc tải lên video tham chiếu của riêng bạn")
341
+ gr.Markdown("3. Nhấn **Tạo video** chờ kết quả")
 
342
 
343
  gr.Markdown("### Lưu ý")
344
  gr.Markdown("- Ảnh nguồn và video tham chiếu nên có đối tượng tương tự (người với người, mặt với mặt)")
345
  gr.Markdown("- Đối tượng nên ở vị trí tương tự trong cả ảnh nguồn và khung đầu tiên của video tham chiếu")
346
  gr.Markdown("- Quá trình tạo video có thể mất vài phút")
347
+ gr.Markdown("- Nếu gặp vấn đề với việc tải lên video, hãy sử dụng video mẫu có sẵn")
348
 
349
  demo.launch()