Spaces:
Running
Running
阿灰
commited on
Commit
·
9b9835e
1
Parent(s):
5b31657
init
Browse files- .gitattributes +2 -0
- app.py +443 -0
- files/example_images/ai_woman1.jpg +3 -0
- files/example_images/ai_woman2.jpg +3 -0
- files/example_images/anime.jpg +3 -0
- files/example_images/anime2.jpg +3 -0
- files/example_images/basket.jpg +3 -0
- files/example_images/eins.jpg +3 -0
- files/example_images/girl1.jpg +3 -0
- files/example_images/joker.jpg +3 -0
- files/example_images/robot.jpg +3 -0
- files/example_images/zz.jpg +3 -0
- files/example_videos/cai.mp4 +3 -0
- files/example_videos/girl.mp4 +3 -0
- files/example_videos/lee.mp4 +3 -0
- files/example_videos/ma.mp4 +3 -0
- files/example_videos/mimo1_origin.mp4 +3 -0
- files/example_videos/mimo2_origin.mp4 +3 -0
- files/example_videos/play_basketball.mp4 +3 -0
- files/example_videos/wushu.mp4 +3 -0
- requirements.txt +7 -0
.gitattributes
CHANGED
@@ -1,3 +1,5 @@
|
|
|
|
|
|
1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
|
|
1 |
+
*.jpg filter=lfs diff=lfs merge=lfs -text
|
2 |
+
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
3 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
4 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
5 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
@@ -0,0 +1,443 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
|
3 |
+
import requests
|
4 |
+
import os
|
5 |
+
import time
|
6 |
+
import json
|
7 |
+
from datetime import datetime
|
8 |
+
import oss2
|
9 |
+
import cv2
|
10 |
+
from pathlib import Path
|
11 |
+
import decord
|
12 |
+
from gradio.utils import get_cache_folder
|
13 |
+
|
14 |
+
cache_version = 20250325
|
15 |
+
dashscope_api_key = os.getenv("API_KEY","")
|
16 |
+
|
17 |
+
class Examples(gr.helpers.Examples):
|
18 |
+
def __init__(self, *args, directory_name=None, **kwargs):
|
19 |
+
super().__init__(*args, **kwargs, _initiated_directly=False)
|
20 |
+
if directory_name is not None:
|
21 |
+
self.cached_folder = get_cache_folder() / directory_name
|
22 |
+
self.cached_file = Path(self.cached_folder) / "log.csv"
|
23 |
+
self.create()
|
24 |
+
|
25 |
+
def upload_to_oss(local_file_path, remote_file_path, expire_time=3600):
|
26 |
+
remote_url = "motionshop/%s/%s" %(datetime.now().strftime("%Y%m%d"), remote_file_path)
|
27 |
+
for i in range(5):
|
28 |
+
try:
|
29 |
+
from oss2.credentials import EnvironmentVariableCredentialsProvider
|
30 |
+
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
|
31 |
+
bucket = oss2.Bucket(auth, 'oss-cn-hangzhou.aliyuncs.com', 'virtualbuy-devo')
|
32 |
+
bucket.put_object_from_file(key=remote_url, filename=local_file_path)
|
33 |
+
break
|
34 |
+
except Exception as e:
|
35 |
+
if i < 4: # If this is not the last retry
|
36 |
+
time.sleep(2) # Wait for 2 second before next retry
|
37 |
+
continue
|
38 |
+
else: # If this is the last retry and it still fails
|
39 |
+
raise e
|
40 |
+
return bucket.sign_url('GET', remote_url, expire_time)
|
41 |
+
|
42 |
+
def get_url(filepath):
|
43 |
+
filename = os.path.basename(filepath)
|
44 |
+
remote_file_path = "test/%s" %filename
|
45 |
+
return upload_to_oss(filepath, remote_file_path)
|
46 |
+
|
47 |
+
def online_detect(filepath):
|
48 |
+
url = "https://poc-dashscope.aliyuncs.com/api/v1/services/default/default/default"
|
49 |
+
headers = {
|
50 |
+
"Content-Type": "application/json",
|
51 |
+
"Authorization": "Bearer {}".format(dashscope_api_key)
|
52 |
+
}
|
53 |
+
data = {
|
54 |
+
"model": "pre-motionshop-detect-gradio",
|
55 |
+
"input": {
|
56 |
+
"video_url": filepath
|
57 |
+
},
|
58 |
+
"parameters": {
|
59 |
+
"threshold": 0.4,
|
60 |
+
"min_area_ratio": 0.001
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
print("Call detect api, params: " + json.dumps(data))
|
65 |
+
query_result_request = requests.post(
|
66 |
+
url,
|
67 |
+
json=data,
|
68 |
+
headers=headers
|
69 |
+
)
|
70 |
+
print("Detect api returned: " + query_result_request.text)
|
71 |
+
return json.loads(query_result_request.text)
|
72 |
+
|
73 |
+
def online_render(filepath, frame_id, bbox, replacement_ids, cache_url=None, model="pre-motionshop-render-gradio"):
|
74 |
+
url = "https://poc-dashscope.aliyuncs.com/api/v1/services/async-default/async-default/async-default"
|
75 |
+
headers = {
|
76 |
+
"Content-Type": "application/json",
|
77 |
+
"Authorization": "Bearer {}".format(dashscope_api_key),
|
78 |
+
"X-DashScope-Async": "enable"
|
79 |
+
}
|
80 |
+
data = {
|
81 |
+
"model": model,
|
82 |
+
# "model": "pre-motionshop-render-gradio",
|
83 |
+
"input": {
|
84 |
+
"video_url": filepath,
|
85 |
+
"frame_index": frame_id,
|
86 |
+
"bbox": bbox,
|
87 |
+
"replacement_id": replacement_ids
|
88 |
+
},
|
89 |
+
"parameters": {
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
if cache_url is not None:
|
94 |
+
data["input"]["cache_url"] = cache_url
|
95 |
+
|
96 |
+
print("Call render video api with params: " + json.dumps(data))
|
97 |
+
query_result_request = requests.post(
|
98 |
+
url,
|
99 |
+
json=data,
|
100 |
+
headers=headers
|
101 |
+
)
|
102 |
+
print("Render video api returned: " + query_result_request.text)
|
103 |
+
return json.loads(query_result_request.text)
|
104 |
+
|
105 |
+
def get_async_result(task_id):
|
106 |
+
while True:
|
107 |
+
result = requests.post(
|
108 |
+
"https://poc-dashscope.aliyuncs.com/api/v1/tasks/%s" %task_id,
|
109 |
+
headers={
|
110 |
+
"Authorization": "Bearer {}".format(dashscope_api_key),
|
111 |
+
}
|
112 |
+
)
|
113 |
+
result = json.loads(result.text)
|
114 |
+
if "output" in result and result["output"]["task_status"] in ["SUCCEEDED", "FAILED"]:
|
115 |
+
break
|
116 |
+
time.sleep(1)
|
117 |
+
return result
|
118 |
+
|
119 |
+
def save_video_cv2(vid, resize_video_input, resize_h, resize_w, fps):
|
120 |
+
fourcc = cv2.VideoWriter_fourcc(*'XVID')
|
121 |
+
out = cv2.VideoWriter(resize_video_input, fourcc, fps, (resize_w, resize_h))
|
122 |
+
for idx in range(len(vid)):
|
123 |
+
frame = vid[idx].asnumpy()[:,:,::-1]
|
124 |
+
frame = cv2.resize(frame,(resize_w, resize_h))
|
125 |
+
out.write(frame)
|
126 |
+
out.release()
|
127 |
+
|
128 |
+
def detect_human(video_input):
|
129 |
+
# print(video_input)
|
130 |
+
video_input_basename = os.path.basename(video_input)
|
131 |
+
resize_video_input = os.path.join(os.path.dirname(video_input), video_input_basename.split(".")[0]+"_resize."+video_input_basename.split(".")[-1])
|
132 |
+
vid = decord.VideoReader(video_input)
|
133 |
+
fps = vid.get_avg_fps()
|
134 |
+
H, W, C = vid[0].shape
|
135 |
+
if H > 1280 or W > 1280:
|
136 |
+
if H > W:
|
137 |
+
resize_h, resize_w = 1280, int(W*1280/H)
|
138 |
+
else:
|
139 |
+
resize_h, resize_w = int(H*1280/W), 1280
|
140 |
+
save_video_cv2(vid, resize_video_input, resize_h, resize_w, fps)
|
141 |
+
new_video_input = resize_video_input
|
142 |
+
else:
|
143 |
+
# resize_h, resize_w = H, W
|
144 |
+
new_video_input = video_input
|
145 |
+
video_url = get_url(new_video_input)
|
146 |
+
detect_result = online_detect(video_url)
|
147 |
+
check_result = "output" in detect_result
|
148 |
+
select_frame_index = detect_result["output"]["frame_index"]
|
149 |
+
boxes = detect_result["output"]["bbox"][:3]
|
150 |
+
print("Detected %d characters" %len(boxes))
|
151 |
+
|
152 |
+
cap = cv2.VideoCapture(new_video_input)
|
153 |
+
cap.set(cv2.CAP_PROP_POS_FRAMES, select_frame_index)
|
154 |
+
_, box_image = cap.read()
|
155 |
+
box_image = cv2.cvtColor(box_image, cv2.COLOR_BGR2RGB)
|
156 |
+
|
157 |
+
width, height = box_image.shape[1], box_image.shape[0]
|
158 |
+
|
159 |
+
for i, box in enumerate(boxes):
|
160 |
+
box = [
|
161 |
+
(box[0] - box[2] / 2) * width, (box[1] - box[3] / 2) * height,
|
162 |
+
(box[0] + box[2] / 2) * width, (box[1] + box[3] / 2) * height]
|
163 |
+
# box_image = cv2.rectangle(box_image, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2)
|
164 |
+
if i == 0:
|
165 |
+
box_image = cv2.rectangle(box_image, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (255, 0, 0), 2)
|
166 |
+
if i == 1:
|
167 |
+
box_image = cv2.rectangle(box_image, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 0), 2)
|
168 |
+
if i == 2:
|
169 |
+
box_image = cv2.rectangle(box_image, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 0, 255), 2)
|
170 |
+
|
171 |
+
# check_result, select_frame_index, box, box_image, _ = object_detector.getGroundingInfo(video_input)
|
172 |
+
video_state = {
|
173 |
+
"check_result": check_result,
|
174 |
+
"select_frame_index": select_frame_index,
|
175 |
+
"box": boxes,
|
176 |
+
"replace_ids": [],
|
177 |
+
"image_to_3d_tasks": {},
|
178 |
+
"video_url": video_url,
|
179 |
+
"video_path": new_video_input
|
180 |
+
}
|
181 |
+
return video_state, box_image, gr.update(visible=True), gr.update(visible=False)
|
182 |
+
|
183 |
+
def predict(video_state, first_image, second_image, third_image):
|
184 |
+
if len(video_state["box"]) == 0:
|
185 |
+
return None, "No human detected, please use a video with clear human"
|
186 |
+
|
187 |
+
print("images:", first_image, second_image, third_image)
|
188 |
+
|
189 |
+
tasks = []
|
190 |
+
boxes = []
|
191 |
+
if first_image is not None and len(video_state["box"]) >= 1:
|
192 |
+
tasks.append(image_to_3d(first_image))
|
193 |
+
boxes.append(video_state["box"][0])
|
194 |
+
|
195 |
+
if second_image is not None and len(video_state["box"]) >= 2:
|
196 |
+
tasks.append(image_to_3d(second_image))
|
197 |
+
boxes.append(video_state["box"][1])
|
198 |
+
|
199 |
+
if third_image is not None and len(video_state["box"]) >= 3:
|
200 |
+
tasks.append(image_to_3d(third_image))
|
201 |
+
boxes.append(video_state["box"][2])
|
202 |
+
|
203 |
+
if len(tasks) == 0:
|
204 |
+
return None, "Please upload at least one character photo for replacement."
|
205 |
+
|
206 |
+
ids = []
|
207 |
+
for t in tasks:
|
208 |
+
try:
|
209 |
+
image_to_3d_result = get_async_result(t)
|
210 |
+
print("image to 3d finished", image_to_3d_result)
|
211 |
+
ids.append(image_to_3d_result["output"]["ply_url"])
|
212 |
+
except Exception as e:
|
213 |
+
print(e)
|
214 |
+
return None, "Error in 3d model generation, please check the uploaded image"
|
215 |
+
|
216 |
+
if (video_state["check_result"]):
|
217 |
+
try:
|
218 |
+
taskid = online_render(video_state["video_url"], video_state["select_frame_index"], boxes, ids, None)["output"]["task_id"]
|
219 |
+
task_output = get_async_result(taskid)
|
220 |
+
print("Video synthesis completed, api returned: " + json.dumps(task_output))
|
221 |
+
video_url = task_output["output"]["synthesis_video_url"]
|
222 |
+
return video_url, "Processing Success"
|
223 |
+
except Exception as e:
|
224 |
+
print(e)
|
225 |
+
return None, "Error in video synthesis, please change the material and try again"
|
226 |
+
else:
|
227 |
+
return None, "Error in human detection, please use a video with clear human"
|
228 |
+
|
229 |
+
def online_img_to_3d(img_url):
|
230 |
+
url = "https://poc-dashscope.aliyuncs.com/api/v1/services/async-default/async-default/async-default"
|
231 |
+
headers = {
|
232 |
+
"Content-Type": "application/json",
|
233 |
+
"Authorization": "Bearer {}".format(dashscope_api_key),
|
234 |
+
"X-DashScope-Async": "enable"
|
235 |
+
}
|
236 |
+
data = {
|
237 |
+
# "model": "pre-Human3DGS",
|
238 |
+
"model": "pre-image-to-3d-gradio",
|
239 |
+
# "model": "pre-motionshop-render-h20-test",
|
240 |
+
"input": {
|
241 |
+
"image_url": img_url,
|
242 |
+
},
|
243 |
+
"parameters": {
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
+
query_result_request = requests.post(
|
248 |
+
url,
|
249 |
+
json=data,
|
250 |
+
headers=headers
|
251 |
+
)
|
252 |
+
print("Call image to 3d api, params: " + json.dumps(data))
|
253 |
+
return json.loads(query_result_request.text)
|
254 |
+
|
255 |
+
def image_to_3d(image_path):
|
256 |
+
url = get_url(image_path)
|
257 |
+
task_send_result = online_img_to_3d(url)
|
258 |
+
image_to_3d_task_id = task_send_result["output"]["task_id"]
|
259 |
+
return image_to_3d_task_id
|
260 |
+
|
261 |
+
def gradio_demo():
|
262 |
+
with gr.Blocks() as iface:
|
263 |
+
"""
|
264 |
+
state for
|
265 |
+
"""
|
266 |
+
|
267 |
+
video_state = gr.State(
|
268 |
+
{
|
269 |
+
"check_result": False,
|
270 |
+
"select_frame_index": 0,
|
271 |
+
"box": [],
|
272 |
+
"replace_ids": [],
|
273 |
+
"image_to_3d_tasks": {},
|
274 |
+
"video_url": "",
|
275 |
+
"video_path": ""
|
276 |
+
}
|
277 |
+
)
|
278 |
+
|
279 |
+
gr.HTML(
|
280 |
+
"""
|
281 |
+
<div style="display: flex; justify-content: center; align-items: center; text-align: center;">
|
282 |
+
<div>
|
283 |
+
<h1 >Motionshop2</h1>
|
284 |
+
<div style="display: flex; justify-content: center; align-items: center; text-align: center; margin: 20px; gap: 10px;">
|
285 |
+
<a class="flex-item" href="https://aigc3d.github.io/motionshop-2" target="_blank">
|
286 |
+
<img src="https://img.shields.io/badge/Project_Page-Motionshop2-green.svg" alt="Project Page">
|
287 |
+
</a>
|
288 |
+
<a class="flex-item" href="https://lingtengqiu.github.io/LHM/" target="_blank">
|
289 |
+
<img src="https://img.shields.io/badge/Project_Page-LHM-green.svg" alt="Project Page">
|
290 |
+
</a>
|
291 |
+
<a class="flex-item" href="https://github.com/aigc3d/LHM" target="_blank">
|
292 |
+
<img src="https://img.shields.io/badge/Github-LHM-blue.svg" alt="GitHub Code">
|
293 |
+
</a>
|
294 |
+
<a class="flex-item" href="https://arxiv.org/abs/2503.10625" target="_blank">
|
295 |
+
<img src="https://img.shields.io/badge/Paper-LHM-darkred.svg" alt="arXiv Paper">
|
296 |
+
</a>
|
297 |
+
</div>
|
298 |
+
|
299 |
+
</div>
|
300 |
+
</div>
|
301 |
+
"""
|
302 |
+
)
|
303 |
+
|
304 |
+
gr.Markdown("""<h4 style="color: green;"> 1. Choose or upload a video (duration<=15s, resolution<=720p)</h4>""")
|
305 |
+
with gr.Row():
|
306 |
+
with gr.Column():
|
307 |
+
gr.HTML("""
|
308 |
+
<style>
|
309 |
+
#input_video video, #output_video video {
|
310 |
+
height: 480px !important;
|
311 |
+
object-fit: contain;
|
312 |
+
}
|
313 |
+
#template_frame img {
|
314 |
+
height: 480px !important;
|
315 |
+
object-fit: contain;
|
316 |
+
}
|
317 |
+
</style>
|
318 |
+
""")
|
319 |
+
video_input = gr.Video(elem_id="input_video")
|
320 |
+
template_frame = gr.Image(type="pil",interactive=True, elem_id="template_frame", visible=False)
|
321 |
+
Examples(
|
322 |
+
fn=detect_human,
|
323 |
+
examples=sorted([
|
324 |
+
os.path.join("files", "example_videos", name)
|
325 |
+
for name in os.listdir(os.path.join("files", "example_videos"))
|
326 |
+
]),
|
327 |
+
run_on_click=True,
|
328 |
+
inputs=[video_input],
|
329 |
+
outputs=[video_state, template_frame, template_frame, video_input],
|
330 |
+
directory_name="examples_videos",
|
331 |
+
cache_examples=False,
|
332 |
+
)
|
333 |
+
|
334 |
+
gr.Markdown("""<h4 style="color: green;"> 2.Choose or upload images to replace </h4>""")
|
335 |
+
with gr.Row():
|
336 |
+
with gr.Column():
|
337 |
+
gr.Markdown("Replace the character in the red box with...")
|
338 |
+
with gr.Row():
|
339 |
+
first_image = gr.Image(type="filepath",interactive=True, elem_id="first_image", visible=True, height=480, width=270)
|
340 |
+
first_example = gr.Examples(
|
341 |
+
examples=sorted([os.path.join("files", "example_images", name) for name in os.listdir(os.path.join("files", "example_images"))]),
|
342 |
+
inputs=[first_image],
|
343 |
+
examples_per_page=6
|
344 |
+
)
|
345 |
+
with gr.Column():
|
346 |
+
gr.Markdown("Replace the character in the green box with...")
|
347 |
+
with gr.Row():
|
348 |
+
second_image = gr.Image(type="filepath",interactive=True, elem_id="second_image", visible=True, height=480, width=270)
|
349 |
+
second_example = gr.Examples(
|
350 |
+
examples=sorted([os.path.join("files", "example_images", name) for name in os.listdir(os.path.join("files", "example_images"))]),
|
351 |
+
inputs=[second_image],
|
352 |
+
examples_per_page=6
|
353 |
+
)
|
354 |
+
with gr.Column():
|
355 |
+
gr.Markdown("Replace the character in the blue box with...")
|
356 |
+
with gr.Row():
|
357 |
+
third_image = gr.Image(type="filepath",interactive=True, elem_id="third_image", visible=True, height=480, width=270)
|
358 |
+
third_example = gr.Examples(
|
359 |
+
examples=sorted([os.path.join("files", "example_images", name) for name in os.listdir(os.path.join("files", "example_images"))]),
|
360 |
+
inputs=[third_image],
|
361 |
+
examples_per_page=6
|
362 |
+
)
|
363 |
+
|
364 |
+
gr.Markdown("""<h4 style="color: green;"> 3.Click Start, each generation may takes 5 minutes. </h4>""")
|
365 |
+
with gr.Row():
|
366 |
+
with gr.Column():
|
367 |
+
motion_shop_predict_button = gr.Button(value="Start", variant="primary")
|
368 |
+
video_output = gr.Video(elem_id="output_video")
|
369 |
+
error_message = gr.Textbox(label="Processing Status", visible=True, interactive=False)
|
370 |
+
|
371 |
+
video_input.upload(
|
372 |
+
fn=detect_human,
|
373 |
+
inputs=[
|
374 |
+
video_input
|
375 |
+
],
|
376 |
+
outputs=[video_state, template_frame, template_frame, video_input],
|
377 |
+
)
|
378 |
+
|
379 |
+
motion_shop_predict_button.click(
|
380 |
+
fn=predict,
|
381 |
+
inputs=[video_state, first_image, second_image, third_image],
|
382 |
+
outputs=[video_output, error_message]
|
383 |
+
)
|
384 |
+
|
385 |
+
# clear input
|
386 |
+
template_frame.clear(
|
387 |
+
lambda: (
|
388 |
+
{
|
389 |
+
"check_result": False,
|
390 |
+
"select_frame_index": 0,
|
391 |
+
"box": [],
|
392 |
+
"replace_ids": [],
|
393 |
+
"image_to_3d_tasks": {},
|
394 |
+
"video_url": "",
|
395 |
+
"video_path": ""
|
396 |
+
},
|
397 |
+
None,
|
398 |
+
None,
|
399 |
+
None,
|
400 |
+
gr.update(visible=True),
|
401 |
+
gr.update(visible=False),
|
402 |
+
gr.update(value=None),
|
403 |
+
gr.update(value=None),
|
404 |
+
gr.update(value=None),
|
405 |
+
gr.update(value="")
|
406 |
+
),
|
407 |
+
[],
|
408 |
+
[
|
409 |
+
video_state,
|
410 |
+
video_output,
|
411 |
+
template_frame,
|
412 |
+
video_input,
|
413 |
+
video_input,
|
414 |
+
template_frame,
|
415 |
+
first_image,
|
416 |
+
second_image,
|
417 |
+
third_image,
|
418 |
+
error_message
|
419 |
+
],
|
420 |
+
queue=False,
|
421 |
+
show_progress=False)
|
422 |
+
|
423 |
+
# print("username:", uuid_output_field)
|
424 |
+
# set example
|
425 |
+
# gr.Markdown("## Examples")
|
426 |
+
# gr.Examples(
|
427 |
+
# examples=[os.path.join(os.path.dirname(__file__), "./test_sample/", test_sample) for test_sample in ["test-sample8.mp4","test-sample4.mp4", \
|
428 |
+
# "test-sample2.mp4","test-sample13.mp4"]],
|
429 |
+
# fn=run_example,
|
430 |
+
# inputs=[
|
431 |
+
# e.s video_input
|
432 |
+
# ],
|
433 |
+
# outputs=[video_input],
|
434 |
+
# # cache_examples=True,
|
435 |
+
# )
|
436 |
+
|
437 |
+
iface.queue(default_concurrency_limit=200)
|
438 |
+
iface.launch(debug=False, max_threads=10, server_name="0.0.0.0")
|
439 |
+
|
440 |
+
if __name__=="__main__":
|
441 |
+
gradio_demo()
|
442 |
+
|
443 |
+
# iface.launch(debug=True, enable_queue=True)
|
files/example_images/ai_woman1.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/ai_woman2.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/anime.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/anime2.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/basket.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/eins.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/girl1.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/joker.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/robot.jpg
ADDED
![]() |
Git LFS Details
|
files/example_images/zz.jpg
ADDED
![]() |
Git LFS Details
|
files/example_videos/cai.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:31bdf441813a78b4f0f259044ad6726d9dbeb608fb319c86a705799f5c750baf
|
3 |
+
size 1080169
|
files/example_videos/girl.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:89c05e6d68eebf7c87b282f4bc8bbef5b35069753c437f6c83a388d3e961f05d
|
3 |
+
size 2137986
|
files/example_videos/lee.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f4775fafc1dc2da3c4cd65df764f3dae43b95f8c5ff1ab3c30faea0070108e53
|
3 |
+
size 617387
|
files/example_videos/ma.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:9e31c0cc0897859cb6ea4c226287005b6e424511998a3a3549562afacabacbb5
|
3 |
+
size 1423057
|
files/example_videos/mimo1_origin.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:83d140279bfca2e649a7c84141361f88b9d2c899d66ca7e33f917692cf21c381
|
3 |
+
size 577767
|
files/example_videos/mimo2_origin.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:aecea22a348a584d2240f9565019ad36bcf959101456251e8990e48ca604b09e
|
3 |
+
size 440988
|
files/example_videos/play_basketball.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:3a3c99291456ea39efa1adbb4a86bc119a6f9def86c6b2d638a76e52c8247fc9
|
3 |
+
size 545834
|
files/example_videos/wushu.mp4
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1665e613af247ff59ee53250ab2bca981993f6250e21b3210539d2f32f57eee7
|
3 |
+
size 2319594
|
requirements.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio==5.1.0
|
2 |
+
opencv-python
|
3 |
+
ffmpeg
|
4 |
+
decord
|
5 |
+
numpy
|
6 |
+
oss2
|
7 |
+
wget
|