import os
import warnings
warnings.filterwarnings('ignore', category=UserWarning)
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import streamlit as st
import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import io
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# ====== Page Configuration ======
st.set_page_config(
page_title="Tetanus Risk Classifier",
page_icon="🩺",
layout="wide",
initial_sidebar_state="expanded"
)
# ====== Custom CSS for Modern UI ======
st.markdown("""
""", unsafe_allow_html=True)
# ====== Main Title ======
st.markdown('
Tetanus Risk Assessment System
', unsafe_allow_html=True)
st.markdown('AI-powered medical imaging analysis for tetanus risk evaluation
', unsafe_allow_html=True)
# ====== Enhanced Sidebar Configuration ======
with st.sidebar:
st.markdown('', unsafe_allow_html=True)
# ====== Model Loading Function ======
@st.cache_resource
def load_tetanus_model(model_path):
"""Load the trained model with enhanced error handling"""
try:
if os.path.exists(model_path):
model = load_model(model_path)
return model, None
else:
return None, f"Model file not found at: {model_path}"
except Exception as e:
return None, f"Error loading model: {str(e)}"
# ====== Enhanced Image Preprocessing ======
def preprocess_image(img):
"""Enhanced image preprocessing with validation"""
if img.mode != 'RGB':
img = img.convert('RGB')
# Store original size for display
original_size = img.size
# Resize for model
img = img.resize((224, 224))
img_array = image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = img_array / 255.0
return img_array, original_size
# ====== Enhanced Prediction Function ======
def make_prediction(model, img_array):
"""Make prediction with detailed probability analysis"""
try:
risk_categories = ['High Risk', 'Mid Risk', 'Low Risk']
# 🔥 Use actual model prediction instead of mock
prediction = model.predict(img_array, verbose=0)
predicted_index = np.argmax(prediction)
predicted_label = risk_categories[predicted_index]
confidence = prediction[0][predicted_index] * 100
all_probabilities = prediction[0] * 100
return predicted_label, confidence, all_probabilities, None
except Exception as e:
return None, None, None, f"Error making prediction: {str(e)}"
# ====== Enhanced Visualization Functions ======
def create_confidence_chart(confidence):
"""Create an enhanced confidence visualization"""
fig = go.Figure(go.Indicator(
mode = "gauge+number+delta",
value = confidence,
domain = {'x': [0, 1], 'y': [0, 1]},
title = {'text': "Confidence Level"},
delta = {'reference': 80},
gauge = {
'axis': {'range': [None, 100]},
'bar': {'color': "#4f46e5"},
'steps': [
{'range': [0, 50], 'color': "#fee2e2"},
{'range': [50, 80], 'color': "#fef3c7"},
{'range': [80, 100], 'color': "#d1fae5"}],
'threshold': {
'line': {'color': "red", 'width': 4},
'thickness': 0.75,
'value': 90}}))
fig.update_layout(
height=300,
font={'color': "#4f46e5", 'family': "Inter"},
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)"
)
return fig
def create_probability_chart(probabilities, categories):
"""Create enhanced probability visualization"""
colors = ['#ef4444', '#f59e0b', '#10b981']
fig = go.Figure(data=[
go.Bar(
x=categories,
y=probabilities,
marker_color=colors,
text=[f'{p:.1f}%' for p in probabilities],
textposition='auto',
)
])
fig.update_layout(
title="Risk Probability Distribution",
xaxis_title="Risk Categories",
yaxis_title="Probability (%)",
font={'color': "#374151", 'family': "Inter"},
paper_bgcolor="rgba(0,0,0,0)",
plot_bgcolor="rgba(0,0,0,0)",
height=400
)
return fig
# ====== Main Application ======
def main():
# Load model with enhanced feedback
with st.spinner("Loading AI model..."):
model, error = load_tetanus_model(model_path)
if error:
st.error(f"**Model Loading Error:** {error}")
st.info("**Tip:** Please verify the model path in the sidebar configuration.")
st.stop()
# Success message with animation
st.info("**AI Model loaded successfully!** Ready for medical image analysis.")
# Create enhanced layout
col1, col2 = st.columns([1.2, 1], gap="large")
with col1:
# Enhanced upload section
st.markdown('', unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
# File uploader
uploaded_file = st.file_uploader(
"Upload Medical Image",
type=['png', 'jpg', 'jpeg', 'bmp', 'tiff'],
help="Upload a clear, high-quality image of the wound for analysis",
label_visibility="collapsed"
)
# Camera input
camera_file = st.camera_input(
"Capture Medical Image",
label_visibility="collapsed"
)
# Pick whichever is used
final_file = uploaded_file if uploaded_file is not None else camera_file
if final_file is not None:
# Display image with enhanced presentation
img = Image.open(final_file)
st.image(img, caption="Medical Image for Analysis", use_container_width=True)
# Enhanced image metadata
img_array, original_size = preprocess_image(img)
col_meta1, col_meta2, col_meta3 = st.columns(3)
with col_meta1:
st.markdown('
', unsafe_allow_html=True)
st.metric("Dimensions", f"{original_size[0]} × {original_size[1]}")
st.markdown('
', unsafe_allow_html=True)
with col_meta2:
st.markdown('
', unsafe_allow_html=True)
st.metric("Format", img.format if hasattr(img, 'format') else 'Unknown')
st.markdown('
', unsafe_allow_html=True)
with col_meta3:
st.markdown('
', unsafe_allow_html=True)
file_size = len(final_file.getvalue()) / 1024 # KB
st.metric("Size", f"{file_size:.1f} KB")
st.markdown('
', unsafe_allow_html=True)
else:
# Enhanced empty state
st.markdown("### Drop your medical image here or capture using the camera")
st.markdown("Supported formats: PNG, JPG, JPEG, BMP, TIFF")
st.markdown("Maximum file size: 10MB")
st.markdown('
', unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
with col2:
# Enhanced results section
st.markdown('', unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
if uploaded_file is not None or camera_file is not None:
# Choose file priority (uploaded > captured)
file_source = uploaded_file if uploaded_file is not None else camera_file
img = Image.open(file_source)
img_array, _ = preprocess_image(img)
# Processing with enhanced feedback
with st.spinner("Analyzing image with AI model..."):
predicted_label, confidence, all_probabilities, pred_error = make_prediction(model, img_array)
if pred_error:
st.error(f"❌ **Prediction Error:** {pred_error}")
st.markdown('
', unsafe_allow_html=True)
st.stop()
# Enhanced risk level display
if predicted_label == "High Risk":
st.markdown('HIGH RISK DETECTED
', unsafe_allow_html=True)
elif predicted_label == "Mid Risk":
st.markdown('MODERATE RISK DETECTED
', unsafe_allow_html=True)
else:
st.markdown('LOW RISK DETECTED
', unsafe_allow_html=True)
# Enhanced confidence display
st.markdown("### Confidence Analysis")
confidence_chart = create_confidence_chart(confidence)
st.plotly_chart(confidence_chart, use_container_width=True)
else:
# Enhanced empty state for results
st.markdown("""
⚕
Ready for Analysis
Upload or capture a medical image to begin AI-powered risk assessment
""", unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
# Enhanced detailed analysis section (full width)
if (uploaded_file is not None or camera_file is not None) and 'predicted_label' in locals():
st.markdown('', unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
# Create probability visualization
risk_categories = ['High Risk', 'Mid Risk', 'Low Risk']
prob_chart = create_probability_chart(all_probabilities, risk_categories)
st.plotly_chart(prob_chart, use_container_width=True)
# Detailed breakdown
col1, col2, col3 = st.columns(3)
categories = ['High Risk', 'Mid Risk', 'Low Risk']
colors = ['#ef4444', '#f59e0b', '#10b981']
for i, (col, category, color, prob) in enumerate(zip([col1, col2, col3], categories, colors, all_probabilities)):
with col:
st.markdown(f"""
""", unsafe_allow_html=True)
st.markdown('
', unsafe_allow_html=True)
# Enhanced recommendations section
st.markdown('', unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
if predicted_label == "High Risk":
st.markdown("""
IMMEDIATE MEDICAL ATTENTION REQUIRED
- Seek emergency medical care immediately
- Do not delay professional treatment
- Verify tetanus vaccination status with healthcare provider
- Clean wound with sterile saline if available
- Avoid home remedies - professional care is essential
- Monitor for signs of infection or tetanus symptoms
""", unsafe_allow_html=True)
elif predicted_label == "Mid Risk":
st.markdown("""
CLINICAL EVALUATION RECOMMENDED
- Clean wound thoroughly with soap and water
- Monitor for signs of infection (redness, swelling, warmth)
- Consult healthcare provider within 24 hours
- Update tetanus vaccination if necessary (>5 years)
- Apply clean dressing and change regularly
- Take photos to track healing progress
""", unsafe_allow_html=True)
else:
st.markdown("""
STANDARD WOUND CARE PROTOCOL
- Clean wound gently with soap and water
- Apply antiseptic and clean bandage
- Monitor for changes or infection signs
- Keep wound clean and dry
- Consider tetanus booster if >5 years since last vaccination
- Follow up if wound doesn't heal properly
""", unsafe_allow_html=True)
st.markdown('
', unsafe_allow_html=True)
# Enhanced information section
st.markdown("---")
info_col1, info_col2 = st.columns(2)
with info_col1:
st.markdown("""
System Overview
AI Technology: Convolutional Neural Networks
Processing: Real-time image analysis
Classification: Three-tier risk assessment
Guidelines: Evidence-based medical protocols
""", unsafe_allow_html=True)
with info_col2:
st.markdown("""
Technical Specs
Model Architecture: Deep CNN
Input Resolution: 224×224 pixels
Framework: TensorFlow/Keras
Inference Time: <2 seconds
""", unsafe_allow_html=True)
# ====== Run Application ======
if __name__ == "__main__":
main()