romi2001 commited on
Commit
7d63be3
·
verified ·
1 Parent(s): f88fe8c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -12
app.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
  import base64
3
  import os
4
  import urllib.parse
@@ -144,28 +143,38 @@ def pil_to_base64(img, max_size=280):
144
  return base64.b64encode(buf.getvalue()).decode("utf-8")
145
 
146
  # ---------------------------------------------------------------------------
147
- # EMBEDDING + FAISS SEARCH (תיקון חילוץ הוקטורים מתוך אובייקט ה-CLIP)
148
  # ---------------------------------------------------------------------------
149
  @torch.no_grad()
150
  def embed_query_image(pil_image):
151
  inputs = win_processor(images=pil_image, return_tensors="pt").to(DEVICE)
152
  outputs = win_model.get_image_features(**inputs)
153
- # תיקון קריטי: חילוץ וקטור המאפיינים האמיתי מתוך ה-BaseModelOutput
154
  if hasattr(outputs, "image_embeds"):
155
  feats = outputs.image_embeds
 
 
156
  else:
157
  feats = outputs
 
 
 
158
  return feats.cpu().numpy().astype("float32")
159
 
160
  @torch.no_grad()
161
  def embed_query_text(sentence):
162
  inputs = win_processor(text=[sentence], return_tensors="pt", padding=True, truncation=True).to(DEVICE)
163
  outputs = win_model.get_text_features(**inputs)
164
- # תיקון קריטי: חילוץ וקטור המאפיינים האמיתי מתוך ה-BaseModelOutput
165
  if hasattr(outputs, "text_embeds"):
166
  feats = outputs.text_embeds
 
 
167
  else:
168
  feats = outputs
 
 
 
169
  return feats.cpu().numpy().astype("float32")
170
 
171
  def build_feature_sentence(skin_tone, undertone, style_preference, gender=None, age_group=None):
@@ -247,6 +256,9 @@ def generate_new_outfit_image(pil_image, row, target_gender=None):
247
  resized_protect_img = Image.fromarray(protect.astype(np.uint8) * 255).resize((head_w, head_h), resample=Image.NEAREST)
248
 
249
  canvas = Image.new("RGB", (canvas_w, canvas_h), color=(240, 238, 235))
 
 
 
250
  canvas.paste(resized_face_crop, (paste_x, paste_y))
251
 
252
  mask_arr = np.full((canvas_h, canvas_w), 255, dtype=np.uint8)
