dschandra commited on
Commit
82fe2a7
·
verified ·
1 Parent(s): 9cd9511

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +260 -145
app.py CHANGED
@@ -1,160 +1,275 @@
1
  import os
 
 
2
  import numpy as np
3
- import base64
4
- import json
5
  import random
6
- import cv2
7
- from PIL import Image
8
  import requests
9
- import gradio as gr
 
10
 
11
- # In-memory user storage for demonstration
12
- users_db = {}
13
-
14
- # Ensure the model path is correct
15
- current_dir = os.path.dirname(os.path.abspath(__file__))
16
- default_model = os.path.join(current_dir, "models/eva/Eva_0.png")
17
-
18
- # Map of AI models with their corresponding file paths
19
- MODEL_MAP = {
20
- "AI Model Rouyan_0": os.path.join(current_dir, 'models/rouyan_new/Rouyan_0.png'),
21
- "AI Model Eva_0": os.path.join(current_dir, 'models/eva/Eva_0.png'),
22
- "AI Model Eva_1": os.path.join(current_dir, 'models/eva/Eva_1.png'),
23
- "AI Model Simon_0": os.path.join(current_dir, 'models/simon_online/Simon_0.png'),
24
- "AI Model Simon_1": os.path.join(current_dir, 'models/simon_online/Simon_1.png'),
25
- "AI Model Xuanxuan_0": os.path.join(current_dir, 'models/xiaoxuan_online/Xuanxuan_0.png'),
26
- "AI Model Xuanxuan_1": os.path.join(current_dir, 'models/xiaoxuan_online/Xuanxuan_1.png'),
27
- "AI Model Xuanxuan_2": os.path.join(current_dir, 'models/xiaoxuan_online/Xuanxuan_2.png'),
28
- "AI Model Yaqi_0": os.path.join(current_dir, 'models/yaqi/Yaqi_0.png'),
29
- "AI Model Yaqi_1": os.path.join(current_dir, 'models/yaqi/Yaqi_1.png'),
30
- "AI Model Yaqi_2": os.path.join(current_dir, 'models/yaqi/Yaqi_2.png'),
31
- "AI Model Yaqi_3": os.path.join(current_dir, 'models/yaqi/Yaqi_3.png'),
32
- "AI Model Yifeng_0": os.path.join(current_dir, 'models/yifeng_online/Yifeng_0.png'),
33
- "AI Model Yifeng_1": os.path.join(current_dir, 'models/yifeng_online/Yifeng_1.png'),
34
- "AI Model Yifeng_2": os.path.join(current_dir, 'models/yifeng_online/Yifeng_2.png'),
35
- "AI Model Yifeng_3": os.path.join(current_dir, 'models/yifeng_online/Yifeng_3.png'),
36
- }
37
 
38
- # Registration function
39
- def register(username, password, confirm_password):
40
- if username in users_db:
41
- return "Username already exists", gr.update(visible=True), gr.update(visible=False)
42
- if password != confirm_password:
43
- return "Passwords do not match", gr.update(visible=True), gr.update(visible=False)
44
- users_db[username] = password
45
- return "Registration successful! Please login.", gr.update(visible=True), gr.update(visible=False)
46
-
47
- # Login function
48
- def login(username, password):
49
- if users_db.get(username) == password:
50
- return gr.update(visible=False), gr.update(visible=True)
51
- else:
52
- return gr.update(visible=True), gr.update(visible=False)
53
-
54
- # Watermark function
55
- def add_watermark(image):
56
- height, width, _ = image.shape
57
- cv2.putText(image, 'Powered by OutfitAnyone', (int(0.3 * width), height - 20),
58
- cv2.FONT_HERSHEY_PLAIN, 2, (128, 128, 128), 2, cv2.LINE_AA)
59
- return image
60
-
61
- # Try-on result processing
62
- def get_tryon_result(model_name, top_garment, bottom_garment=None):
63
- model_key = "AI Model " + model_name.split("/")[-1].split(".")[0]
64
- print(f"Selected model: {model_key}")
65
-
66
- encoded_top = base64.b64encode(cv2.imencode('.jpg', top_garment)[1].tobytes()).decode('utf-8')
67
-
68
- # Check if bottom_garment is not None and is not an empty array
69
- encoded_bottom = ""
70
- if bottom_garment is not None and bottom_garment.size > 0:
71
- encoded_bottom = base64.b64encode(cv2.imencode('.jpg', bottom_garment)[1].tobytes()).decode('utf-8')
72
-
73
- server_url = os.environ.get('OA_IP_ADDRESS', 'http://localhost:5000')
74
- headers = {'Content-Type': 'application/json'}
75
- payload = {
76
- "garment1": encoded_top,
77
- "garment2": encoded_bottom,
78
- "model_name": model_key,
79
- "seed": random.randint(0, 99999999)
80
- }
81
 
 
 
 
 
 
 
 
 
 
 
