Spaces:
Sleeping
Sleeping
| 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') # Cambiado a 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.3): | |
| # Redimensionar el mapa de calor al tamaño de la imagen | |
| heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0])) | |
| # Aplicar un umbral al mapa de calor para resaltar solo las zonas importantes | |
| threshold = 0.6 # Solo mostrar las áreas con alta activación | |
| heatmap[heatmap < threshold] = 0 | |
| # Aplicar el colormap JET para mantener los colores, pero suavizar la superposición | |
| heatmap = np.uint8(255 * heatmap) | |
| heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) | |
| # Convertir la imagen original a BGR para poder mezclar con el mapa de calor | |
| img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) | |
| # Superponer el mapa de calor en la imagen original | |
| overlayed_img = cv2.addWeighted(heatmap, alpha, img, 1 - alpha, 0) | |
| # 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) | |
| # Asumimos que el modelo devuelve una probabilidad entre 0 y 1 para PNEUMONIA | |
| prediction = preds[0][0] # Suponiendo que el modelo devuelve la probabilidad de neumonía | |
| # Si la predicción es mayor a 0.5, consideramos que es neumonía | |
| if prediction > 0.5: | |
| pred_label = "PNEUMONIA" | |
| prediction_percentage = {'PNEUMONIA': float(prediction * 100), 'NORMAL': float((1 - prediction) * 100)} | |
| else: | |
| pred_label = "NORMAL" | |
| prediction_percentage = {'NORMAL': float((1 - prediction) * 100), 'PNEUMONIA': float(prediction * 100)} | |
| # Generar mapa de calor | |
| heatmap = make_gradcam_heatmap(img_array, model1, last_conv_layer_name, pred_index=int(prediction > 0.5)) | |
| # 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 | |
| return overlayed_img, prediction_percentage | |
| # Crear interfaz Gradio con estilo predeterminado 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="Jeysshon 2024" | |
| ) | |
| # Ejecutar la interfaz | |
| if __name__ == "__main__": | |
| demo_model1.launch(share=True) | |