Spaces:
Running
on
T4
Running
on
T4
Update app.py
Browse files
app.py
CHANGED
|
@@ -151,6 +151,37 @@ async def log_faceswap_hit(token: str, status: str = "success"):
|
|
| 151 |
# --------------------- Face Swap Pipeline ---------------------
|
| 152 |
swap_lock = threading.Lock()
|
| 153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
def face_swap_and_enhance(src_img, tgt_img, temp_dir=None):
|
| 155 |
try:
|
| 156 |
with swap_lock:
|
|
@@ -265,6 +296,29 @@ def download_from_spaces(key):
|
|
| 265 |
obj = client.get_object(Bucket=DO_SPACES_BUCKET, Key=key)
|
| 266 |
return obj['Body'].read()
|
| 267 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
# --------------------- API Endpoints ---------------------
|
| 269 |
@fastapi_app.get("/")
|
| 270 |
def root():
|
|
@@ -664,10 +718,17 @@ async def preview_result(result_key: str):
|
|
| 664 |
)
|
| 665 |
# --------------------- Mount Gradio ---------------------
|
| 666 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 667 |
|
| 668 |
if __name__ == "__main__":
|
| 669 |
uvicorn.run(fastapi_app, host="0.0.0.0", port=7860)
|
| 670 |
|
|
|
|
| 671 |
# # --------------------- List Images Endpoint ---------------------
|
| 672 |
# import os
|
| 673 |
# os.environ["OMP_NUM_THREADS"] = "1"
|
|
|
|
| 151 |
# --------------------- Face Swap Pipeline ---------------------
|
| 152 |
swap_lock = threading.Lock()
|
| 153 |
|
| 154 |
+
def multi_face_swap(src_img, tgt_img):
|
| 155 |
+
"""
|
| 156 |
+
Swap multiple faces from source image into target image.
|
| 157 |
+
Faces are matched left-to-right.
|
| 158 |
+
"""
|
| 159 |
+
src_bgr = cv2.cvtColor(src_img, cv2.COLOR_RGB2BGR)
|
| 160 |
+
tgt_bgr = cv2.cvtColor(tgt_img, cv2.COLOR_RGB2BGR)
|
| 161 |
+
|
| 162 |
+
src_faces = face_analysis_app.get(src_bgr)
|
| 163 |
+
tgt_faces = face_analysis_app.get(tgt_bgr)
|
| 164 |
+
|
| 165 |
+
if len(src_faces) < 1 or len(tgt_faces) < 1:
|
| 166 |
+
raise ValueError("No faces detected in one of the images")
|
| 167 |
+
|
| 168 |
+
# Sort faces left → right
|
| 169 |
+
src_faces = sorted(src_faces, key=lambda f: f.bbox[0])
|
| 170 |
+
tgt_faces = sorted(tgt_faces, key=lambda f: f.bbox[0])
|
| 171 |
+
|
| 172 |
+
face_count = min(len(src_faces), len(tgt_faces))
|
| 173 |
+
result_img = tgt_bgr.copy()
|
| 174 |
+
|
| 175 |
+
for i in range(face_count):
|
| 176 |
+
result_img = swapper.get(
|
| 177 |
+
result_img,
|
| 178 |
+
tgt_faces[i],
|
| 179 |
+
src_faces[i],
|
| 180 |
+
paste_back=True
|
| 181 |
+
)
|
| 182 |
+
|
| 183 |
+
return cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
|
| 184 |
+
|
| 185 |
def face_swap_and_enhance(src_img, tgt_img, temp_dir=None):
|
| 186 |
try:
|
| 187 |
with swap_lock:
|
|
|
|
| 296 |
obj = client.get_object(Bucket=DO_SPACES_BUCKET, Key=key)
|
| 297 |
return obj['Body'].read()
|
| 298 |
|
| 299 |
+
def build_multi_faceswap_gradio():
|
| 300 |
+
with gr.Blocks() as demo:
|
| 301 |
+
gr.Markdown("## 👩❤️👨 Multi Face Swap (Couple → Couple)")
|
| 302 |
+
|
| 303 |
+
with gr.Row():
|
| 304 |
+
src = gr.Image(type="numpy", label="Source Image (2 Faces)")
|
| 305 |
+
tgt = gr.Image(type="numpy", label="Target Image (2 Faces)")
|
| 306 |
+
|
| 307 |
+
out = gr.Image(type="numpy", label="Swapped Result")
|
| 308 |
+
error = gr.Textbox(label="Logs", interactive=False)
|
| 309 |
+
|
| 310 |
+
def process(src_img, tgt_img):
|
| 311 |
+
try:
|
| 312 |
+
result = multi_face_swap(src_img, tgt_img)
|
| 313 |
+
return result, ""
|
| 314 |
+
except Exception as e:
|
| 315 |
+
return None, str(e)
|
| 316 |
+
|
| 317 |
+
btn = gr.Button("Swap Faces")
|
| 318 |
+
btn.click(process, [src, tgt], [out, error])
|
| 319 |
+
|
| 320 |
+
return demo
|
| 321 |
+
|
| 322 |
# --------------------- API Endpoints ---------------------
|
| 323 |
@fastapi_app.get("/")
|
| 324 |
def root():
|
|
|
|
| 718 |
)
|
| 719 |
# --------------------- Mount Gradio ---------------------
|
| 720 |
|
| 721 |
+
multi_faceswap_app = build_multi_faceswap_gradio()
|
| 722 |
+
fastapi_app = mount_gradio_app(
|
| 723 |
+
fastapi_app,
|
| 724 |
+
multi_faceswap_app,
|
| 725 |
+
path="/gradio-multi"
|
| 726 |
+
)
|
| 727 |
|
| 728 |
if __name__ == "__main__":
|
| 729 |
uvicorn.run(fastapi_app, host="0.0.0.0", port=7860)
|
| 730 |
|
| 731 |
+
|
| 732 |
# # --------------------- List Images Endpoint ---------------------
|
| 733 |
# import os
|
| 734 |
# os.environ["OMP_NUM_THREADS"] = "1"
|