alvinichi commited on
Commit
dff2739
·
1 Parent(s): e77f2ba
Files changed (1) hide show
  1. app.py +68 -42
app.py CHANGED
@@ -1,13 +1,21 @@
1
  import os
2
  import sys
3
  import subprocess
 
 
 
 
 
 
 
 
4
 
5
  # Đảm bảo cài đặt các thư viện cần thiết trước khi import
6
  subprocess.check_call([sys.executable, "-m", "pip", "install", "scikit-learn"])
7
  subprocess.check_call([sys.executable, "-m", "pip", "install", "scikit-image==0.19.3"])
8
  subprocess.check_call([sys.executable, "-m", "pip", "install", "face-alignment==1.3.5"])
9
- subprocess.check_call([sys.executable, "-m", "pip", "install", "ffmpeg-python"])
10
  subprocess.check_call([sys.executable, "-m", "pip", "install", "PyYAML==5.3.1"])
 
11
 
12
  # Cài đặt ffmpeg trong môi trường Ubuntu
13
  os.system("apt-get update && apt-get install -y ffmpeg")
@@ -15,24 +23,13 @@ os.system("apt-get update && apt-get install -y ffmpeg")
15
  # Clone repo nếu chưa có
16
  if not os.path.exists('first_order_model'):
17
  subprocess.call(['git', 'clone', 'https://github.com/AliaksandrSiarohin/first-order-model.git'])
18
- os.rename('first-order-model', 'first_order_model')
 
19
 
20
  # Thêm đường dẫn vào PYTHONPATH
21
  sys.path.append('.')
22
  sys.path.append('first_order_model')
23
 
24
- # Sửa code để truy cập trực tiếp vào các hàm cần thiết
25
- # Tạo một bản sao của demo.py mà không phụ thuộc vào ffmpeg thư viện Python
26
- with open('first_order_model/demo.py', 'r') as f:
27
- demo_code = f.read()
28
-
29
- # Thay thế dòng import ffmpeg
30
- demo_code = demo_code.replace('import ffmpeg', '# import ffmpeg')
31
-
32
- # Viết lại demo.py đã sửa
33
- with open('first_order_model/demo_fixed.py', 'w') as f:
34
- f.write(demo_code)
35
-
36
  # Tạo file helper với hàm load_checkpoints
37
  with open('load_helper.py', 'w') as f:
38
  f.write("""
@@ -43,7 +40,7 @@ from first_order_model.modules.keypoint_detector import KPDetector
43
 
44
  def load_checkpoints(config_path, checkpoint_path, device='cpu'):
45
  with open(config_path) as f:
46
- config = yaml.full_load(f)
47
 
48
  generator = OcclusionAwareGenerator(**config['model_params']['generator_params'],
49
  **config['model_params']['common_params'])
@@ -93,15 +90,6 @@ def normalize_kp(kp_source, kp_driving, kp_driving_initial,
93
  return kp_new
94
  """)
95
 
96
- # Bây giờ import các module cần thiết
97
- import gradio as gr
98
- import numpy as np
99
- import torch
100
- import imageio
101
- from skimage.transform import resize
102
- from skimage import img_as_ubyte
103
- from PIL import Image
104
-
105
  # Import hàm load_checkpoints từ file helper
106
  from load_helper import load_checkpoints, normalize_kp
107
 
@@ -112,14 +100,14 @@ def download_model():
112
  os.makedirs('checkpoints', exist_ok=True)
113
 
114
  if not os.path.exists(model_path):
115
- os.system('wget -P checkpoints https://drive.google.com/uc?export=download&id=1PyQJmkdCsAkOYwUyaj_l-l0as-iLDgeH -O checkpoints/vox-cpk.pth.tar')
116
 
117
  config_path = 'first_order_model/config/vox-256.yaml'
118
  if not os.path.exists('first_order_model/config'):
119
  os.makedirs('first_order_model/config', exist_ok=True)
120
 
121
  if not os.path.exists(config_path):
122
- os.system('wget -P first_order_model/config https://drive.google.com/uc?export=download&id=1pZUMNRjkBiuBEM68oj9nskuWgJR-5QMn -O first_order_model/config/vox-256.yaml')
123
 
124
  return config_path, model_path
125
 
