Spaces:
aiqcamp
/
Running on Zero

aiqcamp commited on
Commit
e7295be
·
verified ·
1 Parent(s): b7c3bac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +273 -110
app.py CHANGED
@@ -16,7 +16,6 @@ from model.cloth_masker import AutoMasker, vis_mask
16
  from model.pipeline import CatVTONPipeline
17
  from utils import init_weight_dtype, resize_and_crop, resize_and_padding
18
 
19
-
20
  def parse_args():
21
  parser = argparse.ArgumentParser(description="Simple example of a training script.")
22
  parser.add_argument(
@@ -41,7 +40,6 @@ def parse_args():
41
  default="resource/demo/output",
42
  help="The output directory where the model predictions will be written.",
43
  )
44
-
45
  parser.add_argument(
46
  "--width",
47
  type=int,
@@ -103,7 +101,6 @@ def image_grid(imgs, rows, cols):
103
  grid.paste(img, box=(i % cols * w, i // cols * h))
104
  return grid
105
 
106
-
107
  args = parse_args()
108
  repo_path = snapshot_download(repo_id=args.resume_path)
109
  # Pipeline
@@ -168,7 +165,6 @@ def submit_function(
168
  mask = mask_processor.blur(mask, blur_factor=9)
169
 
170
  # Inference
171
- # try:
172
  result_image = pipeline(
173
  image=person_image,
174
  condition_image=cloth_image,
@@ -177,10 +173,6 @@ def submit_function(
177
  guidance_scale=guidance_scale,
178
  generator=generator
179
  )[0]
180
- # except Exception as e:
181
- # raise gr.Error(
182
- # "An error occurred. Please try again later: {}".format(e)
183
- # )
184
 
185
  # Post-process
186
  masked_person = vis_mask(person_image, mask)
@@ -202,136 +194,294 @@ def submit_function(
202
  new_result_image.paste(result_image, (condition_width + 5, 0))
203
  return new_result_image
204
 
205
-
206
  def person_example_fn(image_path):
207
  return image_path
208
 
209
-
210
  css = """
211
- footer {
212
- visibility: hidden;
 
 
 
 
 
213
  }
214
- """
215
 
 
 
 
 
 
 
216
 
217
- def app_gradio():
218
- with gr.Blocks(theme="Nymbo/Nymbo_Theme", css=css) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  with gr.Row():
221
  with gr.Column(scale=1, min_width=350):
222
- with gr.Row():
223
- image_path = gr.Image(
224
- type="filepath",
225
- interactive=True,
226
- visible=False,
227
- )
228
- person_image = gr.ImageEditor(
229
- interactive=True, label="Person Image", type="filepath"
230
- )
231
-
232
- with gr.Row():
233
- with gr.Column(scale=1, min_width=230):
234
- cloth_image = gr.Image(
235
- interactive=True, label="Condition Image", type="filepath"
236
- )
237
- with gr.Column(scale=1, min_width=120):
238
- gr.Markdown(
239
- '<span style="color: #808080; font-size: small;">Two ways to provide Mask:<br>1. Upload the person image and use the `🖌️` above to draw the Mask (higher priority)<br>2. Select the `Try-On Cloth Type` to generate automatically </span>'
240
  )
241
- cloth_type = gr.Radio(
242
- label="Try-On Cloth Type",
243
- choices=["upper", "lower", "overall"],
244
- value="upper",
 
245
  )
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
 
248
- submit = gr.Button("Submit")
249
  gr.Markdown(
250
- '<center><span style="color: #FF0000">!!! Click only Once, Wait for Delay !!!</span></center>'
 
 
 
 
251
  )
252
 
253
- gr.Markdown(
254
- '<span style="color: #808080; font-size: small;">Advanced options can adjust details:<br>1. `Inference Step` may enhance details;<br>2. `CFG` is highly correlated with saturation;<br>3. `Random seed` may improve pseudo-shadow.</span>'
255
- )
256
- with gr.Accordion("Advanced Options", open=False):
257
  num_inference_steps = gr.Slider(
258
- label="Inference Step", minimum=10, maximum=100, step=5, value=50
 
 
 
 
 
259
  )
260
- # Guidence Scale
261
  guidance_scale = gr.Slider(
262
- label="CFG Strenth", minimum=0.0, maximum=7.5, step=0.5, value=2.5
 
 
 
 
 
263
  )
264
- # Random Seed
265
  seed = gr.Slider(
266
- label="Seed", minimum=-1, maximum=10000, step=1, value=42
 
 
 
 
 
267
  )
268
  show_type = gr.Radio(
269
- label="Show Type",
270
  choices=["result only", "input & result", "input & mask & result"],
271
  value="input & mask & result",
 
272
  )
273
-
274
  with gr.Column(scale=2, min_width=500):
275
- result_image = gr.Image(interactive=False, label="Result")
276
- with gr.Row():
277
- # Photo Examples
278
- root_path = "resource/demo/example"
279
- with gr.Column():
280
- men_exm = gr.Examples(
281
- examples=[
282
- os.path.join(root_path, "person", "men", _)
283
- for _ in os.listdir(os.path.join(root_path, "person", "men"))
284
- ],
285
- examples_per_page=4,
286
- inputs=image_path,
287
- label="Person Examples ①",
288
- )
289
- women_exm = gr.Examples(
290
- examples=[
291
- os.path.join(root_path, "person", "women", _)
292
- for _ in os.listdir(os.path.join(root_path, "person", "women"))
293
- ],
294
- examples_per_page=4,
295
- inputs=image_path,
296
- label="Person Examples",
297
- )
298
- gr.Markdown(
299
- '<span style="color: #808080; font-size: small;">*Person examples come from the demos of <a href="https://huggingface.co/spaces/levihsu/OOTDiffusion">OOTDiffusion</a> and <a href="https://www.outfitanyone.org">OutfitAnyone</a>. </span>'
300
- )
301
- with gr.Column():
302
- condition_upper_exm = gr.Examples(
303
- examples=[
304
- os.path.join(root_path, "condition", "upper", _)
305
- for _ in os.listdir(os.path.join(root_path, "condition", "upper"))
306
- ],
307
- examples_per_page=4,
308
- inputs=cloth_image,
309
- label="Condition Upper Examples",
310
- )
311
- condition_overall_exm = gr.Examples(
312
- examples=[
313
- os.path.join(root_path, "condition", "overall", _)
314
- for _ in os.listdir(os.path.join(root_path, "condition", "overall"))
315
- ],
316
- examples_per_page=4,
317
- inputs=cloth_image,
318
- label="Condition Overall Examples",
319
- )
320
- condition_person_exm = gr.Examples(
321
- examples=[
322
- os.path.join(root_path, "condition", "person", _)
323
- for _ in os.listdir(os.path.join(root_path, "condition", "person"))
324
- ],
325
- examples_per_page=4,
326
- inputs=cloth_image,
327
- label="Condition Reference Person Examples",
328
- )
329
- gr.Markdown(
330
- '<span style="color: #808080; font-size: small;">*Condition examples come from the Internet. </span>'
331
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
  image_path.change(
334
- person_example_fn, inputs=image_path, outputs=person_image
 
 
335
  )
336
 
337
  submit.click(
@@ -347,8 +497,21 @@ def app_gradio():
347
  ],
348
  result_image,
349
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  demo.queue().launch(share=True, show_error=True)
351
 
352
-
353
  if __name__ == "__main__":
354
- app_gradio()
 
16
  from model.pipeline import CatVTONPipeline
17
  from utils import init_weight_dtype, resize_and_crop, resize_and_padding
18
 
 
19
  def parse_args():
20
  parser = argparse.ArgumentParser(description="Simple example of a training script.")
21
  parser.add_argument(
 
40
  default="resource/demo/output",
41
  help="The output directory where the model predictions will be written.",
42
  )
 
43
  parser.add_argument(
44
  "--width",
45
  type=int,
 
101
  grid.paste(img, box=(i % cols * w, i // cols * h))
102
  return grid
103
 
 
104
  args = parse_args()
105
  repo_path = snapshot_download(repo_id=args.resume_path)
106
  # Pipeline
 
165
  mask = mask_processor.blur(mask, blur_factor=9)
166
 
167
  # Inference
 
168
  result_image = pipeline(
169
  image=person_image,
170
  condition_image=cloth_image,
 
173
  guidance_scale=guidance_scale,
174
  generator=generator
175
  )[0]
 
 
 
 
176
 
177
  # Post-process
178
  masked_person = vis_mask(person_image, mask)
 
194
  new_result_image.paste(result_image, (condition_width + 5, 0))
195
  return new_result_image
196
 
 
197
  def person_example_fn(image_path):
198
  return image_path
199
 
200
+ # Custom CSS for enhanced visual appeal
201
  css = """
202
+ footer {visibility: hidden}
203
+
204
+ /* Main container styling */
205
+ .gradio-container {
206
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
207
+ border-radius: 20px;
208
+ box-shadow: 0 8px 32px rgba(31, 38, 135, 0.15);
209
  }
 
210
 
211
+ /* Header styling */
212
+ h1, h2, h3 {
213
+ color: #2c3e50;
214
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
215
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
216
+ }
217
 
218
+ /* Button styling */
219
+ button.primary-button {
220
+ background: linear-gradient(45deg, #4CAF50, #45a049);
221
+ border: none;
222
+ border-radius: 10px;
223
+ color: white;
224
+ padding: 12px 24px;
225
+ font-weight: bold;
226
+ transition: all 0.3s ease;
227
+ box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
228
+ }
229
+
230
+ button.primary-button:hover {
231
+ transform: translateY(-2px);
232
+ box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);
233
+ }
234
+
235
+ /* Image container styling */
236
+ .image-container {
237
+ border-radius: 15px;
238
+ overflow: hidden;
239
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
240
+ transition: transform 0.3s ease;
241
+ }
242
 
243
+ .image-container:hover {
244
+ transform: scale(1.02);
245
+ }
246
+
247
+ /* Radio button styling */
248
+ .radio-group label {
249
+ background-color: #ffffff;
250
+ border-radius: 8px;
251
+ padding: 10px 15px;
252
+ margin: 5px;
253
+ cursor: pointer;
254
+ transition: all 0.3s ease;
255
+ }
256
+
257
+ .radio-group input:checked + label {
258
+ background-color: #4CAF50;
259
+ color: white;
260
+ }
261
+
262
+ /* Slider styling */
263
+ .slider-container {
264
+ background: white;
265
+ padding: 15px;
266
+ border-radius: 10px;
267
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
268
+ }
269
+
270
+ .slider {
271
+ height: 8px;
272
+ border-radius: 4px;
273
+ background: #e0e0e0;
274
+ }
275
+
276
+ .slider .thumb {
277
+ width: 20px;
278
+ height: 20px;
279
+ background: #4CAF50;
280
+ border-radius: 50%;
281
+ box-shadow: 0 2px 5px rgba(0,0,0,0.2);
282
+ }
283
+
284
+ /* Alert/warning text styling */
285
+ .warning-text {
286
+ color: #ff5252;
287
+ font-weight: bold;
288
+ text-align: center;
289
+ padding: 10px;
290
+ background: rgba(255,82,82,0.1);
291
+ border-radius: 8px;
292
+ margin: 10px 0;
293
+ }
294
+
295
+ /* Example gallery styling */
296
+ .example-gallery {
297
+ display: grid;
298
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
299
+ gap: 15px;
300
+ padding: 15px;
301
+ background: white;
302
+ border-radius: 10px;
303
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
304
+ }
305
+
306
+ .example-item {
307
+ border-radius: 8px;
308
+ overflow: hidden;
309
+ transition: transform 0.3s ease;
310
+ }
311
+
312
+ .example-item:hover {
313
+ transform: scale(1.05);
314
+ }
315
+ """
316
+
317
+ def app_gradio():
318
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="blue"), css=css) as demo:
319
+ gr.Markdown(
320
+ """
321
+ # Virtual Try-On App 👔
322
+ Transform your look with AI-powered virtual clothing try-on!
323
+ """
324
+ )
325
+
326
  with gr.Row():
327
  with gr.Column(scale=1, min_width=350):
328
+ with gr.Box():
329
+ gr.Markdown("### 📸 Upload Images")
330
+ with gr.Row():
331
+ image_path = gr.Image(
332
+ type="filepath",
333
+ interactive=True,
334
+ visible=False,
 
 
 
 
 
 
 
 
 
 
 
335
  )
336
+ person_image = gr.ImageEditor(
337
+ interactive=True,
338
+ label="Person Image",
339
+ type="filepath",
340
+ elem_classes="image-container"
341
  )
342
 
343
+ with gr.Row():
344
+ with gr.Column(scale=1, min_width=230):
345
+ cloth_image = gr.Image(
346
+ interactive=True,
347
+ label="Clothing Item",
348
+ type="filepath",
349
+ elem_classes="image-container"
350
+ )
351
+ with gr.Column(scale=1, min_width=120):
352
+ gr.Markdown(
353
+ """
354
+ ### 🎯 Masking Options
355
+ 1. Draw mask manually with 🖌️
356
+ 2. Auto-generate based on clothing type
357
+ """
358
+ )
359
+ cloth_type = gr.Radio(
360
+ label="Clothing Type",
361
+ choices=["upper", "lower", "overall"],
362
+ value="upper",
363
+ elem_classes="radio-group"
364
+ )
365
 
366
+ submit = gr.Button("🚀 Generate Try-On", elem_classes="primary-button")
367
  gr.Markdown(
368
+ """
369
+ <div class="warning-text">
370
+ ⚠️ Please click only once and wait patiently for processing
371
+ </div>
372
+ """
373
  )
374
 
375
+ with gr.Accordion("⚙️ Advanced Settings", open=False):
 
 
 
376
  num_inference_steps = gr.Slider(
377
+ label="Quality Level",
378
+ minimum=10,
379
+ maximum=100,
380
+ step=5,
381
+ value=50,
382
+ elem_classes="slider-container"
383
  )
 
384
  guidance_scale = gr.Slider(
385
+ label="Style Strength",
386
+ minimum=0.0,
387
+ maximum=7.5,
388
+ step=0.5,
389
+ value=2.5,
390
+ elem_classes="slider-container"
391
  )
 
392
  seed = gr.Slider(
393
+ label="Random Seed",
394
+ minimum=-1,
395
+ maximum=10000,
396
+ step=1,
397
+ value=42,
398
+ elem_classes="slider-container"
399
  )
400
  show_type = gr.Radio(
401
+ label="Display Mode",
402
  choices=["result only", "input & result", "input & mask & result"],
403
  value="input & mask & result",
404
+ elem_classes="radio-group"
405
  )
 
406
  with gr.Column(scale=2, min_width=500):
407
+ result_image = gr.Image(
408
+ interactive=False,
409
+ label="Final Result",
410
+ elem_classes="image result_image = gr.Image(
411
+ interactive=False,
412
+ label="Final Result",
413
+ elem_classes="image-container"
414
+ )
415
+
416
+ with gr.Row():
417
+ # Photo Examples
418
+ root_path = "resource/demo/example"
419
+ with gr.Column():
420
+ gr.Markdown("#### 👤 Model Examples")
421
+ men_exm = gr.Examples(
422
+ examples=[
423
+ os.path.join(root_path, "person", "men", _)
424
+ for _ in os.listdir(os.path.join(root_path, "person", "men"))
425
+ ],
426
+ examples_per_page=4,
427
+ inputs=image_path,
428
+ label="Men's Examples",
429
+ elem_classes="example-item"
430
+ )
431
+ women_exm = gr.Examples(
432
+ examples=[
433
+ os.path.join(root_path, "person", "women", _)
434
+ for _ in os.listdir(os.path.join(root_path, "person", "women"))
435
+ ],
436
+ examples_per_page=4,
437
+ inputs=image_path,
438
+ label="Women's Examples",
439
+ elem_classes="example-item"
440
+ )
441
+ gr.Markdown(
442
+ '<div class="info-text">Model examples courtesy of <a href="https://huggingface.co/spaces/levihsu/OOTDiffusion">OOTDiffusion</a> and <a href="https://www.outfitanyone.org">OutfitAnyone</a></div>'
443
+ )
444
+
445
+ with gr.Column():
446
+ gr.Markdown("#### 👕 Clothing Examples")
447
+ condition_upper_exm = gr.Examples(
448
+ examples=[
449
+ os.path.join(root_path, "condition", "upper", _)
450
+ for _ in os.listdir(os.path.join(root_path, "condition", "upper"))
451
+ ],
452
+ examples_per_page=4,
453
+ inputs=cloth_image,
454
+ label="Upper Garments",
455
+ elem_classes="example-item"
456
+ )
457
+ condition_overall_exm = gr.Examples(
458
+ examples=[
459
+ os.path.join(root_path, "condition", "overall", _)
460
+ for _ in os.listdir(os.path.join(root_path, "condition", "overall"))
461
+ ],
462
+ examples_per_page=4,
463
+ inputs=cloth_image,
464
+ label="Full Outfits",
465
+ elem_classes="example-item"
466
+ )
467
+ condition_person_exm = gr.Examples(
468
+ examples=[
469
+ os.path.join(root_path, "condition", "person", _)
470
+ for _ in os.listdir(os.path.join(root_path, "condition", "person"))
471
+ ],
472
+ examples_per_page=4,
473
+ inputs=cloth_image,
474
+ label="Reference Styles",
475
+ elem_classes="example-item"
476
+ )
477
+ gr.Markdown(
478
+ '<div class="info-text">Clothing examples sourced from various online retailers</div>'
479
+ )
480
 
481
  image_path.change(
482
+ person_example_fn,
483
+ inputs=image_path,
484
+ outputs=person_image
485
  )
486
 
487
  submit.click(
 
497
  ],
498
  result_image,
499
  )
500
+
501
+ gr.Markdown(
502
+ """
503
+ ### 💡 Tips & Instructions
504
+ 1. Upload or select a person image
505
+ 2. Choose or upload a clothing item
506
+ 3. Select clothing type (upper/lower/overall)
507
+ 4. Adjust advanced settings if needed
508
+ 5. Click Generate and wait for results
509
+
510
+ For best results, use clear, front-facing images with good lighting.
511
+ """
512
+ )
513
+
514
  demo.queue().launch(share=True, show_error=True)
515
 
 
516
  if __name__ == "__main__":
517
+ app_gradio()