pgomez611's picture
Arreglo compatibilidad NumPy y actualización app.py y requirements
1ed9ed3
# -----------------------------
# app.py - Detección de objetos con DETR y Gradio (imagen + datos)
# -----------------------------
# -----------------------------
# Librerías utilizadas y justificación
# -----------------------------
# transformers: permite usar modelos preentrenados como DETR para detección de objetos.
# DetrImageProcessor: preprocesa imágenes para que DETR las interprete correctamente.
# DetrForObjectDetection: modelo DETR preentrenado para detectar objetos en imágenes.
# torch: cálculos con tensores para inferencia con PyTorch.
# PIL.Image y ImageDraw: manipulación de imágenes y dibujo de cajas y etiquetas.
# gradio: crear interfaces web interactivas de manera sencilla.
from transformers import DetrImageProcessor, DetrForObjectDetection
import torch
from PIL import Image, ImageDraw, ImageFont
import gradio as gr
# -----------------------------
# Cargar modelo preentrenado
# -----------------------------
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
# -----------------------------
# Función de detección
# -----------------------------
def detect_objects(image):
"""
Detecta objetos en la imagen y retorna:
- Imagen con cajas y etiquetas
- Texto con los objetos detectados y coordenadas
"""
width, height = image.size
# Preprocesamiento
inputs = processor(images=image, return_tensors="pt", padding=True)
# Inferencia
with torch.no_grad():
outputs = model(**inputs)
# Postprocesamiento
target_sizes = torch.tensor([[height, width]])
results = processor.post_process_object_detection(
outputs, target_sizes=target_sizes, threshold=0.9
)[0]
labels = results["labels"]
scores = results["scores"]
boxes = results["boxes"]
# -----------------------------
# Preparar la imagen con detecciones
# -----------------------------
image_drawn = image.copy()
draw = ImageDraw.Draw(image_drawn)
try:
font = ImageFont.truetype("arial.ttf", 16)
except:
font = ImageFont.load_default()
for score, label, box in zip(scores, labels, boxes):
box = [float(b) for b in box]
# Ajustar coordenadas dentro de la imagen
box[0] = max(0, min(box[0], width))
box[1] = max(0, min(box[1], height))
box[2] = max(0, min(box[2], width))
box[3] = max(0, min(box[3], height))
# Dibujar caja roja
draw.rectangle(box, outline="red", width=3)
# Preparar etiqueta con margen y fondo blanco
label_text = f"{label} {score:.2f}"
text_width, text_height = draw.textsize(label_text, font=font)
text_padding = 4 # margen en pixeles
# Determinar posición de la etiqueta
text_x0 = box[0]
text_y0 = max(0, box[1] - text_height - 2*text_padding)
text_x1 = text_x0 + text_width + 2*text_padding
text_y1 = text_y0 + text_height + 2*text_padding
# Fondo blanco para la etiqueta
draw.rectangle([text_x0, text_y0, text_x1, text_y1], fill="white")
# Texto en negro encima del fondo blanco
draw.text((text_x0 + text_padding, text_y0 + text_padding), label_text, fill="black", font=font)
# -----------------------------
# Preparar texto de resultados
# -----------------------------
detected_objects_text = []
for score, label, box in zip(scores, labels, boxes):
detected_objects_text.append(
f"Objeto: {label}, Score: {score:.2f}, Box: {box.tolist()}"
)
detected_objects_text = "\n".join(detected_objects_text)
# Retornar: (imagen procesada, resultados en texto)
return image_drawn, detected_objects_text
# -----------------------------
# Crear interfaz con Gradio
# -----------------------------
def create_interface():
"""
Interfaz con dos cuadros:
- Imagen con detección visual
- Texto con coordenadas y scores
"""
interface = gr.Interface(
fn=detect_objects,
inputs=gr.Image(type="pil"),
outputs=[gr.Image(type="pil", label="Imagen con Detección"),
gr.Textbox(label="Resultados (datos)")],
live=True,
title="Detección de Objetos con DETR",
description=(
"Sube una imagen y obtén la detección de objetos. "
"El primer cuadro muestra la imagen con cajas rojas y etiquetas (ahora con fondo blanco). "
"El segundo cuadro muestra los datos: objetos detectados, scores y coordenadas."
)
)
interface.launch()
# -----------------------------
# Ejecutar la aplicación
# -----------------------------
if __name__ == "__main__":
create_interface()
# -----------------------------
# Justificaciones y decisiones
# -----------------------------
# 1. Separar imagen y datos mejora la visualización y comprensión.
# 2. Fondo blanco en etiquetas evita que el texto quede recortado o sobre fondo rojo/imagen.
# 3. text_padding asegura un margen entre el borde del recuadro y el texto.
# 4. threshold=0.9 evita falsos positivos y mantiene solo predicciones confiables.
# 5. PIL.ImageDraw se usa para dibujar cajas y etiquetas sin modificar la imag