fecia commited on
Commit
06f39c7
1 Parent(s): 1b07cca

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -0
app.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ from ultralytics import YOLO
5
+ import gradio as gr
6
+ from matplotlib.patches import Rectangle
7
+ from matplotlib.legend import Legend
8
+
9
+ # Cargar el modelo YOLO (asegúrate de que 'model.pt' esté en el mismo directorio)
10
+ model = YOLO("model.pt")
11
+
12
+ def process_image(image):
13
+ # Convertir la imagen de PIL a NumPy array y de RGB a BGR
14
+ img = np.array(image)
15
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
16
+
17
+ # Realizar inferencia en la imagen
18
+ results = model.predict(source=img, save=False)
19
+
20
+ # Inicializar la lista para almacenar la información de las máscaras
21
+ mask_info_list = []
22
+
23
+ # Iterar sobre los resultados
24
+ for result in results:
25
+ # Verificar si se detectaron máscaras
26
+ if result.masks is not None and len(result.masks.data) > 0:
27
+ # Obtener las máscaras, las probabilidades y las clases
28
+ masks = result.masks.data.cpu().numpy() # Forma: (num_masks, altura, ancho)
29
+ confidences = result.boxes.conf.cpu().numpy() # Probabilidades
30
+ classes = result.boxes.cls.cpu().numpy().astype(int)
31
+ names = model.names # Nombres de las clases
32
+
33
+ # Normalizar las probabilidades al rango [0, 1]
34
+ confidences_norm = (confidences - confidences.min()) / (confidences.max() - confidences.min() + 1e-6)
35
+
36
+ # Redimensionar las máscaras para que coincidan con el tamaño de la imagen
37
+ resized_masks = []
38
+ for mask in masks:
39
+ mask_resized = cv2.resize(mask, (img.shape[1], img.shape[0]), interpolation=cv2.INTER_LINEAR)
40
+ resized_masks.append(mask_resized)
41
+ resized_masks = np.array(resized_masks) # Forma: (num_masks, altura, ancho)
42
+
43
+ # Aplicar suavizado a las máscaras
44
+ smoothed_masks = []
45
+ for mask in resized_masks:
46
+ # Convertir la máscara a escala de grises (valores entre 0 y 255)
47
+ mask_uint8 = (mask * 255).astype(np.uint8)
48
+ # Aplicar desenfoque gaussiano
49
+ blurred_mask = cv2.GaussianBlur(mask_uint8, (7, 7), 0)
50
+ # Normalizar y convertir de nuevo a rango [0, 1]
51
+ mask_smoothed = blurred_mask.astype(np.float32) / 255.0
52
+ smoothed_masks.append(mask_smoothed)
53
+ smoothed_masks = np.array(smoothed_masks)
54
+
55
+ # Ordenar las máscaras por probabilidad descendente
56
+ sorted_indices = np.argsort(-confidences)
57
+ sorted_masks = smoothed_masks[sorted_indices]
58
+ sorted_confidences = confidences[sorted_indices]
59
+ sorted_confidences_norm = confidences_norm[sorted_indices]
60
+ sorted_classes = classes[sorted_indices]
61
+
62
+ # Definir el mapa de colores
63
+ colormap = plt.cm.get_cmap('viridis')
64
+
65
+ # Crear una imagen en blanco para las máscaras
66
+ mask_image = np.zeros_like(img, dtype=np.uint8)
67
+
68
+ # Crear una matriz para rastrear qué máscara se asigna a cada píxel
69
+ mask_indices = np.full((img.shape[0], img.shape[1]), -1, dtype=int)
70
+
71
+ # Procesar cada máscara y asignar máscaras de mayor probabilidad a los píxeles
72
+ for idx_in_order, (idx, mask, conf_norm, conf, cls) in enumerate(zip(sorted_indices, sorted_masks, sorted_confidences_norm, sorted_confidences, sorted_classes)):
73
+ mask_bool = mask > 0.5 # Umbral para convertir a binario
74
+ # Actualizar píxeles donde aún no se ha asignado una máscara
75
+ update_mask = np.logical_and(mask_bool, mask_indices == -1)
76
+ if not np.any(update_mask):
77
+ continue # Si no hay píxeles nuevos, continuar
78
+ mask_indices[update_mask] = idx
79
+
80
+ # Obtener el color del mapa de colores basado en la probabilidad normalizada
81
+ color_rgb = colormap(conf_norm)[:3]
82
+ color_rgb = [int(c * 255) for c in color_rgb] # Convertir a escala [0, 255]
83
+ color_bgr = color_rgb[::-1] # Convertir de RGB a BGR
84
+
85
+ # Almacenar la información de la máscara
86
+ mask_info = {
87
+ 'mask_index': idx,
88
+ 'class': names[cls],
89
+ 'confidence': conf,
90
+ 'color_rgb': color_rgb,
91
+ 'color_bgr': color_bgr
92
+ }
93
+ mask_info_list.append(mask_info)
94
+
95
+ # Asignar colores a los píxeles correspondientes en la imagen de máscaras
96
+ for i in range(3):
97
+ mask_image[:, :, i][update_mask] = color_bgr[i] # Usar color BGR para OpenCV
98
+
99
+ # Superponer la imagen de máscaras sobre la imagen original
100
+ alpha = 0.2 # Transparencia ajustada
101
+ img_with_masks = cv2.addWeighted(img.astype(np.float32), 1, mask_image.astype(np.float32), alpha, 0).astype(np.uint8)
102
+
103
+ else:
104
+ # Si no hay máscaras, usar la imagen original
105
+ img_with_masks = img.copy()
106
+ print("No se detectaron máscaras en esta imagen.")
107
+
108
+ # Convertir la imagen de BGR a RGB para mostrarla con Gradio
109
+ img_with_masks_rgb = cv2.cvtColor(img_with_masks, cv2.COLOR_BGR2RGB)
110
+
111
+ return img_with_masks_rgb
112
+
113
+ # Crear la interfaz de Gradio
114
+ iface = gr.Interface(
115
+ fn=process_image,
116
+ inputs=gr.Image(type="pil"),
117
+ outputs=gr.Image(type="numpy"),
118
+ title="Detección de Estenosis",
119
+ description="Sube una imagen para detectar estenosis."
120
+ )
121
+
122
+ if __name__ == "__main__":
123
+ iface.launch()