Ox1 Cursor commited on
Commit
ba65fe9
·
1 Parent(s): 12e8038

feat(ui): add capture mode selector (single/multi/video WIP)

Browse files

Add a Radio selector in the Capture tab with three modes:
- Single garment: skips YOLO, sends photo directly to VLM with
single-garment prompt (ideal for close-up photos)
- Multiple garments: full pipeline (YOLO + crops + VLM per crop,
fallback to multi-garment VLM analysis)
- Video stream: placeholder showing "coming soon" message

New vision.extract_single_from_path() for direct single-garment
extraction without YOLO detection step.

Co-authored-by: Cursor <cursoragent@cursor.com>

Files changed (2) hide show
  1. app.py +21 -5
  2. src/vision.py +15 -0
app.py CHANGED
@@ -11,7 +11,7 @@ import os
11
 
12
  import gradio as gr
13
 
14
- from src.vision import extract_garments
15
  from src.catalog import (
16
  add_garments,
17
  load_catalog,
@@ -47,16 +47,23 @@ mediante lenguaje natural. Sube fotos → detecta prendas → pregunta lo que qu
47
  """
48
 
49
 
50
- def analyze_images(images):
51
- """Process uploaded images and extract garments."""
52
  if not images:
53
  return "Sube al menos una imagen.", []
54
 
 
 
 
55
  all_added = []
56
  for img_data in images:
57
  image_path = img_data if isinstance(img_data, str) else img_data.name
58
  try:
59
- garments_with_crops = extract_garments(image_path)
 
 
 
 
60
  if garments_with_crops:
61
  added = add_garments(garments_with_crops)
62
  all_added.extend(added)
@@ -295,6 +302,15 @@ with gr.Blocks(title="Wardrobe AI") as demo:
295
 
296
  with gr.Row():
297
  with gr.Column(scale=1):
 
 
 
 
 
 
 
 
 
298
  image_input = gr.File(
299
  label="Fotos del armario",
300
  file_count="multiple",
@@ -313,7 +329,7 @@ with gr.Blocks(title="Wardrobe AI") as demo:
313
 
314
  analyze_btn.click(
315
  analyze_images,
316
- inputs=[image_input],
317
  outputs=[status_output, detected_table],
318
  )
319
 
 
11
 
12
  import gradio as gr
13
 
14
+ from src.vision import extract_garments, extract_single_from_path
15
  from src.catalog import (
16
  add_garments,
17
  load_catalog,
 
47
  """
48
 
49
 
50
+ def analyze_images(images, mode):
51
+ """Process uploaded images and extract garments based on capture mode."""
52
  if not images:
53
  return "Sube al menos una imagen.", []
54
 
55
+ if mode == "video":
56
+ return "Video stream estará disponible próximamente.", []
57
+
58
  all_added = []
59
  for img_data in images:
60
  image_path = img_data if isinstance(img_data, str) else img_data.name
61
  try:
62
+ if mode == "single":
63
+ garments_with_crops = extract_single_from_path(image_path)
64
+ else:
65
+ garments_with_crops = extract_garments(image_path)
66
+
67
  if garments_with_crops:
68
  added = add_garments(garments_with_crops)
69
  all_added.extend(added)
 
302
 
303
  with gr.Row():
304
  with gr.Column(scale=1):
305
+ capture_mode = gr.Radio(
306
+ choices=[
307
+ ("Prenda individual", "single"),
308
+ ("Múltiples prendas", "multi"),
309
+ ("Video stream (próximamente)", "video"),
310
+ ],
311
+ value="multi",
312
+ label="Modo de captura",
313
+ )
314
  image_input = gr.File(
315
  label="Fotos del armario",
316
  file_count="multiple",
 
329
 
330
  analyze_btn.click(
331
  analyze_images,
332
+ inputs=[image_input, capture_mode],
333
  outputs=[status_output, detected_table],
334
  )
335
 
src/vision.py CHANGED
@@ -220,3 +220,18 @@ def extract_garments(image_path: str) -> list[tuple[dict, bytes]]:
220
  logger.info("Falling back to full-image analysis")
221
  garments, full_bytes = _extract_from_full_image(image_path)
222
  return [(g, full_bytes) for g in garments]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  logger.info("Falling back to full-image analysis")
221
  garments, full_bytes = _extract_from_full_image(image_path)
222
  return [(g, full_bytes) for g in garments]
223
+
224
+
225
+ def extract_single_from_path(image_path: str) -> list[tuple[dict, bytes]]:
226
+ """Extract a single garment from a photo (no YOLO, direct VLM).
227
+
228
+ Use when the user photographs one garment at a time.
229
+ Returns a list with 0 or 1 (garment_dict, image_bytes) tuples.
230
+ """
231
+ logger.info("Single-garment mode: %s", image_path)
232
+ _, image_bytes = _prepare_image(image_path)
233
+ garment = _extract_single_garment(image_bytes)
234
+
235
+ if garment:
236
+ return [(garment, image_bytes)]
237
+ return []