alvinichi commited on
Commit
4642fe2
·
1 Parent(s): da92cbc
Files changed (3) hide show
  1. README.md +16 -16
  2. app.py +78 -99
  3. requirements.txt +3 -4
README.md CHANGED
@@ -1,30 +1,30 @@
1
  ---
2
- title: Image to Video Generator
3
- emoji: 🎬
4
- colorFrom: blue
5
  colorTo: purple
6
  sdk: gradio
7
  sdk_version: 4.0.2
8
  app_file: app.py
9
  pinned: false
10
  ---
11
- # Ứng dụng tạo video từ hình ảnh
12
 
13
- Ứng dụng này cho phép người dùng tải lên hình ảnh và tạo video chuyển động từ hình ảnh đó sử dụng mô hình AI.
14
 
15
- ## Cách sử dụng
16
 
17
- 1. Tải lên một hình ảnh
18
- 2. Nhập tả cho chuyển động bạn muốn tạo
 
19
  3. Điều chỉnh các tham số (tùy chọn)
20
  4. Nhấn "Tạo video"
21
- 5. Đợi quá trình xử lý hoàn tất và tải xuống video
22
-
23
- ## Mô hình được sử dụng
24
-
25
- Ứng dụng này sử dụng mô hình AnimateDiff để tạo hoạt ảnh từ hình ảnh tĩnh.
26
 
27
- ## Tham khảo
 
 
 
28
 
