eduardo4547 commited on
Commit
444d63f
·
verified ·
1 Parent(s): a948cb1

Upload 2 files

Browse files
Files changed (1) hide show
  1. app.py +42 -16
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import base64
 
2
  import io
3
  import json
4
  import traceback
@@ -22,6 +23,7 @@ from transformers import (
22
  CLIPProcessor,
23
  SegformerImageProcessor,
24
  SegformerForSemanticSegmentation,
 
25
  )
26
  from sam2.build_sam import build_sam2
27
  from sam2.sam2_image_predictor import SAM2ImagePredictor
@@ -55,6 +57,7 @@ segformer_city_model = None
55
  segformer_city_processor = None
56
  segformer_ade_model = None
57
  segformer_ade_processor = None
 
58
 
59
  # --- CATÁLOGO CONTEXTUAL ---
60
  CATALOGO_POR_ENTORNO = {
@@ -385,7 +388,7 @@ def autodetectar_entorno(imagen: Image.Image):
385
  if imagen is None:
386
  entorno_predicho = claves_entorno[0]
387
  nuevas_opciones = list(CATALOGO_POR_ENTORNO[entorno_predicho].keys())
388
- motor_seleccionado = "Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)" if entorno_predicho in exteriores else "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1"
389
  return (
390
  gr.update(value=entorno_predicho),
391
  gr.update(choices=nuevas_opciones, value=nuevas_opciones),
@@ -405,7 +408,7 @@ def autodetectar_entorno(imagen: Image.Image):
405
 
406
  entorno_detectado = claves_entorno[indice_ganador]
407
  nuevas_opciones = list(CATALOGO_POR_ENTORNO[entorno_detectado].keys())
408
- motor_seleccionado = "Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)" if entorno_detectado in exteriores else "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1"
409
 
410
  return (
411
  gr.update(value=entorno_detectado),
@@ -416,14 +419,43 @@ def autodetectar_entorno(imagen: Image.Image):
416
 
417
  def segmentar_y_analizar(imagen: Image.Image, entorno: str, seleccion: list, umbral_sensibilidad: float, motor: str, usar_limpieza: bool):
418
  print(f"\n--- Iniciando análisis con motor: {motor} ---")
 
419
 
420
- if imagen is None or len(seleccion) == 0:
421
  return None, "Sube una imagen y selecciona al menos un elemento.", None
422
 
423
  imagen_rgb = imagen.convert("RGB")
424
  imagen_np = np.array(imagen_rgb)
425
  total_pixels = imagen.width * imagen.height
426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  masks_finales, etiquetas_finales, debug_image = _run_engines_raw(
428
  imagen_rgb, imagen_np, entorno, seleccion, umbral_sensibilidad, motor, usar_limpieza
429
  )
@@ -522,23 +554,16 @@ def segment_for_backend(image_np: np.ndarray):
522
 
523
  def seleccionar_motor_por_entorno(entorno):
524
  exteriores = ["🏙️ Fachada / Exterior", "🌳 Terraza / Patio / Jardín"]
525
- interiores = [
526
- "🛋️ Interiores (Sala / Cuartos)",
527
- "🛁 Baño / Cocina",
528
- "🏢 Oficinas / Corporativo",
529
- "🏪 Locales Comerciales / Restaurantes",
530
- "🏭 Garaje / Bodega / Industrial"
531
- ]
532
  if entorno in exteriores:
533
- return gr.update(value="Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)")
534
- if entorno in interiores:
535
- return gr.update(value="SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1")
536
  return gr.update(value="SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1")
537
 
538
 
539
  def actualizar_opciones(entorno, motor):
540
  opciones = list(CATALOGO_POR_ENTORNO[entorno].keys())
541
- if motor in ["Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)", "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1"]:
 
 
542
  label = "2. Elementos (Detalles a buscar con DINO 🎯)"
543
  else:
544
  label = "2. Elementos"
@@ -554,11 +579,12 @@ def crear_app():
554
  imagen_entrada = gr.Image(type="pil", label="Foto del Espacio")
555
  motor = gr.Radio(
556
  choices=[
557
- "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1",
558
  "Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)",
 
559
  "DINO + SAM 2.1 (Objetos Contables)"
560
  ],
561
- value="Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)",
562
  label="🧠 Motor de Inteligencia Artificial"
563
  )
564
  tipo_entorno = gr.Dropdown(choices=list(CATALOGO_POR_ENTORNO.keys()), value=list(CATALOGO_POR_ENTORNO.keys())[0], label="1. Entorno (Autodetectado 🪄)")
 
1
  import base64
2
+ import hashlib
3
  import io
4
  import json
5
  import traceback
 
23
  CLIPProcessor,
24
  SegformerImageProcessor,
25
  SegformerForSemanticSegmentation,
26
+ pipeline as hf_pipeline,
27
  )
28
  from sam2.build_sam import build_sam2
29
  from sam2.sam2_image_predictor import SAM2ImagePredictor
 
57
  segformer_city_processor = None
58
  segformer_ade_model = None
59
  segformer_ade_processor = None
60
+ sam_vit_pipeline = None
61
 
62
  # --- CATÁLOGO CONTEXTUAL ---
63
  CATALOGO_POR_ENTORNO = {
 
388
  if imagen is None:
389
  entorno_predicho = claves_entorno[0]
390
  nuevas_opciones = list(CATALOGO_POR_ENTORNO[entorno_predicho].keys())
391
+ motor_seleccionado = "SAM Auto (Exteriores - Sin Prompts)" if entorno_predicho in exteriores else "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1"
392
  return (
393
  gr.update(value=entorno_predicho),
394
  gr.update(choices=nuevas_opciones, value=nuevas_opciones),
 
408
 
409
  entorno_detectado = claves_entorno[indice_ganador]
410
  nuevas_opciones = list(CATALOGO_POR_ENTORNO[entorno_detectado].keys())
411
+ motor_seleccionado = "SAM Auto (Exteriores - Sin Prompts)" if entorno_detectado in exteriores else "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1"
412
 
413
  return (
414
  gr.update(value=entorno_detectado),
 
419
 
420
  def segmentar_y_analizar(imagen: Image.Image, entorno: str, seleccion: list, umbral_sensibilidad: float, motor: str, usar_limpieza: bool):
421
  print(f"\n--- Iniciando análisis con motor: {motor} ---")
422
+ global sam_vit_pipeline
423
 
424
+ if imagen is None or (len(seleccion) == 0 and motor != "SAM Auto (Exteriores - Sin Prompts)"):
425
  return None, "Sube una imagen y selecciona al menos un elemento.", None
426
 
427
  imagen_rgb = imagen.convert("RGB")
428
  imagen_np = np.array(imagen_rgb)
429
  total_pixels = imagen.width * imagen.height
430
 
431
+ # ==========================================================
432
+ # MOTOR 4: SAM ViT-Huge AUTOMÁTICO (Sin prompts — Exteriores)
433
+ # ==========================================================
434
+ if motor == "SAM Auto (Exteriores - Sin Prompts)":
435
+ if sam_vit_pipeline is None:
436
+ print("Cargando SAM ViT-Huge pipeline (mask-generation, CPU)...")
437
+ sam_vit_pipeline = hf_pipeline(
438
+ "mask-generation",
439
+ model="facebook/sam-vit-huge",
440
+ device=-1,
441
+ )
442
+
443
+ resultado_sam = sam_vit_pipeline(imagen_rgb)
444
+ if isinstance(resultado_sam, list):
445
+ resultado_sam = resultado_sam[0]
446
+
447
+ all_masks = resultado_sam.get("masks", [])
448
+
449
+ img_arr = np.array(imagen_rgb).copy()
450
+ overlay = img_arr.copy()
451
+ for i, mask in enumerate(all_masks):
452
+ hex_digest = hashlib.md5(str(i).encode()).hexdigest()[:6]
453
+ color = (int(hex_digest[0:2], 16), int(hex_digest[2:4], 16), int(hex_digest[4:6], 16))
454
+ overlay[np.array(mask) > 0] = color
455
+
456
+ blended = cv2.addWeighted(img_arr, 0.5, overlay, 0.5, 0)
457
+ return Image.fromarray(blended), f"📊 REPORTE (SAM Auto):<br>• {len(all_masks)} zonas detectadas automáticamente", None
458
+
459
  masks_finales, etiquetas_finales, debug_image = _run_engines_raw(
460
  imagen_rgb, imagen_np, entorno, seleccion, umbral_sensibilidad, motor, usar_limpieza
461
  )
 
554
 
555
  def seleccionar_motor_por_entorno(entorno):
556
  exteriores = ["🏙️ Fachada / Exterior", "🌳 Terraza / Patio / Jardín"]
 
 
 
 
 
 
 
557
  if entorno in exteriores:
558
+ return gr.update(value="SAM Auto (Exteriores - Sin Prompts)")
 
 
559
  return gr.update(value="SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1")
560
 
561
 
562
  def actualizar_opciones(entorno, motor):
563
  opciones = list(CATALOGO_POR_ENTORNO[entorno].keys())
564
+ if motor == "SAM Auto (Exteriores - Sin Prompts)":
565
+ label = "2. Elementos (No aplica — detección totalmente automática ✨)"
566
+ elif motor in ["Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)", "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1"]:
567
  label = "2. Elementos (Detalles a buscar con DINO 🎯)"
568
  else:
569
  label = "2. Elementos"
 
579
  imagen_entrada = gr.Image(type="pil", label="Foto del Espacio")
580
  motor = gr.Radio(
581
  choices=[
582
+ "SAM Auto (Exteriores - Sin Prompts)",
583
  "Híbrido Arquitectura (Cityscapes Grande + DINO Pequeño)",
584
+ "SegFormer (SegFormer ADE20K+ DINO) + SAM 2.1",
585
  "DINO + SAM 2.1 (Objetos Contables)"
586
  ],
587
+ value="SAM Auto (Exteriores - Sin Prompts)",
588
  label="🧠 Motor de Inteligencia Artificial"
589
  )
590
  tipo_entorno = gr.Dropdown(choices=list(CATALOGO_POR_ENTORNO.keys()), value=list(CATALOGO_POR_ENTORNO.keys())[0], label="1. Entorno (Autodetectado 🪄)")