@@ -180,7 +168,8 @@ def make_animation(source_image, driving_video, relative=True, adapt_movement_sc
180
 
181
  # Lưu video kết quả
182
  output_path = 'result.mp4'
183
- os.system(f"rm -f {output_path}") # Xóa video nếu tồn tại
 
184
 
185
  # Lưu frames thành video sử dụng imageio
186
  frames = [img_as_ubyte(frame) for frame in predictions]
@@ -189,21 +178,34 @@ def make_animation(source_image, driving_video, relative=True, adapt_movement_sc
189
  return output_path
190
 
191
  # Định nghĩa giao diện Gradio
192
- def animate_fomm(source_image, driving_video, relative=True, adapt_scale=True):
193
- if source_image is None or driving_video is None:
194
  return None, "Vui lòng tải lên cả ảnh nguồn và video tham chiếu."
195
 
196
  try:
197
- # Lưu tạm ảnh và video tải lên
198
  source_path = "source_image.jpg"
199
- driving_path = "driving_video.mp4"
200
-
201
- # Lưu ảnh nguồn
202
  source_image.save(source_path)
203
 
204
- # Lưu video tham chiếu
205
- with open(driving_path, 'wb') as f:
206
- f.write(driving_video)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
  # Tạo animation
209
  result_path = make_animation(
@@ -215,7 +217,8 @@ def animate_fomm(source_image, driving_video, relative=True, adapt_scale=True):
215
 
216
  return result_path, "Video được tạo thành công!"
217
  except Exception as e:
218
- return None, f"Lỗi: {str(e)}"
 
219
 
220
  # Tạo giao diện Gradio
221
  with gr.Blocks(title="First Order Motion Model - Tạo video người chuyển động") as demo:
@@ -225,28 +228,51 @@ with gr.Blocks(title="First Order Motion Model - Tạo video người chuyển
225
  with gr.Row():
226
  with gr.Column():
227
  source_image = gr.Image(type="pil", label="Tải lên ảnh nguồn")
228
- driving_video = gr.Video(label="Tải lên video tham chiếu")
 
 
229
 
230
  with gr.Row():
231
  relative = gr.Checkbox(value=True, label="Chuyển động tương đối")
232
  adapt_scale = gr.Checkbox(value=True, label="Điều chỉnh tỷ lệ chuyển động")
233
 
 
 
 
234
  submit_btn = gr.Button("Tạo video")
235
 
236
  with gr.Column():
237
  output_video = gr.Video(label="Video kết quả")
238
- output_message = gr.Textbox(label="Thông báo")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
  submit_btn.click(
241
- fn=animate_fomm,
242
- inputs=[source_image, driving_video, relative, adapt_scale],
243
  outputs=[output_video, output_message]
244
  )
245
 
246
  gr.Markdown("### Cách sử dụng")
247
  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")
248
  gr.Markdown("2. Tải lên **video tham chiếu** - video có chuyển động bạn muốn áp dụng")
249
- gr.Markdown("3. Nhấn **Tạo video** chờ kết quả")
 
250
 
251
  gr.Markdown("### Lưu ý")
252
  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)")
 
1
  import os
2
  import sys
3
  import subprocess
4
+ import numpy as np
5
+ import torch
6
+ import imageio
7
+ from skimage.transform import resize
8
+ from skimage import img_as_ubyte
9
+ import gradio as gr
10
+ from PIL import Image
11
+ import tempfile
12
 
13
  # Đảm bảo cài đặt các thư viện cần thiết trước khi import
14
  subprocess.check_call([sys.executable, "-m", "pip", "install", "scikit-learn"])
15
  subprocess.check_call([sys.executable, "-m", "pip", "install", "scikit-image==0.19.3"])
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")
 
23
  # Clone repo nếu chưa có
24
  if not os.path.exists('first_order_model'):
25
  subprocess.call(['git', 'clone', 'https://github.com/AliaksandrSiarohin/first-order-model.git'])
26
+ if os.path.exists('first-order-model'):
27
+ os.rename('first-order-model', 'first_order_model')
28
 
29
  # Thêm đường dẫn vào PYTHONPATH
30
  sys.path.append('.')
31
  sys.path.append('first_order_model')
32
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  # Tạo file helper với hàm load_checkpoints
34
  with open('load_helper.py', 'w') as f:
35
  f.write("""
 
40
 
41
  def load_checkpoints(config_path, checkpoint_path, device='cpu'):
42
  with open(config_path) as f:
43
+ config = yaml.safe_load(f)
44
 
45
  generator = OcclusionAwareGenerator(**config['model_params']['generator_params'],
46
  **config['model_params']['common_params'])
 
90
  return kp_new
91
  """)
92
 
 
 
 
 
 
 
 
 
 
93
  # Import hàm load_checkpoints từ file helper
94
  from load_helper import load_checkpoints, normalize_kp
95
 
 
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
 
 
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
 
174
  # Lưu frames thành video sử dụng imageio
175
  frames = [img_as_ubyte(frame) for frame in predictions]
 
178
  return output_path
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ử 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 là đườ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(
 
217
 
218
  return result_path, "Video được tạo thành công!"
219
  except Exception as e:
220
+ import traceback
221
+ return None, f"Lỗi: {str(e)}\n{traceback.format_exc()}"
222
 
223
  # Tạo giao diện Gradio
224
  with gr.Blocks(title="First Order Motion Model - Tạo video người chuyển động") as demo:
 
228
  with gr.Row():
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():
245
  output_video = gr.Video(label="Video kết quả")
246
+ output_message = gr.Textbox(label="Thông báo", lines=5)
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 có chuyển động bạn muốn áp dụng")
274
+ gr.Markdown("3. Hoặc chọn sử dụng video mẫu 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)")