29
- - [AnimateDiff GitHub](https://github.com/guoyww/AnimateDiff)
30
- - [HuggingFace Diffusers](https://huggingface.co/docs/diffusers/index)
 
 
 
1
  ---
2
+ title: Animate Person From Image
3
+ emoji: 🎭
4
+ colorFrom: pink
5
  colorTo: purple
6
  sdk: gradio
7
  sdk_version: 4.0.2
8
  app_file: app.py
9
  pinned: false
10
  ---
 
11
 
12
+ # Ứng dụng tạo video người chuyển động từ ảnh
13
 
14
+ Ứng dụng này sử dụng AI để tạo video người chuyển động từ một ảnh tĩnh.
15
 
16
+ ## Cách sử dụng
17
+ 1. Tải lên ảnh chứa người
18
+ 2. Nhập mô tả cho kiểu chuyển động mong muốn
19
  3. Điều chỉnh các tham số (tùy chọn)
20
  4. Nhấn "Tạo video"
 
 
 
 
 
21
 
22
+ ## Các tham số
23
+ - **Mô tả chuyển động**: Mô tả bằng lời cách người sẽ chuyển động
24
+ - **Mức độ chuyển động**: Điều chỉnh cường độ chuyển động (1-255)
25
+ - **FPS**: Số khung hình mỗi giây của video kết quả
26
 
27
+ ## Mẹo sử dụng
28
+ - Ảnh nên có nền đơn giản để có kết quả tốt nhất
29
+ - Người trong ảnh nên ở tư thế tự nhiên, không quá phức tạp
30
+ - Thử nghiệm với các mô tả khác nhau để có hiệu quả tốt nhất
app.py CHANGED
@@ -1,130 +1,109 @@
1
  import gradio as gr
2
- import torch
3
  import os
4
- from PIL import Image
5
  import numpy as np
6
- import imageio
7
- import time
 
8
 
9
- # Kiểm tra device
10
- device = "cuda" if torch.cuda.is_available() else "cpu"
11
- print(f"Using device: {device}")
 
 
 
 
 
 
12
 
13
- # Hàm tạo video đơn giản
14
- def generate_video(image, effect_type, num_frames=16, effect_strength=5.0):
15
  if image is None:
16
- return None, "Vui lòng tải lên một hình ảnh"
17
-
18
- # Đảm bảo hình ảnh là định dạng RGB
19
- if image.mode != "RGB":
20
- image = image.convert("RGB")
21
-
22
- # Thay đổi kích thước hình ảnh về 512x512
23
- image = image.resize((512, 512))
24
 
25
  try:
26
- # Tạo chuỗi khung hình với hiệu ứng khác nhau
27
- frames = []
28
-
29
- if effect_type == "zoom-in":
30
- # Hiệu ứng zoom-in
31
- for i in range(num_frames):
32
- zoom_factor = 1.0 + (i / num_frames) * (effect_strength / 10)
33
- img_copy = image.copy()
34
-
35
- size = int(img_copy.width / zoom_factor)
36
- left = (img_copy.width - size) // 2
37
- top = (img_copy.height - size) // 2
38
- right = left + size
39
- bottom = top + size
40
-
41
- cropped = img_copy.crop((left, top, right, bottom))
42
- frame = cropped.resize((512, 512))
43
- frames.append(np.array(frame))
44
-
45
- elif effect_type == "pan-right":
46
- # Hiệu ứng pan từ trái sang phải
47
- width, height = image.size
48
- for i in range(num_frames):
49
- offset = int((i / num_frames) * width * (effect_strength / 10))
50
- img_copy = image.copy()
51
-
52
- # Tạo hiệu ứng pan
53
- if offset > 0:
54
- # Lấy phần hình ảnh từ offset đến cuối
55
- right_part = img_copy.crop((offset, 0, width, height))
56
- # Lấy phần còn lại từ đầu
57
- left_part = img_copy.crop((0, 0, offset, height))
58
- # Tạo hình ảnh mới
59
- new_img = Image.new('RGB', (width, height))
60
- new_img.paste(right_part, (0, 0))
61
- new_img.paste(left_part, (width - offset, 0))
62
- frames.append(np.array(new_img))
63
- else:
64
- frames.append(np.array(img_copy))
65
-
66
- elif effect_type == "fade":
67
- # Hiệu ứng fade in/out
68
- base_frame = np.array(image)
69
- for i in range(num_frames):
70
- # Tính toán độ mờ
71
- if i < num_frames / 2:
72
- # Fade in
73
- alpha = i / (num_frames / 2)
74
- else:
75
- # Fade out
76
- alpha = 2.0 - (i / (num_frames / 2))
77
-
78
- # Áp dụng độ mờ
79
- frame = (base_frame * alpha * (effect_strength / 5)).astype(np.uint8)
80
- frames.append(frame)
81
 
 
 
 
 
82
  else:
83
- # Mặc định, chỉ thêm hiệu ứng đơn giản
84
- for i in range(num_frames):
85
- brightness = 1.0 + (effect_strength / 10) * np.sin(2 * np.pi * i / num_frames)
86
- frame = (np.array(image) * brightness).clip(0, 255).astype(np.uint8)
87
- frames.append(frame)
88
 
89
- # Tạo video từ các khung hình
90
- output_path = f"output_video_{int(time.time())}.mp4"
91
- imageio.mimsave(output_path, frames, fps=8)
92
 
93
- return output_path, "Video đã được tạo thành công!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  except Exception as e:
95
  return None, f"Lỗi: {str(e)}"
96
 
97
  # Tạo giao diện Gradio
98
- with gr.Blocks(title="Ứng dụng tạo video từ hình ảnh") as demo:
99
- gr.Markdown("# Tạo video từ hình ảnh")
100
- gr.Markdown("Tải lên một hình ảnh chọn hiệu ứng để tạo video.")
101
 
102
  with gr.Row():
103
  with gr.Column():
104
- image_input = gr.Image(type="pil", label="Tải lên hình ảnh")
105
- effect_input = gr.Radio(
106
- ["zoom-in", "pan-right", "fade", "pulse"],
107
- label="Chọn hiệu ứng",
108
- value="zoom-in"
 
 
 
 
 
 
 
 
109
  )
110
- num_frames = gr.Slider(minimum=10, maximum=30, value=16, step=2, label="Số khung hình")
111
- effect_strength = gr.Slider(minimum=1.0, maximum=10.0, value=5.0, step=0.5, label="Độ mạnh của hiệu ứng")
112
  submit_btn = gr.Button("Tạo video")
113
-
114
  with gr.Column():
115
  output_video = gr.Video(label="Video kết quả")
116
  output_message = gr.Textbox(label="Thông báo")
117
 
118
  submit_btn.click(
119
- fn=generate_video,
120
- inputs=[image_input, effect_input, num_frames, effect_strength],
121
  outputs=[output_video, output_message]
122
  )
123
 
124
- gr.Markdown("### Hướng dẫn")
125
- gr.Markdown("- **Zoom-in**: Hiệu ứng phóng to hình ảnh")
126
- gr.Markdown("- **Pan-right**: Hiệu ứng di chuyển từ trái sang phải")
127
- gr.Markdown("- **Fade**: Hiệu ứng mờ dần rồi hiện dần")
128
- gr.Markdown("- **Pulse**: Hiệu ứng thay đổi độ sáng theo nhịp")
129
 
130
  demo.launch()
 
1
  import gradio as gr
 
2
  import os
3
+ import torch
4
  import numpy as np
5
+ from PIL import Image
6
+ from diffusers import DiffusionPipeline, DDIMScheduler
7
+ from diffusers.utils import export_to_video
8
 
9
+ # Khởi tạo mô hình
10
+ def load_model():
11
+ pipe = DiffusionPipeline.from_pretrained(
12
+ "guoyww/animatediff-motion-adapter-v1-5",
13
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
14
+ )
15
+ pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
16
+ pipe = pipe.to("cuda" if torch.cuda.is_available() else "cpu")
17
+ return pipe
18
 
19
+ # Hàm xử lý chính để tạo video từ ảnh
20
+ def animate_person(image, prompt, motion_bucket_id=127, fps=8):
21
  if image is None:
22
+ return None, "Vui lòng tải lên một hình ảnh."
 
 
 
 
 
 
 
23
 
24
  try:
25
+ # Xử chuẩn bị hình ảnh
26
+ if image.mode != "RGB":
27
+ image = image.convert("RGB")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # Resize hình ảnh để phù hợp với mô hình
30
+ w, h = image.size
31
+ if w > h:
32
+ new_w, new_h = 512, int(h * 512 / w)
33
  else:
34
+ new_w, new_h = int(w * 512 / h), 512
35
+
36
+ image = image.resize((new_w, new_h))
 
 
37
 
38
+ # Tạo mặt nạ để tập trung vào chủ thể (người)
39
+ # Mặt nạ đơn giản - trong thực tế có thể cần mô hình phân đoạn người phức tạp hơn
 
40
 
41
+ # Tải hình
42
+ pipe = load_model()
43
+
44
+ # Tạo video
45
+ if not prompt:
46
+ prompt = "A person moving naturally, photorealistic, high quality"
47
+
48
+ # Thêm hướng dẫn về chuyển động người để có kết quả tốt hơn
49
+ full_prompt = f"{prompt}, person in motion, smooth movement, natural pose, high quality, detailed"
50
+
51
+ # Sinh video
52
+ output = pipe(
53
+ prompt=full_prompt,
54
+ image=image,
55
+ negative_prompt="blurry, low quality, distorted, disfigured, bad anatomy",
56
+ num_frames=24,
57
+ guidance_scale=7.5,
58
+ num_inference_steps=50,
59
+ motion_bucket_id=motion_bucket_id
60
+ )
61
+
62
+ # Xuất video
63
+ video_path = "animated_person.mp4"
64
+ frames = output.frames[0]
65
+ export_to_video(frames, video_path, fps=fps)
66
+
67
+ return video_path, "Video được tạo thành công!"
68
  except Exception as e:
69
  return None, f"Lỗi: {str(e)}"
70
 
71
  # Tạo giao diện Gradio
72
+ with gr.Blocks(title="Tạo video người chuyển động từ ảnh") as demo:
73
+ gr.Markdown("# Tạo video người chuyển động từ ảnh")
74
+ gr.Markdown("Tải lên ảnh ngườixem họ chuyển động tự nhiên trong video")
75
 
76
  with gr.Row():
77
  with gr.Column():
78
+ image_input = gr.Image(type="pil", label="Tải lên ảnh người")
79
+ prompt_input = gr.Textbox(
80
+ label=" tả chuyển động",
81
+ placeholder=" tả cách người trong ảnh sẽ chuyển động...",
82
+ value="Person walking naturally, photorealistic"
83
+ )
84
+ motion_input = gr.Slider(
85
+ minimum=1, maximum=255, value=127, step=1,
86
+ label="Mức độ chuyển động (1-255)"
87
+ )
88
+ fps_input = gr.Slider(
89
+ minimum=6, maximum=30, value=8, step=1,
90
+ label="Số khung hình mỗi giây (FPS)"
91
  )
 
 
92
  submit_btn = gr.Button("Tạo video")
93
+
94
  with gr.Column():
95
  output_video = gr.Video(label="Video kết quả")
96
  output_message = gr.Textbox(label="Thông báo")
97
 
98
  submit_btn.click(
99
+ fn=animate_person,
100
+ inputs=[image_input, prompt_input, motion_input, fps_input],
101
  outputs=[output_video, output_message]
102
  )
103
 
104
+ gr.Markdown("### Lưu ý")
105
+ gr.Markdown("- Quá trình tạo video thể mất vài phút")
106
+ gr.Markdown("- Kết quả tốt nhất với ảnh người nét, chụp thẳng")
107
+ gr.Markdown("- Sử dụng prompt cụ thể để điều khiển kiểu chuyển động")
 
108
 
109
  demo.launch()
requirements.txt CHANGED
@@ -1,7 +1,6 @@
1
  gradio==4.0.2
2
  torch
3
  torchvision
4
- pillow
5
- numpy
6
- imageio==2.31.1
7
- imageio-ffmpeg
 
1
  gradio==4.0.2
2
  torch
3
  torchvision
4
+ diffusers>=0.24.0
5
+ transformers>=4.31.0
6
+ accelerate