@@ -400,7 +412,6 @@ body, .gradio-container { background-color: #F8F5F5 !important; font-family: 'In
400
  .gradio-container { max-width: 850px !important; margin: 0 auto !important; padding-top: 20px !important; }
401
  footer { display: none !important; }
402
 
403
- /* Global Font Contrast Controls - No Invisible Text */
404
  h1, h2, h3, p, span, label, input, select, textarea, button { color: #2C2A29 !important; }
405
 
406
  .tab-nav button { font-size: 14px !important; font-weight: 600 !important; padding: 14px 24px !important; color: #555 !important; }
@@ -409,7 +420,6 @@ h1, h2, h3, p, span, label, input, select, textarea, button { color: #2C2A29 !im
409
  #find-btn, .big-btn { background: #161617 !important; color: #FFFFFF !important; border: none !important; border-radius: 8px !important; font-weight: 700 !important; font-size: 14px !important; padding: 14px !important; text-transform: uppercase; letter-spacing: .08em !important; width: 100% !important; margin-top: 10px; }
410
  #find-btn:hover, .big-btn:hover { background: #2D2D2F !important; }
411
 
412
- /* Clean Pastel Premium Layout Blocks */
413
  .dark-panel { background: #FFFFFF !important; border-radius: 16px !important; padding: 24px !important; border: 1px solid #ECE4D6 !important; margin-bottom: 20px; }
414
  .dark-panel label, .dark-panel span { color: #2C2A29 !important; font-weight: 600; }
415
 
@@ -424,7 +434,6 @@ h1, h2, h3, p, span, label, input, select, textarea, button { color: #2C2A29 !im
424
  .color-bubble { width: 44px; height: 44px; border-radius: 50%; margin: 0 auto 6px; border: 1px solid rgba(0,0,0,.06); box-shadow: inset 0 0 0 2px #FFF; }
425
  .tip-text { font-size: 15px; color: #222222 !important; line-height: 1.6; margin: 0; font-style: italic; }
426
 
427
- /* Perfect 6-Card Row Flow without Hiding or Squishing */
428
  .outfit-grid { display: grid !important; grid-template-columns: repeat(3, 1fr) !important; gap: 20px !important; margin-top: 20px !important; width: 100% !important; }
429
  @media (max-width: 768px) { .outfit-grid { grid-template-columns: repeat(2, 1fr) !important; } }
430
  @media (max-width: 480px) { .outfit-grid { grid-template-columns: 1fr !important; } }
@@ -437,17 +446,16 @@ h1, h2, h3, p, span, label, input, select, textarea, button { color: #2C2A29 !im
437
  .prod-title { font-size: 15px; font-weight: 700; color: #111111 !important; margin: 0 0 4px 0; line-height: 1.3; min-height: 40px; display: flex; align-items: center; }
438
  .prod-brand { font-size: 13px; color: #999999 !important; margin-bottom: 14px; display: block; }
439
 
 
440
  .shop-btn { display: block; width: 100%; background: #161617; color: #FFFFFF !important; text-align: center; padding: 11px 0; border-radius: 8px; font-size: 13px; font-weight: 700; text-decoration: none !important; letter-spacing: 0.5px; }
441
  .shop-btn:hover { background: #2D2D2F; color: #FFFFFF !important; }
442
  .more-matches-label { font-size: 11px; font-weight: 700; color: #9C8E82 !important; letter-spacing: 1.6px; text-transform: uppercase; margin: 24px 0 12px; }
443
  .palette-name { font-family: 'Playfair Display', serif !important; }
444
- .footer-note { font-size: 13px; color: #A0A0A0 !important; text-align: center; margin-top: 16px; }
445
  """
446
 
447
  # ---------------------------------------------------------------------------
448
  # INTERFACE BUILD
449
  # ---------------------------------------------------------------------------
450
- # CRITICAL FIX: Moving custom CSS and theme injection parameters directly to the final launch function to comply with Gradio 6
451
  with gr.Blocks(title="Personal Color Styling") as demo:
452
  gr.HTML("""
453
  <div style="text-align:center; padding:24px 20px 10px;">
@@ -479,9 +487,13 @@ with gr.Blocks(title="Personal Color Styling") as demo:
479
  [style_card_a, new_img_a, answer_a, outfit_cards_a],
480
  )
481
 
482
- # CRITICAL FIX: All expected positional inputs must map corresponding elements to prevent load_example mismatches
483
  gr.Examples(
484
- examples=[[p, "woman", "adult", "What style would suit me best?"] for p in SAMPLE_PHOTOS],
 
 
 
 
485
  inputs=[photo_in, gender_a, age_a, question_a],
486
  outputs=[style_card_a, new_img_a, answer_a, outfit_cards_a],
487
  fn=recommend_from_photo,
@@ -518,5 +530,5 @@ with gr.Blocks(title="Personal Color Styling") as demo:
518
  )
519
 
520
  if __name__ == "__main__":
521
- # CRITICAL FIX: Safe execution of Gradio 6 theme parameters
522
  demo.launch(css=CUSTOM_CSS, theme=gr.themes.Soft(primary_hue="amber"))
 
 
1
  import base64
2
  import os
3
  import urllib.parse
 
143
  return base64.b64encode(buf.getvalue()).decode("utf-8")
144
 
145
  # ---------------------------------------------------------------------------
146
+ # EMBEDDING + FAISS SEARCH (תיקון סופי ומאובטח לחילוץ הוקטורים מחבילת CLIP)
147
  # ---------------------------------------------------------------------------
148
  @torch.no_grad()
149
  def embed_query_image(pil_image):
150
  inputs = win_processor(images=pil_image, return_tensors="pt").to(DEVICE)
151
  outputs = win_model.get_image_features(**inputs)
152
+ # חילוץ בטוח באמצעות בדיקת סוג האובייקט והפיכתו לטנסור טהור
153
  if hasattr(outputs, "image_embeds"):
154
  feats = outputs.image_embeds
155
+ elif isinstance(outputs, getattr(gr, "__package__", object)) or not hasattr(outputs, "cpu"):
156
+ feats = outputs[0] if (isinstance(outputs, tuple) or isinstance(outputs, list)) else outputs
157
  else:
158
  feats = outputs
159
+
160
+ if hasattr(feats, "detach"):
161
+ feats = feats.detach()
162
  return feats.cpu().numpy().astype("float32")
163
 
164
  @torch.no_grad()
165
  def embed_query_text(sentence):
166
  inputs = win_processor(text=[sentence], return_tensors="pt", padding=True, truncation=True).to(DEVICE)
167
  outputs = win_model.get_text_features(**inputs)
168
+ # חילוץ בטוח באמצעות בדיקת סוג האובייקט והפיכתו לטנסור טהור
169
  if hasattr(outputs, "text_embeds"):
170
  feats = outputs.text_embeds
171
+ elif isinstance(outputs, getattr(gr, "__package__", object)) or not hasattr(outputs, "cpu"):
172
+ feats = outputs[0] if (isinstance(outputs, tuple) or isinstance(outputs, list)) else outputs
173
  else:
174
  feats = outputs
175
+
176
+ if hasattr(feats, "detach"):
177
+ feats = feats.detach()
178
  return feats.cpu().numpy().astype("float32")
179
 
180
  def build_feature_sentence(skin_tone, undertone, style_preference, gender=None, age_group=None):
 
256
  resized_protect_img = Image.fromarray(protect.astype(np.uint8) * 255).resize((head_w, head_h), resample=Image.NEAREST)
257
 
258
  canvas = Image.new("RGB", (canvas_w, canvas_h), color=(240, 238, 235))
259
+ # תיקון קריטי: הגדרת משתני המיקום המקומיים לחישוב הקנבס
260
+ paste_x = (canvas_w - head_w) // 2
261
+ paste_y = int(canvas_h * 0.03)
262
  canvas.paste(resized_face_crop, (paste_x, paste_y))
263
 
264
  mask_arr = np.full((canvas_h, canvas_w), 255, dtype=np.uint8)
 
412
  .gradio-container { max-width: 850px !important; margin: 0 auto !important; padding-top: 20px !important; }
413
  footer { display: none !important; }
414
 
 
415
  h1, h2, h3, p, span, label, input, select, textarea, button { color: #2C2A29 !important; }
416
 
417
  .tab-nav button { font-size: 14px !important; font-weight: 600 !important; padding: 14px 24px !important; color: #555 !important; }
 
420
  #find-btn, .big-btn { background: #161617 !important; color: #FFFFFF !important; border: none !important; border-radius: 8px !important; font-weight: 700 !important; font-size: 14px !important; padding: 14px !important; text-transform: uppercase; letter-spacing: .08em !important; width: 100% !important; margin-top: 10px; }
421
  #find-btn:hover, .big-btn:hover { background: #2D2D2F !important; }
422
 
 
423
  .dark-panel { background: #FFFFFF !important; border-radius: 16px !important; padding: 24px !important; border: 1px solid #ECE4D6 !important; margin-bottom: 20px; }
424
  .dark-panel label, .dark-panel span { color: #2C2A29 !important; font-weight: 600; }
425
 
 
434
  .color-bubble { width: 44px; height: 44px; border-radius: 50%; margin: 0 auto 6px; border: 1px solid rgba(0,0,0,.06); box-shadow: inset 0 0 0 2px #FFF; }
435
  .tip-text { font-size: 15px; color: #222222 !important; line-height: 1.6; margin: 0; font-style: italic; }
436
 
 
437
  .outfit-grid { display: grid !important; grid-template-columns: repeat(3, 1fr) !important; gap: 20px !important; margin-top: 20px !important; width: 100% !important; }
438
  @media (max-width: 768px) { .outfit-grid { grid-template-columns: repeat(2, 1fr) !important; } }
439
  @media (max-width: 480px) { .outfit-grid { grid-template-columns: 1fr !important; } }
 
446
  .prod-title { font-size: 15px; font-weight: 700; color: #111111 !important; margin: 0 0 4px 0; line-height: 1.3; min-height: 40px; display: flex; align-items: center; }
447
  .prod-brand { font-size: 13px; color: #999999 !important; margin-bottom: 14px; display: block; }
448
 
449
+ /* כפתורי הרכישה המקוריים */
450
  .shop-btn { display: block; width: 100%; background: #161617; color: #FFFFFF !important; text-align: center; padding: 11px 0; border-radius: 8px; font-size: 13px; font-weight: 700; text-decoration: none !important; letter-spacing: 0.5px; }
451
  .shop-btn:hover { background: #2D2D2F; color: #FFFFFF !important; }
452
  .more-matches-label { font-size: 11px; font-weight: 700; color: #9C8E82 !important; letter-spacing: 1.6px; text-transform: uppercase; margin: 24px 0 12px; }
453
  .palette-name { font-family: 'Playfair Display', serif !important; }
 
454
  """
455
 
456
  # ---------------------------------------------------------------------------
457
  # INTERFACE BUILD
458
  # ---------------------------------------------------------------------------
 
459
  with gr.Blocks(title="Personal Color Styling") as demo:
460
  gr.HTML("""
461
  <div style="text-align:center; padding:24px 20px 10px;">
 
487
  [style_card_a, new_img_a, answer_a, outfit_cards_a],
488
  )
489
 
490
+ # תיקון: הגדרת מערך ערכים מלא ומדויק לכל הפרמטרים של ה-Examples כדי למנוע את שגיאת ה-load_example
491
  gr.Examples(
492
+ examples=[
493
+ [SAMPLE_PHOTOS[0], "woman", "adult", "What style would suit me best?"],
494
+ [SAMPLE_PHOTOS[1], "man", "adult", "What style would suit me best?"],
495
+ [SAMPLE_PHOTOS[2], "woman", "teen", "What style would suit me best?"]
496
+ ],
497
  inputs=[photo_in, gender_a, age_a, question_a],
498
  outputs=[style_card_a, new_img_a, answer_a, outfit_cards_a],
499
  fn=recommend_from_photo,
 
530
  )
531
 
532
  if __name__ == "__main__":
533
+ # העברת פרמטרי ה-CSS וה-Theme באופן בטוח לתוך פונקציית הריצה הסופית כנדרש בגרדיו 6
534
  demo.launch(css=CUSTOM_CSS, theme=gr.themes.Soft(primary_hue="amber"))