82
  try:
83
- response = requests.post(server_url, headers=headers, data=json.dumps(payload))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  if response.status_code == 200:
86
- result = response.json()
87
- result_img = cv2.imdecode(np.frombuffer(base64.b64decode(result['images'][0]), np.uint8), cv2.IMREAD_UNCHANGED)
88
- final_img = add_watermark(result_img)
89
- return final_img
 
 
 
 
 
 
90
  else:
91
- print(f"Error: Server responded with status code {response.status_code}")
92
- return None
93
- except requests.exceptions.ConnectionError as e:
94
- print(f"ConnectionError: Could not connect to server at {server_url}. Please ensure the server is running.")
95
- print(f"Details: {e}")
96
- return None
97
- except requests.exceptions.RequestException as e:
98
- print(f"RequestException: An error occurred during the request.")
99
- print(f"Details: {e}")
100
- return None
101
-
102
- # Gradio Interface
103
- with gr.Blocks() as demo:
104
- gr.HTML("<script>console.log('Custom JavaScript');</script>")
105
- login_block = gr.Column(visible=True)
106
- register_block = gr.Column(visible=False)
107
- main_app = gr.Column(visible=False)
108
-
109
- # Registration Page
110
- with register_block:
111
- gr.HTML("<h2>Register for Outfit Anyone</h2>")
112
- username = gr.Textbox(label="Username")
113
- password = gr.Textbox(label="Password", type="password", elem_id="reg_pass")
114
- confirm_password = gr.Textbox(label="Confirm Password", type="password", elem_id="reg_conf_pass")
115
- register_button = gr.Button("Register")
116
- back_to_login_button = gr.Button("Back to Login")
117
- register_message = gr.Textbox(label="", visible=False)
118
-
119
- # Login Page
120
- with login_block:
121
- gr.HTML("<h2>Login to Outfit Anyone</h2>")
122
- username_login = gr.Textbox(label="Username")
123
- password_login = gr.Textbox(label="Password", type="password", elem_id="login_pass")
124
- login_button = gr.Button("Login")
125
- go_to_register_button = gr.Button("Register")
126
- login_message = gr.Textbox(label="", visible=False)
127
-
128
- # Main App Interface
129
- with main_app:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  gr.HTML("""
131
- <div style="text-align: center;">
132
- <h1>Outfit Anyone: Virtual Try-On</h1>
133
- <h4>v1.0</h4>
134
- <p>Upload your garments and choose a model to see the virtual try-on.</p>
 
135
  </div>
 
136
  """)
137
- with gr.Row():
138
- with gr.Column():
139
- model_selector = gr.Image(sources='upload', type="filepath", label="Model", value=default_model)
140
- example_models = gr.Examples(inputs=model_selector, examples=[MODEL_MAP['AI Model Rouyan_0'], MODEL_MAP['AI Model Eva_0']], examples_per_page=4)
141
- with gr.Column():
142
- gr.HTML("<h3>Select Garments for Virtual Try-On</h3>")
143
- top_garment_input = gr.Image(sources='upload', type="numpy", label="Top Garment")
144
- bottom_garment_input = gr.Image(sources='upload', type="numpy", label="Bottom Garment (Optional)")
145
- generate_button = gr.Button(value="Generate Outfit")
146
- with gr.Column():
147
- result_display = gr.Image()
148
-
149
- generate_button.click(fn=get_tryon_result, inputs=[model_selector, top_garment_input, bottom_garment_input], outputs=[result_display])
150
-
151
- # Button Click Actions
152
- register_button.click(fn=register, inputs=[username, password, confirm_password], outputs=[register_message, register_block, login_block])
153
- back_to_login_button.click(lambda: (gr.update(visible=False), gr.update(visible=True)), None, [register_block, login_block])
154
- go_to_register_button.click(lambda: (gr.update(visible=True), gr.update(visible=False)), None, [register_block, login_block])
155
- login_button.click(fn=login, inputs=[username_login, password_login], outputs=[login_block, main_app])
156
-
157
- if __name__ == "__main__":
158
- demo.queue(max_size=10)
159
- demo.launch(server_name="127.0.0.1", server_port=3300)
160
 
 
 
