madboi's picture
Upload 3 files
4e0c33e verified
import streamlit as st
import numpy as np
import cv2
import tensorflow as tf
from tensorflow.keras.preprocessing import image
import matplotlib.pyplot as plt
from PIL import Image
import gdown
# Load trained model
# model_path = "tb_classification_model.h5" # Ensure this file exists
# model = tf.keras.models.load_model(model_path)
file_id = "1S6Keu4Qmaj6NrtX3lF3s9tbUFlyYhDhL"
output_path = "tb_classification_model.h5"
# Download the model
gdown.download(f"https://drive.google.com/uc?id={file_id}", output_path, quiet=False)
# Load the model
model = tf.keras.models.load_model(output_path)
def preprocess_image(img):
img = img.resize((224, 224)) # Resize to model input size
img_array = image.img_to_array(img)
# Convert grayscale images to 3-channel RGB
if img_array.shape[-1] == 1:
img_array = np.repeat(img_array, 3, axis=-1) # (224, 224, 1) → (224, 224, 3)
img_array = img_array / 255.0 # Normalize
img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
return img_array # ✅ Return processed image
# Function to compute Grad-CAM
def compute_gradcam(model, img_array, layer_name="conv4_block5_out"):
grad_model = tf.keras.models.Model(inputs=model.input,
outputs=[model.get_layer(layer_name).output, model.output])
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(img_array)
class_idx = tf.argmax(predictions[0])
loss = predictions[:, class_idx]
grads = tape.gradient(loss, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
conv_outputs = conv_outputs.numpy()[0]
heatmap = np.dot(conv_outputs, pooled_grads.numpy())
heatmap = np.maximum(heatmap, 0) # ReLU
heatmap /= np.max(heatmap) + 1e-10 # Normalize
return heatmap
# Function to overlay Grad-CAM heatmap
def overlay_gradcam(img, heatmap, alpha=0.4):
"""Overlay Grad-CAM heatmap on the original image."""
# Ensure heatmap is the same size as the image
heatmap = cv2.resize(heatmap, (img.width, img.height)) # Resize to match original image
# Normalize heatmap to [0,255] and apply color mapping
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
# Convert PIL image to NumPy array
original = np.array(img)
# If original image is grayscale, convert to RGB
if len(original.shape) == 2 or original.shape[-1] == 1:
original = cv2.cvtColor(original, cv2.COLOR_GRAY2RGB)
# Ensure both images have the same shape (H, W, 3)
if heatmap.shape != original.shape:
heatmap = cv2.resize(heatmap, (original.shape[1], original.shape[0]))
# Blend original image with heatmap
superimposed = cv2.addWeighted(original, 1 - alpha, heatmap, alpha, 0)
return superimposed
# Streamlit UI
st.title("Tuberculosis Detection using ResNet50")
st.write("Upload a Chest X-ray image to classify as **Normal** or **TB**.")
uploaded_file = st.file_uploader("Choose a Chest X-ray Image...", type=["jpg", "png", "jpeg"])
if uploaded_file is not None:
image_pil = Image.open(uploaded_file)
st.image(image_pil, caption="Uploaded Image", use_container_width=True)
# Preprocess image
img_array = preprocess_image(image_pil)
# Get model prediction
prediction = model.predict(img_array)[0][0]
result = "Tuberculosis Detected" if prediction > 0.5 else "Normal"
confidence = prediction if prediction > 0.5 else 1 - prediction
st.subheader(f"Prediction: **{result}**")
st.write(f"Confidence: **{confidence:.2%}**")
# Generate Grad-CAM
heatmap = compute_gradcam(model, img_array)
gradcam_output = overlay_gradcam(image_pil, heatmap)
# Show Grad-CAM
st.subheader("Grad-CAM Visualization")
st.image(gradcam_output, caption="Grad-CAM Heatmap", use_container_width=True)