Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import tensorflow as tf | |
| import numpy as np | |
| from PIL import Image | |
| import os | |
| # Page configuration | |
| st.set_page_config( | |
| page_title="Pneumonia Detection AI", | |
| page_icon="π«", | |
| layout="wide" | |
| ) | |
| # Custom CSS | |
| st.markdown(""" | |
| <style> | |
| .main-header { | |
| text-align: center; | |
| color: #1f77b4; | |
| margin-bottom: 2rem; | |
| } | |
| .result-box { | |
| padding: 1rem; | |
| border-radius: 10px; | |
| margin: 1rem 0; | |
| text-align: center; | |
| } | |
| .pneumonia-result { | |
| background-color: #f8d7da; | |
| border: 2px solid #dc3545; | |
| color: #721c24; | |
| } | |
| .normal-result { | |
| background-color: #d4edda; | |
| border: 2px solid #28a745; | |
| color: #155724; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Header | |
| st.markdown('<h1 class="main-header">π« Pneumonia Detection AI</h1>', unsafe_allow_html=True) | |
| st.markdown('<p style="text-align: center; font-size: 1.2rem; color: #666;">Upload a chest X-ray image for AI-powered pneumonia detection</p>', unsafe_allow_html=True) | |
| def load_model(): | |
| """Load the Keras model - much more reliable!""" | |
| try: | |
| model_path = 'Fast_VGG19_3epoch.keras' # Changed to .keras format! | |
| if os.path.exists(model_path): | |
| model = tf.keras.models.load_model(model_path) | |
| st.success("β Keras model loaded successfully!") | |
| return model | |
| else: | |
| st.error(f"Model file not found: {model_path}") | |
| return None | |
| except Exception as e: | |
| st.error(f"Error loading model: {str(e)}") | |
| return None | |
| def preprocess_image(image): | |
| """Preprocess image for model prediction""" | |
| try: | |
| img = np.array(image.convert('RGB')) | |
| img = tf.image.resize(img, [64, 64]) | |
| img = tf.cast(img, tf.float32) / 255.0 | |
| mean = [0.485, 0.456, 0.406] | |
| std = [0.229, 0.224, 0.225] | |
| img = (img - mean) / std | |
| return tf.expand_dims(img, 0) | |
| except Exception as e: | |
| st.error(f"Error preprocessing image: {str(e)}") | |
| return None | |
| # Sidebar information | |
| with st.sidebar: | |
| st.header("π Model Information") | |
| st.info(""" | |
| **Architecture:** VGG19 Transfer Learning | |
| **Accuracy:** 77.0% | |
| **AUC Score:** 0.850 | |
| **Format:** Keras (.keras) β | |
| **TensorFlow:** 2.15.0 | |
| """) | |
| st.header("π How to Use") | |
| st.markdown(""" | |
| 1. **Upload Image:** Click browse to select X-ray | |
| 2. **Supported Formats:** JPG, JPEG, PNG | |
| 3. **Click Analyze:** Get AI prediction | |
| 4. **Review Results:** Check confidence levels | |
| """) | |
| # Load model | |
| model = load_model() | |
| if model is not None: | |
| uploaded_file = st.file_uploader( | |
| "Choose a chest X-ray image", | |
| type=['jpg', 'jpeg', 'png'], | |
| help="Upload a chest X-ray image in JPG, JPEG, or PNG format" | |
| ) | |
| if uploaded_file is not None: | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| st.subheader("πΈ Uploaded Image") | |
| image = Image.open(uploaded_file) | |
| st.image(image, caption="Chest X-ray Image", use_column_width=True) | |
| st.write(f"**Filename:** {uploaded_file.name}") | |
| st.write(f"**Size:** {image.size}") | |
| with col2: | |
| st.subheader("π€ AI Analysis") | |
| if st.button("π Analyze X-ray", type="primary", use_container_width=True): | |
| with st.spinner("π§ AI is analyzing the X-ray..."): | |
| processed_img = preprocess_image(image) | |
| if processed_img is not None: | |
| try: | |
| prediction = model.predict(processed_img, verbose=0)[0][0] | |
| if prediction > 0.5: | |
| confidence = prediction * 100 | |
| pneumonia_html = f""" | |
| <div class="result-box pneumonia-result"> | |
| <h3>π¨ PNEUMONIA DETECTED</h3> | |
| <h4>Confidence: {confidence:.1f}%</h4> | |
| </div> | |
| """ | |
| st.markdown(pneumonia_html, unsafe_allow_html=True) | |
| if confidence >= 80: | |
| st.error("π¨ **HIGH CONFIDENCE** - Immediate medical attention recommended") | |
| elif confidence >= 60: | |
| st.warning("β οΈ **MODERATE CONFIDENCE** - Medical consultation advised") | |
| else: | |
| st.info("βΉοΈ **LOW CONFIDENCE** - Consider additional testing") | |
| else: | |
| confidence = (1 - prediction) * 100 | |
| normal_html = f""" | |
| <div class="result-box normal-result"> | |
| <h3>β NORMAL</h3> | |
| <h4>Confidence: {confidence:.1f}%</h4> | |
| </div> | |
| """ | |
| st.markdown(normal_html, unsafe_allow_html=True) | |
| if confidence >= 80: | |
| st.success("β **HIGH CONFIDENCE** - X-ray appears normal") | |
| elif confidence >= 60: | |
| st.info("βΉοΈ **MODERATE CONFIDENCE** - Likely normal") | |
| else: | |
| st.warning("β οΈ **LOW CONFIDENCE** - Review recommended") | |
| # Detailed probabilities | |
| st.subheader("π Detailed Analysis") | |
| normal_prob = (1 - prediction) * 100 | |
| pneumonia_prob = prediction * 100 | |
| st.write("**Probability Breakdown:**") | |
| st.progress(normal_prob/100, text=f"Normal: {normal_prob:.1f}%") | |
| st.progress(pneumonia_prob/100, text=f"Pneumonia: {pneumonia_prob:.1f}%") | |
| col_a, col_b = st.columns(2) | |
| with col_a: | |
| st.metric("Normal", f"{normal_prob:.1f}%") | |
| with col_b: | |
| st.metric("Pneumonia", f"{pneumonia_prob:.1f}%") | |
| except Exception as e: | |
| st.error(f"β Prediction failed: {str(e)}") | |
| else: | |
| st.error("β Failed to process image") | |
| else: | |
| st.info("π Please upload a chest X-ray image to begin analysis") | |
| else: | |
| st.error("β Failed to load the AI model. Please check the deployment.") | |
| # Footer | |
| footer_html = """ | |
| <div style="text-align: center; padding: 2rem; background-color: #f8f9fa; border-radius: 10px; margin-top: 2rem;"> | |
| <h4>β οΈ Medical Disclaimer</h4> | |
| <p>This AI tool is for <strong>educational and research purposes only</strong>. | |
| It should not be used as a substitute for professional medical advice, diagnosis, or treatment. | |
| Always seek the advice of qualified healthcare providers with any questions regarding medical conditions.</p> | |
| <hr style="margin: 1rem 0;"> | |
| <p><em>π³ Powered by Docker β’ TensorFlow 2.15.0 β’ Streamlit</em></p> | |
| <p><em>π€ VGG19 Transfer Learning Model (.keras format)</em></p> | |
| </div> | |
| """ | |
| st.markdown("---") | |
| st.markdown(footer_html, unsafe_allow_html=True) | |