1
  import os
2
+ import cv2
3
+ import gradio as gr
4
  import numpy as np
 
 
5
  import random
6
+ import base64
 
7
  import requests
8
+ import json
9
+ import time
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ def tryon(person_img, garment_img, seed, randomize_seed):
13
+ post_start_time = time.time()
14
+ if person_img is None or garment_img is None:
15
+ gr.Warning("Empty image")
16
+ return None, None, "Empty image"
17
+ if randomize_seed:
18
+ seed = random.randint(0, MAX_SEED)
19
+ encoded_person_img = cv2.imencode('.jpg', cv2.cvtColor(person_img, cv2.COLOR_RGB2BGR))[1].tobytes()
20
+ encoded_person_img = base64.b64encode(encoded_person_img).decode('utf-8')
21
+ encoded_garment_img = cv2.imencode('.jpg', cv2.cvtColor(garment_img, cv2.COLOR_RGB2BGR))[1].tobytes()
22
+ encoded_garment_img = base64.b64encode(encoded_garment_img).decode('utf-8')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ url = "http://" + os.environ['tryon_url'] + "Submit"
25
+ token = os.environ['token']
26
+ cookie = os.environ['Cookie']
27
+ referer = os.environ['referer']
28
+ headers = {'Content-Type': 'application/json', 'token': token, 'Cookie': cookie, 'referer': referer}
29
+ data = {
30
+ "clothImage": encoded_garment_img,
31
+ "humanImage": encoded_person_img,
32
+ "seed": seed
33
+ }
34
  try:
35
+ response = requests.post(url, headers=headers, data=json.dumps(data), timeout=50)
36
+ # print("post response code", response.status_code)
37
+ if response.status_code == 200:
38
+ result = response.json()['result']
39
+ status = result['status']
40
+ if status == "success":
41
+ uuid = result['result']
42
+ # print(uuid)
43
+ except Exception as err:
44
+ print(f"Post Exception Error: {err}")
45
+ raise gr.Error("Too many users, please try again later")
46
+ post_end_time = time.time()
47
+ print(f"post time used: {post_end_time-post_start_time}")
48
+
49
+ get_start_time =time.time()
50
+ time.sleep(9)
51
+ Max_Retry = 12
52
+ result_img = None
53
+ info = ""
54
+ err_log = ""
55
+ for i in range(Max_Retry):
56
+ try:
57
+ url = "http://" + os.environ['tryon_url'] + "Query?taskId=" + uuid
58
+ response = requests.get(url, headers=headers, timeout=20)
59
+ # print("get response code", response.status_code)
60
+ if response.status_code == 200:
61
+ result = response.json()['result']
62
+ status = result['status']
63
+ if status == "success":
64
+ result = base64.b64decode(result['result'])
65
+ result_np = np.frombuffer(result, np.uint8)
66
+ result_img = cv2.imdecode(result_np, cv2.IMREAD_UNCHANGED)
67
+ result_img = cv2.cvtColor(result_img, cv2.COLOR_RGB2BGR)
68
+ info = "Success"
69
+ break
70
+ elif status == "error":
71
+ err_log = f"Status is Error"
72
+ info = "Error"
73
+ break
74
+ else:
75
+ # print(response.text)
76
+ err_log = "URL error, pleace contact the admin"
77
+ info = "URL error, pleace contact the admin"
78
+ break
79
+ except requests.exceptions.ReadTimeout:
80
+ err_log = "Http Timeout"
81
+ info = "Http Timeout, please try again later"
82
+ except Exception as err:
83
+ err_log = f"Get Exception Error: {err}"
84
+ time.sleep(1)
85
+ get_end_time = time.time()
86
+ print(f"get time used: {get_end_time-get_start_time}")
87
+ print(f"all time used: {get_end_time-get_start_time+post_end_time-post_start_time}")
88
+ if info == "":
89
+ err_log = f"No image after {Max_Retry} retries"
90
+ info = "Too many users, please try again later"
91
+ if info != "Success":
92
+ print(f"Error Log: {err_log}")
93
+ gr.Warning("Too many users, please try again later")
94
+
95
+ return result_img, seed, info
96
+
97
+ def start_tryon(person_img, garment_img, seed, randomize_seed):
98
+ start_time = time.time()
99
+ if person_img is None or garment_img is None:
100
+ return None, None, "Empty image"
101
+ if randomize_seed:
102
+ seed = random.randint(0, MAX_SEED)
103
+ encoded_person_img = cv2.imencode('.jpg', cv2.cvtColor(person_img, cv2.COLOR_RGB2BGR))[1].tobytes()
104
+ encoded_person_img = base64.b64encode(encoded_person_img).decode('utf-8')
105
+ encoded_garment_img = cv2.imencode('.jpg', cv2.cvtColor(garment_img, cv2.COLOR_RGB2BGR))[1].tobytes()
106
+ encoded_garment_img = base64.b64encode(encoded_garment_img).decode('utf-8')
107
 
