Isatron_V2 / app.py
jeysshon's picture
Update app.py
ca79521 verified
raw
history blame
5.23 kB
import gradio as gr
import numpy as np
import cv2
from keras.models import load_model
import tensorflow as tf
from tensorflow import keras
# Cargar el modelo entrenado
model1 = load_model('./isatron_v3.h5')
# Función para encontrar la última capa convolucional
def find_last_conv_layer(model):
for layer in reversed(model.layers):
if 'conv' in layer.name:
return layer.name
raise ValueError("No se encontró una capa convolucional en el modelo.")
# Obtener el nombre de la última capa convolucional
last_conv_layer_name = find_last_conv_layer(model1)
print("Última capa convolucional:", last_conv_layer_name)
# Definir tamaño de imagen y etiquetas
img_size1 = 150
labels = ['PNEUMONIA', 'NORMAL']
def load_and_preprocess_image1(img):
# Convertir imagen de Gradio (PIL Image) a array numpy
img = np.array(img)
# Convertir de RGB a escala de grises
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# Redimensionar imagen al tamaño requerido
img = cv2.resize(img, (img_size1, img_size1))
# Reformatear imagen para entrada del modelo
img = img.reshape(-1, img_size1, img_size1, 1)
# Normalizar imagen
img = img / 255.0
return img
def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):
# Crear un modelo que mapee la imagen de entrada a las activaciones
# de la última capa convolucional y las predicciones
grad_model = keras.models.Model(
[model.inputs], [model.get_layer(last_conv_layer_name).output, model.output]
)
# Calcular el gradiente de la clase predicha con respecto a las activaciones
with tf.GradientTape() as tape:
last_conv_layer_output, preds = grad_model(img_array)
if pred_index is None:
pred_index = np.argmax(preds[0])
class_channel = preds[:, pred_index]
# Calcular los gradientes
grads = tape.gradient(class_channel, last_conv_layer_output)
# Pooling global de los gradientes
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
# Multiplicar cada canal por su importancia
last_conv_layer_output = last_conv_layer_output[0]
heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
heatmap = tf.squeeze(heatmap)
# Normalizar el mapa de calor entre 0 y 1
heatmap = tf.maximum(heatmap, 0) / tf.reduce_max(heatmap)
heatmap = heatmap.numpy()
return heatmap
def overlay_heatmap(heatmap, img, alpha=0.4):
# Redimensionar mapa de calor al tamaño de la imagen
heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
# Convertir mapa de calor a RGB
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
# Convertir imagen a BGR
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
# Aplicar mapa de calor a la imagen original
overlayed_img = heatmap * alpha + img
overlayed_img = np.uint8(overlayed_img)
# Convertir de nuevo a RGB
overlayed_img = cv2.cvtColor(overlayed_img, cv2.COLOR_BGR2RGB)
return overlayed_img
def image_classifier1(img):
# Mantener la imagen original para superponer
orig_img = np.array(img)
# Preprocesar la imagen
img_array = load_and_preprocess_image1(img)
# Realizar predicción usando model1
preds = model1.predict(img_array)
prediction = preds[0][0] # Suponiendo que el modelo devuelve una probabilidad
# Determinar el índice de la clase predicha
pred_index = int(prediction > 0.5)
# Generar mapa de calor
heatmap = make_gradcam_heatmap(img_array, model1, last_conv_layer_name, pred_index=pred_index)
# Superponer mapa de calor en la imagen original
overlayed_img = overlay_heatmap(heatmap, orig_img)
# Retornar la imagen superpuesta y los porcentajes de predicción
prediction_percentage = {'PNEUMONIA': float(prediction), 'NORMAL': float(1 - prediction)}
return overlayed_img, prediction_percentage
# Definir CSS personalizado
custom_css = """
body {
background-color: #e6f2ff;
}
h1 {
color: #003366;
text-align: center;
}
.gradio-container {
font-family: 'Arial', sans-serif;
max-width: 800px;
margin: auto;
padding: 20px;
background-color: #ffffff;
border-radius: 10px;
}
.footer {
text-align: center;
margin-top: 20px;
color: #003366;
font-size: 14px;
}
label {
font-weight: bold;
color: #003366;
}
button {
background-color: #0059b3;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
}
button:hover {
background-color: #004080;
}
"""
# Crear interfaz Gradio con CSS personalizado y pie de página
demo_model1 = gr.Interface(
fn=image_classifier1,
inputs=gr.Image(type="pil", label="Sube una imagen de radiografía"),
outputs=[
gr.Image(type="numpy", label="Imagen con Mapa de Calor"),
gr.Label(num_top_classes=2, label="Resultados de Predicción")
],
title="IsaTron V2 con Mapa de Calor",
description="Esta aplicación detecta neumonía a partir de imágenes de radiografías de tórax.",
article="<div class='footer'>Jeysshon 2024</div>",
css=custom_css
)
# Ejecutar la interfaz
if __name__ == "__main__":
demo_model1.launch(share=True)