Update app.py
Browse files
app.py
CHANGED
@@ -3,12 +3,14 @@ import numpy as np
|
|
3 |
import matplotlib.pyplot as plt
|
4 |
from ultralytics import YOLO
|
5 |
import gradio as gr
|
|
|
|
|
6 |
|
7 |
# Cargar el modelo YOLO
|
8 |
model = YOLO("model.pt")
|
9 |
|
10 |
def process_image(image):
|
11 |
-
# Convertir la imagen de PIL a NumPy array y de RGB a BGR
|
12 |
img_rgb = np.array(image)
|
13 |
img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
|
14 |
|
@@ -21,6 +23,9 @@ def process_image(image):
|
|
21 |
# Crear una imagen en blanco para las máscaras (en formato BGR)
|
22 |
mask_image = np.zeros_like(img_bgr, dtype=np.uint8)
|
23 |
|
|
|
|
|
|
|
24 |
# Procesar resultados
|
25 |
for result in results:
|
26 |
# Verificar si se detectaron máscaras
|
@@ -61,20 +66,23 @@ def process_image(image):
|
|
61 |
sorted_classes = classes[sorted_indices]
|
62 |
|
63 |
# Definir el mapa de colores (puedes cambiar a 'plasma', 'inferno', etc.)
|
64 |
-
colormap = plt.cm.get_cmap('viridis')
|
65 |
-
|
66 |
-
# Crear una matriz para rastrear qué máscara se asigna a cada píxel
|
67 |
-
mask_indices = np.full((img_bgr.shape[0], img_bgr.shape[1]), -1, dtype=int)
|
68 |
|
69 |
-
# Procesar cada máscara y asignar máscaras de mayor
|
70 |
for idx_in_order, (idx, mask, conf_norm, conf, cls) in enumerate(
|
71 |
zip(sorted_indices, sorted_masks, sorted_confidences_norm, sorted_confidences, sorted_classes)):
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
# Obtener el color del mapa de colores basado en la probabilidad normalizada
|
80 |
color_rgb = colormap(conf_norm)[:3] # Color en formato RGB [0, 1]
|
@@ -93,7 +101,7 @@ def process_image(image):
|
|
93 |
|
94 |
# Asignar colores a los píxeles correspondientes en la imagen de máscaras
|
95 |
for i in range(3):
|
96 |
-
mask_image[:, :, i][
|
97 |
|
98 |
# Superponer la imagen de máscaras sobre la imagen original
|
99 |
alpha = 0.2 # Transparencia ajustada
|
@@ -104,32 +112,45 @@ def process_image(image):
|
|
104 |
img_with_masks = img_bgr.copy()
|
105 |
print("No se detectaron máscaras en esta imagen.")
|
106 |
|
107 |
-
# Convertir
|
108 |
-
img_original_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
|
109 |
img_with_masks_rgb = cv2.cvtColor(img_with_masks, cv2.COLOR_BGR2RGB)
|
110 |
|
111 |
-
#
|
|
|
|
|
|
|
|
|
|
|
112 |
if mask_info_list:
|
113 |
-
|
|
|
114 |
for mask_info in mask_info_list:
|
115 |
-
|
116 |
-
|
117 |
-
label = f"
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
-
return
|
123 |
|
124 |
-
# Crear la interfaz de Gradio
|
125 |
iface = gr.Interface(
|
126 |
fn=process_image,
|
127 |
inputs=gr.Image(type="pil"),
|
128 |
-
outputs=
|
129 |
-
gr.Image(type="numpy", label="Imagen Original"),
|
130 |
-
gr.Image(type="numpy", label="Imagen con Máscaras"),
|
131 |
-
gr.HTML(label="Leyenda")
|
132 |
-
],
|
133 |
title="Detección de Estenosis",
|
134 |
description="Sube una imagen para detectar estenosis."
|
135 |
)
|
|
|
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
|
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 (PIL usa RGB, OpenCV usa BGR)
|
14 |
img_rgb = np.array(image)
|
15 |
img_bgr = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2BGR)
|
16 |
|
|
|
23 |
# Crear una imagen en blanco para las máscaras (en formato BGR)
|
24 |
mask_image = np.zeros_like(img_bgr, dtype=np.uint8)
|
25 |
|
26 |
+
# Inicializar la máscara acumulativa
|
27 |
+
cumulative_mask = np.zeros((img_bgr.shape[0], img_bgr.shape[1]), dtype=bool)
|
28 |
+
|
29 |
# Procesar resultados
|
30 |
for result in results:
|
31 |
# Verificar si se detectaron máscaras
|
|
|
66 |
sorted_classes = classes[sorted_indices]
|
67 |
|
68 |
# Definir el mapa de colores (puedes cambiar a 'plasma', 'inferno', etc.)
|
69 |
+
colormap = plt.cm.get_cmap('viridis') # Cambia 'viridis' por 'plasma' o 'inferno' si lo deseas
|
|
|
|
|
|
|
70 |
|
71 |
+
# Procesar cada máscara y asignar máscaras de mayor confianza primero
|
72 |
for idx_in_order, (idx, mask, conf_norm, conf, cls) in enumerate(
|
73 |
zip(sorted_indices, sorted_masks, sorted_confidences_norm, sorted_confidences, sorted_classes)):
|
74 |
+
# Umbralizar la máscara para obtener valores binarios
|
75 |
+
mask_bool = mask > 0.5
|
76 |
+
|
77 |
+
# Restar la máscara acumulativa de la máscara actual para obtener la parte única
|
78 |
+
unique_mask = np.logical_and(mask_bool, np.logical_not(cumulative_mask))
|
79 |
+
|
80 |
+
# Actualizar la máscara acumulativa
|
81 |
+
cumulative_mask = np.logical_or(cumulative_mask, unique_mask)
|
82 |
+
|
83 |
+
# Si no hay píxeles únicos, continuar
|
84 |
+
if not np.any(unique_mask):
|
85 |
+
continue
|
86 |
|
87 |
# Obtener el color del mapa de colores basado en la probabilidad normalizada
|
88 |
color_rgb = colormap(conf_norm)[:3] # Color en formato RGB [0, 1]
|
|
|
101 |
|
102 |
# Asignar colores a los píxeles correspondientes en la imagen de máscaras
|
103 |
for i in range(3):
|
104 |
+
mask_image[:, :, i][unique_mask] = color_bgr_255[i]
|
105 |
|
106 |
# Superponer la imagen de máscaras sobre la imagen original
|
107 |
alpha = 0.2 # Transparencia ajustada
|
|
|
112 |
img_with_masks = img_bgr.copy()
|
113 |
print("No se detectaron máscaras en esta imagen.")
|
114 |
|
115 |
+
# Convertir la imagen de BGR a RGB para matplotlib
|
|
|
116 |
img_with_masks_rgb = cv2.cvtColor(img_with_masks, cv2.COLOR_BGR2RGB)
|
117 |
|
118 |
+
# Crear una figura para mostrar la imagen y la leyenda
|
119 |
+
fig, ax = plt.subplots(figsize=(8, 8))
|
120 |
+
ax.imshow(img_with_masks_rgb)
|
121 |
+
ax.axis('off')
|
122 |
+
|
123 |
+
# Crear la leyenda si hay máscaras detectadas
|
124 |
if mask_info_list:
|
125 |
+
handles = []
|
126 |
+
labels = []
|
127 |
for mask_info in mask_info_list:
|
128 |
+
color_rgb_normalized = np.array(mask_info['color_rgb']) / 255 # Normalizar al rango [0, 1]
|
129 |
+
patch = Rectangle((0, 0), 1, 1, facecolor=color_rgb_normalized)
|
130 |
+
label = f"{mask_info['class']} - Confianza: {mask_info['confidence']:.2f}"
|
131 |
+
handles.append(patch)
|
132 |
+
labels.append(label)
|
133 |
+
|
134 |
+
# Añadir la leyenda al gráfico
|
135 |
+
legend = Legend(ax, handles, labels, loc='upper right')
|
136 |
+
ax.add_artist(legend)
|
137 |
+
|
138 |
+
plt.tight_layout()
|
139 |
+
|
140 |
+
# Convertir la figura a una imagen NumPy
|
141 |
+
fig.canvas.draw()
|
142 |
+
img_figure = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
|
143 |
+
img_figure = img_figure.reshape(fig.canvas.get_width_height()[::-1] + (3,))
|
144 |
+
|
145 |
+
plt.close(fig) # Cerrar la figura para liberar memoria
|
146 |
|
147 |
+
return img_figure
|
148 |
|
149 |
+
# Crear la interfaz de Gradio
|
150 |
iface = gr.Interface(
|
151 |
fn=process_image,
|
152 |
inputs=gr.Image(type="pil"),
|
153 |
+
outputs=gr.Image(type="numpy"),
|
|
|
|
|
|
|
|
|
154 |
title="Detección de Estenosis",
|
155 |
description="Sube una imagen para detectar estenosis."
|
156 |
)
|