Commit
路
f240112
1
Parent(s):
30a2053
Edit app.py
Browse files
app.py
CHANGED
|
@@ -23,7 +23,30 @@ ROWS, COLS = 224, 224
|
|
| 23 |
model_path = hf_hub_download(repo_id="Martinagg/simpleNet", filename="simpleNet.h5")
|
| 24 |
model = tf.keras.models.load_model(model_path)
|
| 25 |
|
| 26 |
-
# ===
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
def preprocess_and_predict(img_input):
|
| 28 |
# Convertir PIL a OpenCV (BGR)
|
| 29 |
img = np.array(img_input)[:, :, ::-1]
|
|
@@ -35,22 +58,22 @@ def preprocess_and_predict(img_input):
|
|
| 35 |
rgb_clean = cv2.cvtColor(zoomed, cv2.COLOR_BGR2RGB)
|
| 36 |
clean = quitar_pelos(rgb_clean)
|
| 37 |
|
| 38 |
-
# 3. Segmentar
|
| 39 |
mask, lesion_rgb = segmentar_lesion(clean, size=(ROWS, COLS))
|
| 40 |
|
| 41 |
-
# 4. Preparar
|
| 42 |
lesion_resized = cv2.resize(lesion_rgb, (ROWS, COLS))
|
| 43 |
img_array = image.img_to_array(lesion_resized) / 255.0
|
| 44 |
-
img_array = np.expand_dims(img_array, axis=0)
|
| 45 |
|
| 46 |
-
# 5. Predicci贸n
|
| 47 |
probs = model.predict(img_array)[0]
|
| 48 |
classes = ["Benign", "Malignant"]
|
| 49 |
pred_idx = np.argmax(probs)
|
| 50 |
pred_label = classes[pred_idx]
|
| 51 |
result_text = f"Predicci贸n: {pred_label} ({probs[pred_idx]*100:.2f}%)"
|
| 52 |
|
| 53 |
-
# 6.
|
| 54 |
area = calcular_area(mask)
|
| 55 |
perim = calcular_perimetro(mask)
|
| 56 |
circ = calcular_circularidad(mask)
|
|
@@ -64,7 +87,18 @@ def preprocess_and_predict(img_input):
|
|
| 64 |
f"Simetr铆a Horizontal: {sim_h}"
|
| 65 |
)
|
| 66 |
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
# === Interfaz Gradio ===
|
| 70 |
demo = gr.Interface(
|
|
@@ -74,10 +108,11 @@ demo = gr.Interface(
|
|
| 74 |
gr.Image(type="numpy", label="M谩scara Binaria"),
|
| 75 |
gr.Image(type="numpy", label="Lesi贸n Segmentada"),
|
| 76 |
gr.Textbox(label="Resultado del Modelo"),
|
| 77 |
-
gr.Textbox(label="M茅tricas de la Lesi贸n")
|
|
|
|
| 78 |
],
|
| 79 |
title="DermaScan - Clasificaci贸n de Lesiones",
|
| 80 |
-
description="Sube una imagen de piel. El sistema segmenta la lesi贸n, muestra la m谩scara, la predicci贸n
|
| 81 |
)
|
| 82 |
|
| 83 |
if __name__ == "__main__":
|
|
|
|
| 23 |
model_path = hf_hub_download(repo_id="Martinagg/simpleNet", filename="simpleNet.h5")
|
| 24 |
model = tf.keras.models.load_model(model_path)
|
| 25 |
|
| 26 |
+
# === Cargar modelo ZoomNet para Grad-CAM ===
|
| 27 |
+
zoom_path = hf_hub_download(repo_id="Martinagg/ZoomNet", filename="ZoomNet.keras")
|
| 28 |
+
model_zoom = tf.keras.models.load_model(zoom_path)
|
| 29 |
+
|
| 30 |
+
# === Funci贸n Grad-CAM ===
|
| 31 |
+
def make_gradcam_heatmap(img_array, model, last_conv_layer_name="conv4", pred_index=None):
|
| 32 |
+
grad_model = tf.keras.models.Model(
|
| 33 |
+
[model.inputs],
|
| 34 |
+
[model.get_layer(last_conv_layer_name).output, model.output]
|
| 35 |
+
)
|
| 36 |
+
with tf.GradientTape() as tape:
|
| 37 |
+
conv_outputs, predictions = grad_model(img_array)
|
| 38 |
+
if pred_index is None:
|
| 39 |
+
pred_index = tf.argmax(predictions[0])
|
| 40 |
+
class_channel = predictions[:, pred_index]
|
| 41 |
+
grads = tape.gradient(class_channel, conv_outputs)
|
| 42 |
+
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
|
| 43 |
+
conv_outputs = conv_outputs[0]
|
| 44 |
+
heatmap = conv_outputs @ pooled_grads[..., tf.newaxis]
|
| 45 |
+
heatmap = tf.squeeze(heatmap)
|
| 46 |
+
heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)
|
| 47 |
+
return heatmap.numpy()
|
| 48 |
+
|
| 49 |
+
# === Funci贸n de predicci贸n principal ===
|
| 50 |
def preprocess_and_predict(img_input):
|
| 51 |
# Convertir PIL a OpenCV (BGR)
|
| 52 |
img = np.array(img_input)[:, :, ::-1]
|
|
|
|
| 58 |
rgb_clean = cv2.cvtColor(zoomed, cv2.COLOR_BGR2RGB)
|
| 59 |
clean = quitar_pelos(rgb_clean)
|
| 60 |
|
| 61 |
+
# 3. Segmentar
|
| 62 |
mask, lesion_rgb = segmentar_lesion(clean, size=(ROWS, COLS))
|
| 63 |
|
| 64 |
+
# 4. Preparar para SimpleNet
|
| 65 |
lesion_resized = cv2.resize(lesion_rgb, (ROWS, COLS))
|
| 66 |
img_array = image.img_to_array(lesion_resized) / 255.0
|
| 67 |
+
img_array = np.expand_dims(img_array, axis=0)
|
| 68 |
|
| 69 |
+
# 5. Predicci贸n con SimpleNet
|
| 70 |
probs = model.predict(img_array)[0]
|
| 71 |
classes = ["Benign", "Malignant"]
|
| 72 |
pred_idx = np.argmax(probs)
|
| 73 |
pred_label = classes[pred_idx]
|
| 74 |
result_text = f"Predicci贸n: {pred_label} ({probs[pred_idx]*100:.2f}%)"
|
| 75 |
|
| 76 |
+
# 6. M茅tricas geom茅tricas
|
| 77 |
area = calcular_area(mask)
|
| 78 |
perim = calcular_perimetro(mask)
|
| 79 |
circ = calcular_circularidad(mask)
|
|
|
|
| 87 |
f"Simetr铆a Horizontal: {sim_h}"
|
| 88 |
)
|
| 89 |
|
| 90 |
+
# 7. Grad-CAM con ZoomNet (usando la imagen en bruto)
|
| 91 |
+
raw_resized = cv2.resize(np.array(img_input), (ROWS, COLS))
|
| 92 |
+
raw_array = image.img_to_array(raw_resized) / 255.0
|
| 93 |
+
raw_array = np.expand_dims(raw_array, axis=0)
|
| 94 |
+
|
| 95 |
+
heatmap = make_gradcam_heatmap(raw_array, model_zoom, last_conv_layer_name="conv4")
|
| 96 |
+
heatmap = cv2.resize(heatmap, (ROWS, COLS))
|
| 97 |
+
heatmap = np.uint8(255 * heatmap)
|
| 98 |
+
heatmap_color = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
|
| 99 |
+
overlay = cv2.addWeighted(raw_resized.astype("uint8"), 0.6, heatmap_color, 0.4, 0)
|
| 100 |
+
|
| 101 |
+
return mask, lesion_rgb, result_text, metrics_text, overlay
|
| 102 |
|
| 103 |
# === Interfaz Gradio ===
|
| 104 |
demo = gr.Interface(
|
|
|
|
| 108 |
gr.Image(type="numpy", label="M谩scara Binaria"),
|
| 109 |
gr.Image(type="numpy", label="Lesi贸n Segmentada"),
|
| 110 |
gr.Textbox(label="Resultado del Modelo"),
|
| 111 |
+
gr.Textbox(label="M茅tricas de la Lesi贸n"),
|
| 112 |
+
gr.Image(type="numpy", label="Grad-CAM (ZoomNet)")
|
| 113 |
],
|
| 114 |
title="DermaScan - Clasificaci贸n de Lesiones",
|
| 115 |
+
description="Sube una imagen de piel. El sistema segmenta la lesi贸n, muestra la m谩scara, la predicci贸n, m茅tricas geom茅tricas y Grad-CAM."
|
| 116 |
)
|
| 117 |
|
| 118 |
if __name__ == "__main__":
|