File size: 4,206 Bytes
886e412
 
 
 
 
e48dd40
 
 
 
86d32c9
886e412
e48dd40
 
 
 
 
 
 
 
 
 
886e412
e48dd40
886e412
 
 
 
e48dd40
886e412
e48dd40
886e412
e48dd40
886e412
e48dd40
886e412
e48dd40
886e412
 
 
e48dd40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
886e412
 
e48dd40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
886e412
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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

# Crear interfaz Gradio
demo_model1 = gr.Interface(
    fn=image_classifier1,
    inputs="image",
    outputs=[gr.outputs.Image(type="numpy"), "label"],
    title="IsaTron V2 con Mapa de Calor"
)

# Ejecutar la interfaz
if __name__ == "__main__":
    demo_model1.launch(share=True)