Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,13 +6,16 @@ from torchvision.transforms import Compose, Resize, ToTensor, Normalize
|
|
| 6 |
import tensorflow as tf
|
| 7 |
from tensorflow.keras.models import load_model
|
| 8 |
import random
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
# Taille d'entrée pour les modèles
|
| 11 |
INPUT_SIZE = 224
|
| 12 |
|
| 13 |
# Chemins des modèles sauvegardés
|
| 14 |
MODEL_PT_PATH = "best_model.pth"
|
| 15 |
-
MODEL_TF_PATH = "kidney_model.keras"
|
| 16 |
|
| 17 |
# Chargement des classes
|
| 18 |
class_names = ['Cyst', 'Normal', 'Stone', 'Tumor']
|
|
@@ -85,6 +88,49 @@ def predict_with_tensorflow(model_path, image):
|
|
| 85 |
|
| 86 |
return class_names[label_idx], predictions
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
# Fonction JS pour animer les ballons
|
| 89 |
def show_balloons():
|
| 90 |
st.markdown("""
|
|
@@ -215,7 +261,7 @@ st.markdown("""
|
|
| 215 |
""", unsafe_allow_html=True)
|
| 216 |
|
| 217 |
# Application Streamlit
|
| 218 |
-
st.markdown('<div class="title">
|
| 219 |
|
| 220 |
menu = st.sidebar.selectbox("Menu", ["🧠 Accueil", "Classification avec PyTorch", "Classification avec TensorFlow", "👨💻À propos", "Légendes"])
|
| 221 |
|
|
@@ -280,6 +326,10 @@ elif menu == "Classification avec PyTorch":
|
|
| 280 |
label, probabilities = predict_with_pytorch(MODEL_PT_PATH, image)
|
| 281 |
st.markdown(f'<div class="result">Classe prédite : <b>{label}</b></div>', unsafe_allow_html=True)
|
| 282 |
st.bar_chart(probabilities)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
if label == "Normal":
|
| 284 |
st.balloons() # Affiche les ballons si la classe est "Normal"
|
| 285 |
else:
|
|
@@ -297,8 +347,12 @@ elif menu == "Classification avec TensorFlow":
|
|
| 297 |
label, probabilities = predict_with_tensorflow(MODEL_TF_PATH, image)
|
| 298 |
st.markdown(f'<div class="result">Classe prédite : <b>{label}</b></div>', unsafe_allow_html=True)
|
| 299 |
st.bar_chart(probabilities)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
if label == "Normal":
|
| 301 |
-
|
| 302 |
else:
|
| 303 |
st.markdown("<h2 style='color: red;'>Désolé, le résultat n'est pas normal...</h2>", unsafe_allow_html=True)
|
| 304 |
|
|
|
|
| 6 |
import tensorflow as tf
|
| 7 |
from tensorflow.keras.models import load_model
|
| 8 |
import random
|
| 9 |
+
from fpdf import FPDF
|
| 10 |
+
import io
|
| 11 |
+
import os
|
| 12 |
|
| 13 |
# Taille d'entrée pour les modèles
|
| 14 |
INPUT_SIZE = 224
|
| 15 |
|
| 16 |
# Chemins des modèles sauvegardés
|
| 17 |
MODEL_PT_PATH = "best_model.pth"
|
| 18 |
+
MODEL_TF_PATH = "model/kidney_model.keras"
|
| 19 |
|
| 20 |
# Chargement des classes
|
| 21 |
class_names = ['Cyst', 'Normal', 'Stone', 'Tumor']
|
|
|
|
| 88 |
|
| 89 |
return class_names[label_idx], predictions
|
| 90 |
|
| 91 |
+
# Fonction pour générer un PDF avec les prédictions et recommandations
|
| 92 |
+
def generate_pdf(prediction, probabilities, image, model_name):
|
| 93 |
+
pdf = FPDF()
|
| 94 |
+
pdf.set_auto_page_break(auto=True, margin=15)
|
| 95 |
+
pdf.add_page()
|
| 96 |
+
pdf.set_font("Arial", style="B", size=16)
|
| 97 |
+
pdf.cell(200, 10, "Rapport de Prédiction", ln=True, align='C')
|
| 98 |
+
pdf.ln(10)
|
| 99 |
+
|
| 100 |
+
pdf.set_font("Arial", size=12)
|
| 101 |
+
pdf.cell(200, 10, f"Modèle utilisé: {model_name}", ln=True)
|
| 102 |
+
pdf.cell(200, 10, f"Prédiction: {prediction}", ln=True)
|
| 103 |
+
pdf.cell(200, 10, "Probabilités:", ln=True)
|
| 104 |
+
|
| 105 |
+
for i, prob in enumerate(probabilities):
|
| 106 |
+
pdf.cell(200, 10, f"{class_names[i]}: {prob:.2%}", ln=True)
|
| 107 |
+
|
| 108 |
+
pdf.ln(10)
|
| 109 |
+
pdf.cell(200, 10, "Recommandations:", ln=True)
|
| 110 |
+
|
| 111 |
+
recommendations = {
|
| 112 |
+
"Cyst": "Consultez un urologue pour une évaluation approfondie.",
|
| 113 |
+
"Normal": "Aucune intervention n'est requise.",
|
| 114 |
+
"Stone": "Hydratation et suivi avec un spécialiste recommandés.",
|
| 115 |
+
"Tumor": "Consultez un oncologue pour un diagnostic précis."
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
pdf.multi_cell(0, 10, recommendations.get(prediction, "Aucune recommandation disponible."))
|
| 119 |
+
|
| 120 |
+
# Sauvegarde et insertion de l'image
|
| 121 |
+
img_path = "temp_image.jpg"
|
| 122 |
+
image.save(img_path)
|
| 123 |
+
pdf.image(img_path, x=60, w=90)
|
| 124 |
+
|
| 125 |
+
# Générer le PDF en mémoire
|
| 126 |
+
pdf_output = io.BytesIO()
|
| 127 |
+
pdf_bytes = pdf.output(dest='S').encode('latin1') # Générer en mémoire
|
| 128 |
+
pdf_output.write(pdf_bytes)
|
| 129 |
+
pdf_output.seek(0)
|
| 130 |
+
|
| 131 |
+
return pdf_output
|
| 132 |
+
|
| 133 |
+
|
| 134 |
# Fonction JS pour animer les ballons
|
| 135 |
def show_balloons():
|
| 136 |
st.markdown("""
|
|
|
|
| 261 |
""", unsafe_allow_html=True)
|
| 262 |
|
| 263 |
# Application Streamlit
|
| 264 |
+
st.markdown('<div class="title">Session Normale (Kidney Classification)</div>', unsafe_allow_html=True)
|
| 265 |
|
| 266 |
menu = st.sidebar.selectbox("Menu", ["🧠 Accueil", "Classification avec PyTorch", "Classification avec TensorFlow", "👨💻À propos", "Légendes"])
|
| 267 |
|
|
|
|
| 326 |
label, probabilities = predict_with_pytorch(MODEL_PT_PATH, image)
|
| 327 |
st.markdown(f'<div class="result">Classe prédite : <b>{label}</b></div>', unsafe_allow_html=True)
|
| 328 |
st.bar_chart(probabilities)
|
| 329 |
+
|
| 330 |
+
pdf_file = generate_pdf(label, probabilities, image, MODEL_PT_PATH)
|
| 331 |
+
|
| 332 |
+
st.download_button("Télécharger le rapport PDF", pdf_file, "rapport_prediction.pdf", "application/pdf")
|
| 333 |
if label == "Normal":
|
| 334 |
st.balloons() # Affiche les ballons si la classe est "Normal"
|
| 335 |
else:
|
|
|
|
| 347 |
label, probabilities = predict_with_tensorflow(MODEL_TF_PATH, image)
|
| 348 |
st.markdown(f'<div class="result">Classe prédite : <b>{label}</b></div>', unsafe_allow_html=True)
|
| 349 |
st.bar_chart(probabilities)
|
| 350 |
+
pdf_file = generate_pdf(label, probabilities, image, MODEL_TF_PATH)
|
| 351 |
+
|
| 352 |
+
st.download_button("Télécharger le rapport PDF", pdf_file, "rapport_prediction.pdf", "application/pdf")
|
| 353 |
+
|
| 354 |
if label == "Normal":
|
| 355 |
+
st.balloons() # Affiche les ballons si la classe est "Normal"
|
| 356 |
else:
|
| 357 |
st.markdown("<h2 style='color: red;'>Désolé, le résultat n'est pas normal...</h2>", unsafe_allow_html=True)
|
| 358 |
|