ArmanRV commited on
Commit
eef0060
·
verified ·
1 Parent(s): 978ca4f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -18
app.py CHANGED
@@ -61,11 +61,10 @@ def _patch_gradio_client_bool_schema():
61
  except Exception as e:
62
  print("gradio_client patch failed:", repr(e), flush=True)
63
 
64
- _patch_gradio_client_bool_schema()
65
 
 
66
 
67
  import torch
68
- import numpy as np
69
  from torchvision import transforms
70
 
71
  from huggingface_hub import login, snapshot_download
@@ -185,6 +184,8 @@ def clamp_int(x, lo, hi):
185
 
186
 
187
  _last_call_ts = 0.0
 
 
188
  def allow_call(min_interval_sec: float = 2.5) -> Tuple[bool, str]:
189
  global _last_call_ts
190
  now = time.time()
@@ -261,7 +262,6 @@ def start_tryon(
261
  denoise_steps: int = 25,
262
  seed: int = 42,
263
  ) -> Image.Image:
264
-
265
  device = "cuda" if torch.cuda.is_available() else "cpu"
266
  dtype = torch.float16 if device == "cuda" else torch.float32
267
 
@@ -302,16 +302,18 @@ def start_tryon(
302
  human_img_arg = _apply_exif_orientation(human_img.resize((384, 512)))
303
  human_img_arg = convert_PIL_to_numpy(human_img_arg, format="BGR")
304
 
305
- args = apply_net.create_argument_parser().parse_args((
306
- "show",
307
- "./configs/densepose_rcnn_R_50_FPN_s1x.yaml",
308
- "./ckpt/densepose/model_final_162be9.pkl",
309
- "dp_segm",
310
- "-v",
311
- "--opts",
312
- "MODEL.DEVICE",
313
- "cuda" if device == "cuda" else "cpu",
314
- ))
 
 
315
  pose_img = args.func(args, human_img_arg)
316
  pose_img = pose_img[:, :, ::-1]
317
  pose_img = Image.fromarray(pose_img).resize((768, 1024))
@@ -329,9 +331,14 @@ def start_tryon(
329
  if device == "cuda":
330
  autocast_ctx = torch.cuda.amp.autocast()
331
  else:
 
332
  class _NoCtx:
333
- def __enter__(self): return None
334
- def __exit__(self, *args): return False
 
 
 
 
335
  autocast_ctx = _NoCtx()
336
 
337
  with autocast_ctx:
@@ -392,7 +399,7 @@ def start_tryon(
392
 
393
 
394
  # =========================
395
- # UI (API-like)
396
  # =========================
397
  CUSTOM_CSS = """
398
  footer {display:none !important;}
@@ -401,6 +408,18 @@ div[class*="footer"] {display:none !important;}
401
  button[aria-label="Settings"] {display:none !important;}
402
  """
403
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  def refresh_catalog():
405
  ensure_garments_downloaded()
406
  files = list_garments()
@@ -408,6 +427,7 @@ def refresh_catalog():
408
  status = "✅ Каталог обновлён" if files else "⚠️ Каталог пуст (проверь dataset/токен)"
409
  return items, files, None, status
410
 
 
411
  def on_gallery_select(files_list: List[str], evt: gr.SelectData):
412
  if not files_list:
413
  return None, "⚠️ Каталог пуст"
@@ -415,6 +435,7 @@ def on_gallery_select(files_list: List[str], evt: gr.SelectData):
415
  idx = max(0, min(idx, len(files_list) - 1))
416
  return files_list[idx], f"👕 Выбрано: {files_list[idx]}"
417
 
 
418
  def tryon_ui(person_pil, selected_filename):
419
  yield None, "⏳ Обработка... (первый запуск может быть дольше)"
420
 
@@ -436,7 +457,7 @@ def tryon_ui(person_pil, selected_filename):
436
  return
437
 
438
  try:
439
- out = start_tryon(
440
  human_pil=person_pil,
441
  garm_img=garm,
442
  auto_mask=True,
@@ -444,7 +465,7 @@ def tryon_ui(person_pil, selected_filename):
444
  denoise_steps=25,
445
  seed=42,
446
  )
447
- yield out, "✅ Готово"
448
  except Exception as e:
449
  yield None, f"❌ Ошибка: {type(e).__name__}: {str(e)[:220]}"
450
 
@@ -464,6 +485,9 @@ with gr.Blocks(title="Virtual Try-On Rendez-vous", css=CUSTOM_CSS) as demo:
464
  with gr.Column():
465
  person = gr.Image(label="Фото человека", type="pil", height=420)
466
 
 
 
 
467
  with gr.Row():
468
  refresh_btn = gr.Button("🔄 Обновить каталог одежды", variant="secondary")
469
  selected_label = gr.Markdown("👕 Выберите одежду ниже")
 
61
  except Exception as e:
62
  print("gradio_client patch failed:", repr(e), flush=True)
63
 
 
64
 
65
+ _patch_gradio_client_bool_schema()
66
 
67
  import torch
 
68
  from torchvision import transforms
69
 
70
  from huggingface_hub import login, snapshot_download
 
184
 
185
 
186
  _last_call_ts = 0.0
187
+
188
+
189
  def allow_call(min_interval_sec: float = 2.5) -> Tuple[bool, str]:
190
  global _last_call_ts
191
  now = time.time()
 
262
  denoise_steps: int = 25,
263
  seed: int = 42,
264
  ) -> Image.Image:
 
265
  device = "cuda" if torch.cuda.is_available() else "cpu"
266
  dtype = torch.float16 if device == "cuda" else torch.float32
267
 
 
302
  human_img_arg = _apply_exif_orientation(human_img.resize((384, 512)))
303
  human_img_arg = convert_PIL_to_numpy(human_img_arg, format="BGR")
304
 
305
+ args = apply_net.create_argument_parser().parse_args(
306
+ (
307
+ "show",
308
+ "./configs/densepose_rcnn_R_50_FPN_s1x.yaml",
309
+ "./ckpt/densepose/model_final_162be9.pkl",
310
+ "dp_segm",
311
+ "-v",
312
+ "--opts",
313
+ "MODEL.DEVICE",
314
+ "cuda" if device == "cuda" else "cpu",
315
+ )
316
+ )
317
  pose_img = args.func(args, human_img_arg)
318
  pose_img = pose_img[:, :, ::-1]
319
  pose_img = Image.fromarray(pose_img).resize((768, 1024))
 
331
  if device == "cuda":
332
  autocast_ctx = torch.cuda.amp.autocast()
333
  else:
334
+
335
  class _NoCtx:
336
+ def __enter__(self):
337
+ return None
338
+
339
+ def __exit__(self, *args):
340
+ return False
341
+
342
  autocast_ctx = _NoCtx()
343
 
344
  with autocast_ctx:
 
399
 
400
 
401
  # =========================
402
+ # UI
403
  # =========================
404
  CUSTOM_CSS = """
405
  footer {display:none !important;}
 
408
  button[aria-label="Settings"] {display:none !important;}
409
  """
410
 
411
+ PHOTO_TIPS_MD = """
412
+ ### Какое фото подойдёт
413
+
414
+ ✅ В полный рост или по пояс
415
+ ✅ Руки и предметы не закрывают тело
416
+ ✅ Одежда по фигуре
417
+ ✅ Вы стоите прямо и смотрите в камеру
418
+ ✅ Хорошее освещение
419
+ ✅ В кадре нет других людей
420
+ """
421
+
422
+
423
  def refresh_catalog():
424
  ensure_garments_downloaded()
425
  files = list_garments()
 
427
  status = "✅ Каталог обновлён" if files else "⚠️ Каталог пуст (проверь dataset/токен)"
428
  return items, files, None, status
429
 
430
+
431
  def on_gallery_select(files_list: List[str], evt: gr.SelectData):
432
  if not files_list:
433
  return None, "⚠️ Каталог пуст"
 
435
  idx = max(0, min(idx, len(files_list) - 1))
436
  return files_list[idx], f"👕 Выбрано: {files_list[idx]}"
437
 
438
+
439
  def tryon_ui(person_pil, selected_filename):
440
  yield None, "⏳ Обработка... (первый запуск может быть дольше)"
441
 
 
457
  return
458
 
459
  try:
460
+ out_img = start_tryon(
461
  human_pil=person_pil,
462
  garm_img=garm,
463
  auto_mask=True,
 
465
  denoise_steps=25,
466
  seed=42,
467
  )
468
+ yield out_img, "✅ Готово"
469
  except Exception as e:
470
  yield None, f"❌ Ошибка: {type(e).__name__}: {str(e)[:220]}"
471
 
 
485
  with gr.Column():
486
  person = gr.Image(label="Фото человека", type="pil", height=420)
487
 
488
+ # ✅ Добавлено: подсказка сразу под загрузкой фото
489
+ gr.Markdown(PHOTO_TIPS_MD)
490
+
491
  with gr.Row():
492
  refresh_btn = gr.Button("🔄 Обновить каталог одежды", variant="secondary")
493
  selected_label = gr.Markdown("👕 Выберите одежду ниже")