Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,65 +1,142 @@
|
|
1 |
-
import os
|
2 |
import tensorflow as tf
|
3 |
import numpy as np
|
4 |
import streamlit as st
|
|
|
5 |
from PIL import Image
|
6 |
from fpdf import FPDF
|
7 |
|
8 |
-
#
|
9 |
-
|
10 |
-
MODEL_PATH = "brain_tumor_detection_model.h5"
|
11 |
|
12 |
-
# Function to
|
13 |
-
def
|
14 |
-
|
15 |
-
|
16 |
|
17 |
-
#
|
18 |
-
download_model(MODEL_PATH, MODEL_URL)
|
19 |
-
|
20 |
-
# Load the model
|
21 |
try:
|
22 |
-
model =
|
|
|
23 |
except Exception as e:
|
24 |
st.error(f"Error encountered while loading the model: {e}")
|
25 |
model = None
|
26 |
|
27 |
-
# Check if model is loaded successfully
|
28 |
-
if model is None:
|
29 |
-
st.stop()
|
30 |
-
|
31 |
# Define the class labels
|
32 |
label_map = {0: 'Glioma', 1: 'Meningioma', 2: 'Normal', 3: 'Pituitary'}
|
33 |
|
34 |
def preprocess_image(image):
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
-
#
|
41 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
try:
|
43 |
img_array = preprocess_image(image)
|
|
|
|
|
44 |
predictions = model.predict(img_array)[0]
|
45 |
class_idx = np.argmax(predictions)
|
46 |
class_label = label_map[class_idx]
|
47 |
|
|
|
48 |
prediction_results = [f"{label_map[i]}: {predictions[i] * 100:.2f}%" for i in range(len(predictions))]
|
49 |
prediction_text = f"Prediction: {class_label}\n" + "\n".join(prediction_results)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
-
return prediction_text
|
52 |
except Exception as e:
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
-
|
56 |
-
st.
|
57 |
-
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
st.image(image, caption='Uploaded Image', use_column_width=True)
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
1 |
import tensorflow as tf
|
2 |
import numpy as np
|
3 |
import streamlit as st
|
4 |
+
import matplotlib.pyplot as plt
|
5 |
from PIL import Image
|
6 |
from fpdf import FPDF
|
7 |
|
8 |
+
# Load the pre-trained model from Hugging Face
|
9 |
+
model_url = "https://huggingface.co/chrisaldikaraharja/BrainTumor-Model/resolve/main/brain_tumor_detection_model.h5"
|
|
|
10 |
|
11 |
+
# Function to load the model
|
12 |
+
def load_model(model_path):
|
13 |
+
model = tf.keras.models.load_model(model_path, compile=False)
|
14 |
+
return model
|
15 |
|
16 |
+
# Attempt to load the model
|
|
|
|
|
|
|
17 |
try:
|
18 |
+
model = load_model(model_url)
|
19 |
+
st.success("Model loaded successfully.")
|
20 |
except Exception as e:
|
21 |
st.error(f"Error encountered while loading the model: {e}")
|
22 |
model = None
|
23 |
|
|
|
|
|
|
|
|
|
24 |
# Define the class labels
|
25 |
label_map = {0: 'Glioma', 1: 'Meningioma', 2: 'Normal', 3: 'Pituitary'}
|
26 |
|
27 |
def preprocess_image(image):
|
28 |
+
try:
|
29 |
+
img = image.resize((150, 150)) # Resize to match model input shape
|
30 |
+
img = np.array(img) / 255.0 # Normalize pixel values
|
31 |
+
img = np.expand_dims(img, axis=0) # Add batch dimension
|
32 |
+
return img
|
33 |
+
except Exception as e:
|
34 |
+
st.error(f"Error in preprocessing image: {e}")
|
35 |
+
raise
|
36 |
+
|
37 |
+
# Function to compute Occlusion Sensitivity
|
38 |
+
def compute_occlusion_sensitivity(model, img_array, class_idx, patch_size=15):
|
39 |
+
img_array_np = img_array.squeeze()
|
40 |
+
img_shape = img_array_np.shape
|
41 |
+
|
42 |
+
original_img = np.copy(img_array_np)
|
43 |
+
original_prediction = model.predict(np.expand_dims(original_img, axis=0))[0, class_idx]
|
44 |
+
|
45 |
+
sensitivity_map = np.zeros((img_shape[0], img_shape[1]))
|
46 |
+
|
47 |
+
for i in range(0, img_shape[0], patch_size):
|
48 |
+
for j in range(0, img_shape[1], patch_size):
|
49 |
+
img_copy = np.copy(original_img)
|
50 |
+
img_copy[i:i+patch_size, j:j+patch_size, :] = 0 # Occlude patch
|
51 |
+
|
52 |
+
occluded_prediction = model.predict(np.expand_dims(img_copy, axis=0))[0, class_idx]
|
53 |
+
sensitivity_map[i:i+patch_size, j:j+patch_size] = original_prediction - occluded_prediction
|
54 |
+
|
55 |
+
return sensitivity_map
|
56 |
|
57 |
+
# Function to visualize the occlusion map
|
58 |
+
def visualize_occlusion_map(img, occlusion_map):
|
59 |
+
plt.figure(figsize=(10, 10))
|
60 |
+
plt.imshow(img)
|
61 |
+
plt.imshow(occlusion_map, cmap='hot', alpha=0.5)
|
62 |
+
plt.axis('off')
|
63 |
+
plt.colorbar()
|
64 |
+
occlusion_path = "/tmp/occlusion_map.png"
|
65 |
+
plt.savefig(occlusion_path)
|
66 |
+
plt.close()
|
67 |
+
return occlusion_path
|
68 |
+
|
69 |
+
# Function to generate PDF report
|
70 |
+
def create_pdf_report(prediction_text, doctor_notes, image_path):
|
71 |
+
pdf = FPDF()
|
72 |
+
pdf.add_page()
|
73 |
+
pdf.set_font("Arial", size=12)
|
74 |
+
pdf.multi_cell(0, 10, prediction_text)
|
75 |
+
pdf.ln(10)
|
76 |
+
pdf.set_font("Arial", 'B', size=12)
|
77 |
+
pdf.cell(0, 10, "Doctor's Notes:")
|
78 |
+
pdf.ln(10)
|
79 |
+
pdf.set_font("Arial", size=12)
|
80 |
+
pdf.multi_cell(0, 10, doctor_notes)
|
81 |
+
pdf.image(image_path, x=10, y=pdf.get_y(), w=pdf.w - 20)
|
82 |
+
pdf_output_path = "/tmp/medical_report.pdf"
|
83 |
+
pdf.output(pdf_output_path)
|
84 |
+
return pdf_output_path
|
85 |
+
|
86 |
+
# Main prediction and report generation function
|
87 |
+
def predict_and_generate_report(image, doctor_notes):
|
88 |
try:
|
89 |
img_array = preprocess_image(image)
|
90 |
+
print(f"Preprocessed image shape: {img_array.shape}") # Debugging output
|
91 |
+
|
92 |
predictions = model.predict(img_array)[0]
|
93 |
class_idx = np.argmax(predictions)
|
94 |
class_label = label_map[class_idx]
|
95 |
|
96 |
+
# Prediction text
|
97 |
prediction_results = [f"{label_map[i]}: {predictions[i] * 100:.2f}%" for i in range(len(predictions))]
|
98 |
prediction_text = f"Prediction: {class_label}\n" + "\n".join(prediction_results)
|
99 |
+
print(f"Predictions: {predictions}")
|
100 |
+
|
101 |
+
# Save the uploaded image
|
102 |
+
image_path = "/tmp/image.png"
|
103 |
+
image.save(image_path)
|
104 |
+
|
105 |
+
# Generate PDF report
|
106 |
+
pdf_report_path = create_pdf_report(prediction_text, doctor_notes, image_path)
|
107 |
+
|
108 |
+
# Compute and visualize occlusion sensitivity
|
109 |
+
occlusion_map = compute_occlusion_sensitivity(model, img_array, class_idx)
|
110 |
+
occlusion_map_path = visualize_occlusion_map(np.array(image), occlusion_map)
|
111 |
+
|
112 |
+
return image, prediction_text, pdf_report_path, occlusion_map_path
|
113 |
|
|
|
114 |
except Exception as e:
|
115 |
+
print(f"Error during prediction: {e}")
|
116 |
+
return None, "Error during prediction. Please check the input image.", None, None
|
117 |
+
|
118 |
+
# Streamlit Interface
|
119 |
+
st.title("Brain Tumor Detection and Occlusion Sensitivity")
|
120 |
+
st.write("Upload an MRI image to detect brain tumors and view which areas contributed to the prediction.")
|
121 |
+
|
122 |
+
# Image upload
|
123 |
+
uploaded_image = st.file_uploader("Upload MRI Image", type=["png", "jpg", "jpeg"])
|
124 |
+
doctor_notes = st.text_area("Enter doctor's notes here...", "")
|
125 |
+
|
126 |
+
if st.button("Predict"):
|
127 |
+
if uploaded_image is not None:
|
128 |
+
image = Image.open(uploaded_image)
|
129 |
+
drawn_image, prediction_text, pdf_report_path, occlusion_map_path = predict_and_generate_report(image, doctor_notes)
|
130 |
|
131 |
+
if drawn_image is not None:
|
132 |
+
st.image(drawn_image, caption="Original MRI Image", use_column_width=True)
|
133 |
+
st.text(prediction_text)
|
134 |
|
135 |
+
# Provide PDF report download
|
136 |
+
st.download_button("Download Medical Report", data=open(pdf_report_path, "rb").read(), file_name="medical_report.pdf")
|
|
|
137 |
|
138 |
+
# Display Occlusion Sensitivity Map
|
139 |
+
occlusion_image = Image.open(occlusion_map_path)
|
140 |
+
st.image(occlusion_image, caption="Occlusion Sensitivity Map", use_column_width=True)
|
141 |
+
else:
|
142 |
+
st.warning("Please upload an MRI image to proceed.")
|