ArmanRV commited on
Commit
35dac7a
·
verified ·
1 Parent(s): 49ba79d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -28
app.py CHANGED
@@ -1,6 +1,8 @@
1
  # -*- coding: utf-8 -*-
2
  import os
3
  import time
 
 
4
  from typing import List, Optional, Tuple
5
 
6
  import spaces
@@ -242,12 +244,6 @@ pipe.unet_encoder = UNet_Encoder
242
 
243
  # =========================
244
  # Inference (BASELINE params)
245
- # - num_inference_steps: 30
246
- # - guidance_scale: 2.0
247
- # - strength: 1.0
248
- # - seed: 42
249
- # - auto_mask: True (upper_body)
250
- # - crop_center: True
251
  # =========================
252
  @spaces.GPU
253
  def start_tryon(
@@ -405,42 +401,64 @@ def on_gallery_select(files_list: List[str], evt: gr.SelectData):
405
  return None, "⚠️ Каталог пуст"
406
  idx = int(evt.index) if evt.index is not None else 0
407
  idx = max(0, min(idx, len(files_list) - 1))
408
- return files_list[idx], f"👕 Выбрано: {files_list[idx]}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
 
411
  def tryon_ui(person_pil, selected_filename):
412
  # динамическое ожидание для UX (каждые 2–3 сек)
413
  for msg in [
414
- " Анализируем позу…",
415
- " Настраиваем посадку…",
416
- " Переносим ткань…",
417
- " Финальные штрихи…",
 
 
418
  ]:
419
- yield None, msg
420
  time.sleep(2.3)
421
 
422
  ok, msg = allow_call(2.5)
423
  if not ok:
424
- yield None, msg
425
  return
426
 
427
  if person_pil is None:
428
- yield None, "❌ Загрузите фото человека"
429
  return
430
  if not selected_filename:
431
- yield None, "❌ Выберите одежду (клик по превью)"
432
  return
433
 
434
  garm = load_garment_pil(selected_filename)
435
  if garm is None:
436
- yield None, "❌ Не удалось загрузить выбранную одежду"
437
  return
438
 
439
  try:
440
  out_img = start_tryon(human_pil=person_pil, garm_img=garm)
441
- yield out_img, "✅ Готово"
442
  except Exception as e:
443
- yield None, f"❌ Ошибка: {type(e).__name__}: {str(e)[:220]}"
444
 
445
 
446
  # boot
@@ -474,9 +492,8 @@ with gr.Blocks(title="Virtual Try-On Rendez-vous", css=CUSTOM_CSS) as demo:
474
  label="Раздел каталога",
475
  )
476
 
477
- with gr.Row():
478
- refresh_btn = gr.Button("🔄 Обновить каталог одежды", variant="secondary")
479
- selected_label = gr.Markdown("👕 Выберите одежду ниже")
480
 
