File size: 5,408 Bytes
15a1d54
93640ff
e2f298b
2907e7e
1604667
 
 
 
02519fd
1604667
02519fd
 
1604667
 
 
 
 
 
 
02519fd
 
 
 
 
1604667
 
 
 
02519fd
f34cf4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42f3d6b
1604667
f34cf4e
 
 
1604667
591a31c
f34cf4e
 
591a31c
 
f34cf4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1604667
02519fd
 
 
 
 
e01564b
8a3b9f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
02519fd
901d717
484d9a7
90ae56a
0dc0121
5f52a7e
02519fd
9796c19
b77daa5
02519fd
 
03c1299
ff36411
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63937a8
dfa3873
84549f8
8a3b9f6
 
 
 
 
 
 
 
 
 
02519fd
1604667
3d18ec5
f34cf4e
9735653
02519fd
b27fdec
02519fd
316ff73
8a3b9f6
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

import gradio as gr
from overlay import overlay_source
from detect_face import predict, NUM_CLASSES
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

# --- Handler khi click thumbnail của Gallery ---
# def on_gallery_select(evt: gr.SelectData):
#     """
#     Xử lý khi click vào ảnh trong gallery - tối ưu và robust.
#     """
#     val = evt.value
#     if isinstance(val, dict):
#         img = val.get("image")
#         if isinstance(img, str): return img
#         if isinstance(img, dict):
#             path = img.get("path") or img.get("url")
#             if isinstance(path, str): return path
#             for v in img.values():
#                 if isinstance(v, str) and os.path.isfile(v):
#                     return v
#         for v in val.values():
#             if isinstance(v, str) and os.path.isfile(v):
#                 return v
#         raise ValueError(f"Không trích được filepath từ dict: {val}")
#     if isinstance(val, str):
#         return val
#     raise ValueError(f"Kiểu không hỗ trợ: {type(val)}")

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.basename(filepath) 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 "", []

# --- Xây dựng giao diện Gradio ---
def build_demo():
    with gr.Blocks(title="Xử lý hai hình ảnh", theme=gr.themes.Soft()) as demo:
        gr.Markdown("Upload Background & Source, click **Run** to try on wigs.")

        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
                            )
            btn = gr.Button("🔄 Run", variant="primary",scale = 1)  
 


        # Chạy ghép tóc
        btn.click(fn=overlay_source, 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
        )
        # Nút tải lại ảnh thủ công (backup)
        # 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()