fanboyd13 commited on
Commit
6a75bb1
Β·
verified Β·
1 Parent(s): 2c327cc

Upload 2 files

Browse files
Files changed (2) hide show
  1. app (1).py +181 -0
  2. requirements (2).txt +14 -0
app (1).py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ app.py β€” OOTDiffusion Hugging Face Space
3
+ Place this file in the ROOT of your Space repo.
4
+
5
+ Your Space structure should look like:
6
+ OOODdiffusion/
7
+ β”œβ”€β”€ app.py ← this file (root level)
8
+ β”œβ”€β”€ requirements.txt ← root level
9
+ β”œβ”€β”€ README.md ← root level
10
+ └── OOTDiffusion-main/ ← the uploaded zip contents
11
+ β”œβ”€β”€ ootd/
12
+ β”œβ”€β”€ run/
13
+ β”œβ”€β”€ preprocess/
14
+ β”œβ”€β”€ checkpoints/
15
+ └── ...
16
+ """
17
+
18
+ import sys
19
+ import os
20
+
21
+ # ── Path setup ────────────────────────────────────────────────────────────────
22
+ ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
23
+
24
+ # Support both flat layout and nested OOTDiffusion-main/ layout
25
+ OOTD_DIR = ROOT_DIR
26
+ for candidate in ["OOTDiffusion-main", "OOTDiffusion"]:
27
+ candidate_path = os.path.join(ROOT_DIR, candidate)
28
+ if os.path.isdir(candidate_path):
29
+ OOTD_DIR = candidate_path
30
+ break
31
+
32
+ RUN_DIR = os.path.join(OOTD_DIR, "run")
33
+
34
+ sys.path.insert(0, OOTD_DIR)
35
+ sys.path.insert(0, RUN_DIR)
36
+
37
+ print(f"[OOTDiffusion] ROOT_DIR : {ROOT_DIR}")
38
+ print(f"[OOTDiffusion] OOTD_DIR : {OOTD_DIR}")
39
+
40
+ import torch
41
+ import numpy as np
42
+ import gradio as gr
43
+ from PIL import Image
44
+
45
+ # ── Device ────────────────────────────────────────────────────────────────────
46
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
47
+ print(f"[OOTDiffusion] Device: {DEVICE}")
48
+
49
+ # ── Lazy-load models ──────────────────────────────────────────────────────────
50
+ _pipe_hd = None
51
+ _pipe_dc = None
52
+
53
+
54
+ def load_pipeline(model_type: str):
55
+ global _pipe_hd, _pipe_dc
56
+ if model_type == "hd":
57
+ if _pipe_hd is None:
58
+ from ootd.inference_ootd_hd import OOTDiffusionHD
59
+ print("[OOTDiffusion] Loading HD pipeline …")
60
+ _pipe_hd = OOTDiffusionHD(OOTD_DIR)
61
+ return _pipe_hd
62
+ else:
63
+ if _pipe_dc is None:
64
+ from ootd.inference_ootd_dc import OOTDiffusionDC
65
+ print("[OOTDiffusion] Loading DC pipeline …")
66
+ _pipe_dc = OOTDiffusionDC(OOTD_DIR)
67
+ return _pipe_dc
68
+
69
+
70
+ # ── Category mapping ──────────────────────────────────────────────────────────
71
+ CATEGORY_MAP = {
72
+ "Upper-body": 0,
73
+ "Lower-body": 1,
74
+ "Dress": 2,
75
+ }
76
+
77
+
78
+ # ── Inference ─────────────────────────────────────────────────────────────────
79
+ def run_tryon(model_image, cloth_image, model_type, category_label,
80
+ n_samples, n_steps, guidance_scale, seed):
81
+
82
+ if model_image is None:
83
+ raise gr.Error("Please upload a model (person) image.")
84
+ if cloth_image is None:
85
+ raise gr.Error("Please upload a garment image.")
86
+
87
+ if isinstance(model_image, np.ndarray):
88
+ model_image = Image.fromarray(model_image)
89
+ if isinstance(cloth_image, np.ndarray):
90
+ cloth_image = Image.fromarray(cloth_image)
91
+
92
+ model_image = model_image.convert("RGB")
93
+ cloth_image = cloth_image.convert("RGB")
94
+
95
+ category_idx = CATEGORY_MAP[category_label]
96
+
97
+ try:
98
+ pipe = load_pipeline(model_type)
99
+ except Exception as e:
100
+ raise gr.Error(
101
+ f"Failed to load model: {e}\n"
102
+ "Make sure OOTDiffusion-main/ folder with ootd/ and checkpoints/ is present."
103
+ )
104
+
105
+ try:
106
+ result = pipe(
107
+ model_type=model_type,
108
+ category=category_idx,
109
+ image_garm=cloth_image,
110
+ image_vton=model_image,
111
+ mask=None,
112
+ image_ori=model_image,
113
+ num_samples=int(n_samples),
114
+ num_steps=int(n_steps),
115
+ guidance_scale=float(guidance_scale),
116
+ seed=int(seed),
117
+ )
118
+ except Exception as e:
119
+ raise gr.Error(f"Inference failed: {e}")
120
+
121
+ if isinstance(result, (list, tuple)):
122
+ return result
123
+ return [result]
124
+
125
+
126
+ # ── Gradio UI ─────────────────────────────────────────────────────────────────
127
+ with gr.Blocks(title="OOTDiffusion Virtual Try-On", theme=gr.themes.Soft()) as demo:
128
+
129
+ gr.Markdown("""
130
+ # πŸ‘— OOTDiffusion β€” Virtual Try-On
131
+ **[AAAI 2025]** Upload a *person photo* and a *garment image*, then click **Run Try-On**.
132
+ > ⚠️ Non-commercial use only (CC-BY-NC-SA-4.0)
133
+ """)
134
+
135
+ with gr.Row():
136
+ with gr.Column(scale=1):
137
+ model_img = gr.Image(label="πŸ‘€ Model Image (person)", type="pil", height=380)
138
+ cloth_img = gr.Image(label="πŸ‘• Garment Image", type="pil", height=380)
139
+
140
+ with gr.Column(scale=1):
141
+ model_type = gr.Radio(
142
+ choices=["hd", "dc"], value="hd",
143
+ label="Model Type",
144
+ info="hd = half-body (VITON-HD) | dc = full-body (Dress Code)"
145
+ )
146
+ category = gr.Dropdown(
147
+ choices=list(CATEGORY_MAP.keys()), value="Upper-body",
148
+ label="Garment Category",
149
+ info="Only matters when Model Type = dc"
150
+ )
151
+ n_samples = gr.Slider(1, 4, step=1, value=1, label="Number of Samples")
152
+ n_steps = gr.Slider(10, 40, step=5, value=20, label="Denoising Steps",
153
+ info="More steps = better quality, slower")
154
+ guidance = gr.Slider(1.0, 5.0, step=0.5, value=2.0, label="Guidance Scale")
155
+ seed = gr.Number(value=42, label="Seed (-1 = random)", precision=0)
156
+ run_btn = gr.Button("πŸš€ Run Try-On", variant="primary", size="lg")
157
+
158
+ with gr.Column(scale=1):
159
+ output_gallery = gr.Gallery(
160
+ label="✨ Try-On Results",
161
+ columns=2, height=500, object_fit="contain"
162
+ )
163
+
164
+ gr.Markdown("""
165
+ ### πŸ’‘ Tips
166
+ - **HD model** β€” best for upper-body garments on half-body photos
167
+ - **DC model** β€” supports upper / lower / dress on full-body photos
168
+ - Steps **30–40** give noticeably better quality
169
+ - **Seed = -1** gives a different result each run
170
+ """)
171
+
172
+ run_btn.click(
173
+ fn=run_tryon,
174
+ inputs=[model_img, cloth_img, model_type, category,
175
+ n_samples, n_steps, guidance, seed],
176
+ outputs=output_gallery,
177
+ )
178
+
179
+ # ── Launch ────────────────────────────────────────────────────────────────────
180
+ if __name__ == "__main__":
181
+ demo.launch()
requirements (2).txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ torch
2
+ torchvision
3
+ torchaudio
4
+ numpy
5
+ Pillow
6
+ diffusers==0.24.0
7
+ transformers==4.36.2
8
+ accelerate==0.25.0
9
+ omegaconf
10
+ einops
11
+ opencv-python-headless
12
+ scikit-image
13
+ huggingface_hub
14
+ onnxruntime