Spaces:
Sleeping
Sleeping
| # ----------------------------- | |
| # 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 | |