Spaces:
Runtime error
Runtime error
File size: 5,767 Bytes
83d879e e4cbd3b 83d879e 80ac965 83d879e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
import gradio as gr
from overlay import overlay_source
from detect_face import predict, NUM_CLASSES
from swapface import swap_face_now
import os
from pathlib import Path
BASE_DIR = Path(__file__).parent # thư mục chứa app.py
FOLDER = BASE_DIR / "example_wigs"
# --- Hàm load ảnh từ folder ---
def load_images_from_folder(folder_path: str) -> list[str]:
"""
Trả về list[str] chứa tất cả các hình (jpg, png, gif, bmp) trong folder_path.
"""
supported = {'.jpg', '.jpeg', '.png', '.gif', '.bmp'}
if not os.path.isdir(folder_path):
print(f"Cảnh báo: '{folder_path}' không phải folder hợp lệ.")
return []
files = [
os.path.join(folder_path, fn)
for fn in os.listdir(folder_path)
if os.path.splitext(fn)[1].lower() in supported
]
if not files:
print(f"Không tìm thấy hình trong: {folder_path}")
return files
def on_gallery_select(evt: gr.SelectData):
"""
Khi click thumbnail: trả về
1) filepath để nạp vào Image Source
2) tên file (basename) để hiển thị trong Textbox
"""
val = evt.value
# --- logic trích filepath y như cũ ---
if isinstance(val, dict):
img = val.get("image")
if isinstance(img, str):
filepath = img
elif isinstance(img, dict):
filepath = img.get("path") or img.get("url")
else:
filepath = next(
(v for v in val.values() if isinstance(v, str) and os.path.isfile(v)),
None
)
elif isinstance(val, str):
filepath = val
else:
raise ValueError(f"Kiểu không hỗ trợ: {type(val)}")
filename = os.path.splitext(os.path.basename(filepath))[0] if filepath else ""
return filepath, filename
# --- Hàm xác định folder dựa trên phân lớp ---
def infer_folder(image) -> str:
cls = predict(image)["predicted_class"]
folder = str(FOLDER / cls)
return folder
# --- Hàm gộp: phân loại + load ảnh ---
def handle_bg_change(image):
"""
Khi thay đổi background:
1. Phân loại khuôn mặt
2. Load ảnh từ folder tương ứng
"""
if image is None:
return "", []
try:
folder = infer_folder(image)
images = load_images_from_folder(folder)
return folder, images
except Exception as e:
print(f"Lỗi xử lý ảnh: {e}")
return "", []
# --- Hàm swap face ---
def swap_face_wrapper(background_img, result_img):
"""
Wrapper function cho swap face giữa background và result image
"""
if background_img is None or result_img is None:
return None
try:
# Swap face từ background vào result image
swapped = swap_face_now(background_img, result_img, do_enhance=True)
return swapped
except Exception as e:
print(f"Lỗi swap face: {e}")
return result_img # Trả về ảnh gốc nếu có lỗi
# --- Hàm gộp overlay + swap face ---
def combined_hair_and_face(background_img, source_img):
"""
Hàm gộp: chạy overlay trước, sau đó swap face
"""
if background_img is None or source_img is None:
return None
try:
# Bước 1: Chạy overlay (ghép tóc)
hair_result = overlay_source(background_img, source_img)
# Bước 2: Chạy swap face từ background lên kết quả overlay
final_result = swap_face_wrapper(background_img, hair_result)
return final_result
except Exception as e:
print(f"Lỗi trong quá trình gộp hair + face: {e}")
return None
# --- Xây dựng giao diện Gradio ---
def build_demo():
with gr.Blocks(title="Hair Try-On & Face Swap", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🎯 Hair Try-On & Face Swap Application
""")
with gr.Row():
bg = gr.Image(type="pil", label="Background", height=500)
src = gr.Image(type="pil", label="Source", height=500, interactive=False)
out = gr.Image(label="Result", height=500, interactive=False)
folder_path_box = gr.Textbox(label="Folder path", visible=False)
with gr.Row():
src_name_box = gr.Textbox(
label="Wigs Name",
interactive=False,
show_copy_button=True , # tuỳ chọn – tiện copy đường dẫn
scale = 1
)
gallery = gr.Gallery(
label="Recommend For You",
height=300,
value=[],
type="filepath",
interactive=False,
columns=5,
object_fit="cover",
allow_preview=True,
scale = 8
)
combined_btn = gr.Button("✨ Try on now", variant="primary")
# Chạy gộp hair + face swap
combined_btn.click(fn=combined_hair_and_face, inputs=[bg, src], outputs=[out])
# Khi đổi ảnh background, tự động phân loại và load ảnh gợi ý
bg.change(
fn=handle_bg_change,
inputs=[bg],
outputs=[folder_path_box, gallery],
show_progress=True
)
# Khi chọn ảnh trong gallery, cập nhật vào khung Source
gallery.select(
fn=on_gallery_select,
outputs=[src, src_name_box]
)
return demo
if __name__ == "__main__":
build_demo().launch()
|