481
  garment_gallery = gr.Gallery(
482
  label="Одежда для примерки",
@@ -492,6 +509,11 @@ with gr.Blocks(title="Virtual Try-On Rendez-vous", css=CUSTOM_CSS) as demo:
492
  with gr.Column():
493
  out = gr.Image(label="Результат", type="pil", height=760)
494
 
 
 
 
 
 
495
  gender.change(
496
  fn=refresh_catalog,
497
  inputs=[gender],
@@ -504,16 +526,24 @@ with gr.Blocks(title="Virtual Try-On Rendez-vous", css=CUSTOM_CSS) as demo:
504
  outputs=[selected_garment_state, selected_label],
505
  )
506
 
507
- refresh_btn.click(
508
- fn=refresh_catalog,
509
- inputs=[gender],
510
- outputs=[garment_gallery, garment_files_state, selected_garment_state, status, selected_label],
511
- )
512
-
513
  run.click(
514
  fn=tryon_ui,
515
  inputs=[person, selected_garment_state],
516
- outputs=[out, status],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
  concurrency_limit=1,
518
  )
519
 
 
1
  # -*- coding: utf-8 -*-
2
  import os
3
  import time
4
+ import json
5
+ from datetime import datetime
6
  from typing import List, Optional, Tuple
7
 
8
  import spaces
 
244
 
245
  # =========================
246
  # Inference (BASELINE params)
 
 
 
 
 
 
247
  # =========================
248
  @spaces.GPU
249
  def start_tryon(
 
401
  return None, "⚠️ Каталог пуст"
402
  idx = int(evt.index) if evt.index is not None else 0
403
  idx = max(0, min(idx, len(files_list) - 1))
404
+ # НЕ показываем имя файла
405
+ return files_list[idx], "👕 Одежда выбрана"
406
+
407
+
408
+ # =========================
409
+ # Feedback (like/dislike)
410
+ # =========================
411
+ FEEDBACK_DIR = "./feedback"
412
+ FEEDBACK_PATH = os.path.join(FEEDBACK_DIR, "feedback.jsonl")
413
+
414
+
415
+ def save_feedback(is_like: bool, garment_name: str):
416
+ os.makedirs(FEEDBACK_DIR, exist_ok=True)
417
+ record = {
418
+ "timestamp": datetime.utcnow().isoformat(),
419
+ "like": bool(is_like),
420
+ "garment": garment_name or "",
421
+ }
422
+ with open(FEEDBACK_PATH, "a", encoding="utf-8") as f:
423
+ f.write(json.dumps(record, ensure_ascii=False) + "\n")
424
+ return "Спасибо за отзыв 🙏"
425
 
426
 
427
  def tryon_ui(person_pil, selected_filename):
428
  # динамическое ожидание для UX (каждые 2–3 сек)
429
  for msg in [
430
+ "🧵 Анализируем посадку ткани…",
431
+ "📏 Подбираем пропорции…",
432
+ "🎨 Сохраняем цвет и фактуру…",
433
+ "🪡 Прорисовываем швы и детали…",
434
+ "✨ Наводим финальный лоск…",
435
+ "🪄 Почти готово…",
436
  ]:
437
+ yield None, msg, gr.update(visible=False)
438
  time.sleep(2.3)
439
 
440
  ok, msg = allow_call(2.5)
441
  if not ok:
442
+ yield None, msg, gr.update(visible=False)
443
  return
444
 
445
  if person_pil is None:
446
+ yield None, "❌ Загрузите фото человека", gr.update(visible=False)
447
  return
448
  if not selected_filename:
449
+ yield None, "❌ Выберите одежду (клик по превью)", gr.update(visible=False)
450
  return
451
 
452
  garm = load_garment_pil(selected_filename)
453
  if garm is None:
454
+ yield None, "❌ Не удалось загрузить выбранную одежду", gr.update(visible=False)
455
  return
456
 
457
  try:
458
  out_img = start_tryon(human_pil=person_pil, garm_img=garm)
459
+ yield out_img, "✅ Готово", gr.update(visible=True)
460
  except Exception as e:
461
+ yield None, f"❌ Ошибка: {type(e).__name__}: {str(e)[:220]}", gr.update(visible=False)
462
 
463
 
464
  # boot
 
492
  label="Раздел каталога",
493
  )
494
 
495
+ # Убрали кнопку обновления каталога и вывод имени файла
496
+ selected_label = gr.Markdown("👕 Выберите одежду ниже")
 
497
 
498
  garment_gallery = gr.Gallery(
499
  label="Одежда для примерки",
 
509
  with gr.Column():
510
  out = gr.Image(label="Результат", type="pil", height=760)
511
 
512
+ # Кнопки фидбэка появляются после успешной примерки
513
+ with gr.Row(visible=False) as feedback_row:
514
+ like_btn = gr.Button("👍 Нравится")
515
+ dislike_btn = gr.Button("👎 Не нравится")
516
+
517
  gender.change(
518
  fn=refresh_catalog,
519
  inputs=[gender],
 
526
  outputs=[selected_garment_state, selected_label],
527
  )
528
 
 
 
 
 
 
 
529
  run.click(
530
  fn=tryon_ui,
531
  inputs=[person, selected_garment_state],
532
+ outputs=[out, status, feedback_row],
533
+ concurrency_limit=1,
534
+ )
535
+
536
+ like_btn.click(
537
+ fn=lambda garment: save_feedback(True, garment),
538
+ inputs=[selected_garment_state],
539
+ outputs=[status],
540
+ concurrency_limit=1,
541
+ )
542
+
543
+ dislike_btn.click(
544
+ fn=lambda garment: save_feedback(False, garment),
545
+ inputs=[selected_garment_state],
546
+ outputs=[status],
547
  concurrency_limit=1,
548
  )
549