108
+ url = "http://" + os.environ['tryon_url']
109
+ token = os.environ['token']
110
+ cookie = os.environ['Cookie']
111
+ referer = os.environ['referer']
112
+
113
+ headers = {'Content-Type': 'application/json', 'token': token, 'Cookie': cookie, 'referer': referer}
114
+ data = {
115
+ "clothImage": encoded_garment_img,
116
+ "humanImage": encoded_person_img,
117
+ "seed": seed
118
+ }
119
+
120
+ result_img = None
121
+ try:
122
+ session = requests.Session()
123
+ response = session.post(url, headers=headers, data=json.dumps(data), timeout=60)
124
+ print("response code", response.status_code)
125
  if response.status_code == 200:
126
+ result = response.json()['result']
127
+ status = result['status']
128
+ if status == "success":
129
+ result = base64.b64decode(result['result'])
130
+ result_np = np.frombuffer(result, np.uint8)
131
+ result_img = cv2.imdecode(result_np, cv2.IMREAD_UNCHANGED)
132
+ result_img = cv2.cvtColor(result_img, cv2.COLOR_RGB2BGR)
133
+ info = "Success"
134
+ else:
135
+ info = "Try again latter"
136
  else:
137
+ print(response.text)
138
+ info = "URL error, pleace contact the admin"
139
+ except requests.exceptions.ReadTimeout:
140
+ print("timeout")
141
+ info = "Too many users, please try again later"
142
+ raise gr.Error("Too many users, please try again later")
143
+ except Exception as err:
144
+ print(f"其他错误: {err}")
145
+ info = "Error, pleace contact the admin"
146
+ end_time = time.time()
147
+ print(f"time used: {end_time-start_time}")
148
+
149
+ return result_img, seed, info
150
+
151
+ MAX_SEED = 999999
152
+
153
+ example_path = os.path.join(os.path.dirname(__file__), 'assets')
154
+
155
+ garm_list = os.listdir(os.path.join(example_path,"cloth"))
156
+ garm_list_path = [os.path.join(example_path,"cloth",garm) for garm in garm_list]
157
+
158
+ human_list = os.listdir(os.path.join(example_path,"human"))
159
+ human_list_path = [os.path.join(example_path,"human",human) for human in human_list]
160
+
161
+ css="""
162
+ #col-left {
163
+ margin: 0 auto;
164
+ max-width: 430px;
165
+ }
166
+ #col-mid {
167
+ margin: 0 auto;
168
+ max-width: 430px;
169
+ }
170
+ #col-right {
171
+ margin: 0 auto;
172
+ max-width: 430px;
173
+ }
174
+ #col-showcase {
175
+ margin: 0 auto;
176
+ max-width: 1100px;
177
+ }
178
+ #button {
179
+ color: blue;
180
+ }
181
+ """
182
+
183
+ def load_description(fp):
184
+ with open(fp, 'r', encoding='utf-8') as f:
185
+ content = f.read()
186
+ return content
187
+
188
+ def change_imgs(image1, image2):
189
+ return image1, image2
190
+
191
+ with gr.Blocks(css=css) as Tryon:
192
+ gr.HTML(load_description("assets/title.md"))
193
+ with gr.Row():
194
+ with gr.Column(elem_id = "col-left"):
195
+ gr.HTML("""
196
+ <div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
197
+ <div>
198
+ Step 1. Upload a person image ⬇️
199
+ </div>
200
+ </div>
201
+ """)
202
+ with gr.Column(elem_id = "col-mid"):
203
+ gr.HTML("""
204
+ <div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
205
+ <div>
206
+ Step 2. Upload a garment image ⬇️
207
+ </div>
208
+ </div>
209
+ """)
210
+ with gr.Column(elem_id = "col-right"):
211
+ gr.HTML("""
212
+ <div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
213
+ <div>
214
+ Step 3. Press “Run” to get try-on results
215
+ </div>
216
+ </div>
217
+ """)
218
+ with gr.Row():
219
+ with gr.Column(elem_id = "col-left"):
220
+ imgs = gr.Image(label="Person image", sources='upload', type="numpy")
221
+ # category = gr.Dropdown(label="Garment category", choices=['upper_body', 'lower_body', 'dresses'], value="upper_body")
222
+ example = gr.Examples(
223
+ inputs=imgs,
224
+ examples_per_page=12,
225
+ examples=human_list_path
226
+ )
227
+ with gr.Column(elem_id = "col-mid"):
228
+ garm_img = gr.Image(label="Garment image", sources='upload', type="numpy")
229
+ example = gr.Examples(
230
+ inputs=garm_img,
231
+ examples_per_page=12,
232
+ examples=garm_list_path
233
+ )
234
+ with gr.Column(elem_id = "col-right"):
235
+ image_out = gr.Image(label="Result", show_share_button=False)
236
+ with gr.Row():
237
+ seed = gr.Slider(
238
+ label="Seed",
239
+ minimum=0,
240
+ maximum=MAX_SEED,
241
+ step=1,
242
+ value=0,
243
+ )
244
+ randomize_seed = gr.Checkbox(label="Random seed", value=True)
245
+ with gr.Row():
246
+ seed_used = gr.Number(label="Seed used")
247
+ result_info = gr.Text(label="Response")
248
+ # try_button = gr.Button(value="Run", elem_id="button")
249
+ test_button = gr.Button(value="Run", elem_id="button")
250
+
251
+
252
+ # try_button.click(fn=start_tryon, inputs=[imgs, garm_img, seed, randomize_seed], outputs=[image_out, seed_used, result_info], api_name='tryon',concurrency_limit=10)
253
+ test_button.click(fn=tryon, inputs=[imgs, garm_img, seed, randomize_seed], outputs=[image_out, seed_used, result_info], api_name=False, concurrency_limit=45)
254
+
255
+ with gr.Column(elem_id = "col-showcase"):
256
  gr.HTML("""
257
+ <div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
258
+ <div> </div>
259
+ <br>
260
+ <div>
261
+ Virtual try-on examples in pairs of person and garment images
262
  </div>
263
+ </div>
264
  """)
265
+ show_case = gr.Examples(
266
+ examples=[
267
+ ["assets/examples/model2.png", "assets/examples/garment2.png", "assets/examples/result2.png"],
268
+ ["assets/examples/model3.png", "assets/examples/garment3.png", "assets/examples/result3.png"],
269
+ ["assets/examples/model1.png", "assets/examples/garment1.png", "assets/examples/result1.png"],
270
+ ],
271
+ inputs=[imgs, garm_img, image_out],
272
+ label=None
273
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
 
275
+ Tryon.queue(api_open=False).launch(show_api=False)