import streamlit as st
import pandas as pd
import numpy as np
import joblib
import pickle
from PIL import Image
import io
import cv2
import easyocr
import os
import plotly.graph_objects as go
import plotly.express as px
from datetime import datetime
import requests
import json
import base64
import tempfile
from groq import Groq
# Set page config first
st.set_page_config(
page_title="AI-Priority OPD System",
page_icon="🏥",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for styling
def local_css():
st.markdown("""
""", unsafe_allow_html=True)
# Initialize session state
def init_session_state():
if 'language' not in st.session_state:
st.session_state.language = 'English'
if 'patient_data' not in st.session_state:
st.session_state.patient_data = {}
if 'risk_scores' not in st.session_state:
st.session_state.risk_scores = {}
if 'chat_history' not in st.session_state:
st.session_state.chat_history = []
if 'groq_client' not in st.session_state:
st.session_state.groq_client = None
# Load trained models
@st.cache_resource(show_spinner=False)
def load_models():
try:
# Load your trained models
# Replace these paths with your actual model file paths
models = {}
# Try to load heart disease model
try:
heart_model = joblib.load('heart_model.pkl')
models['heart'] = heart_model
except:
st.error("❌ Heart disease model not found. Please ensure 'heart_disease_model.pkl' is in the directory.")
return None, None, None
# Try to load diabetes model
try:
diabetes_model = joblib.load('diabetes_model.pkl')
models['diabetes'] = diabetes_model
except:
st.error("❌ Diabetes model not found. Please ensure 'diabetes_model.pkl' is in the directory.")
return None, None, None
# Try to load hypertension model
try:
hypertension_model = joblib.load('hypertension_model.pkl')
models['hypertension'] = hypertension_model
except:
st.error("❌ Hypertension model not found. Please ensure 'hypertension_model.pkl' is in the directory.")
return None, None, None
return models['heart'], models['diabetes'], models['hypertension']
except Exception as e:
st.error(f"❌ Error loading models: {str(e)}")
return None, None, None
# Initialize Groq client
def init_groq_client(api_key):
try:
client = Groq(api_key=api_key)
return client
except Exception as e:
st.error(f"❌ Error initializing Groq client: {str(e)}")
return None
# Urdu translations
URDU_TRANSLATIONS = {
"AI-Priority OPD System": "AI-ترجیحی OPD سسٹم",
"Patient Information": "مریض کی معلومات",
"Name": "نام",
"Age": "عمر",
"Gender": "جنس",
"Contact": "رابطہ نمبر",
"Medical History": "طبی تاریخ",
"Vital Signs": "اہم علامات",
"Blood Pressure (systolic)": "بلڈ پریشر (سسٹولک)",
"Blood Pressure (diastolic)": "بلڈ پریشر (ڈائیسٹولک)",
"Heart Rate": "دل کی دھڑکن",
"Cholesterol Level": "کولیسٹرول کی سطح",
"Blood Glucose": "خون میں گلوکوز",
"BMI": "باڈی ماس انڈیکس",
"Symptoms": "علامات",
"Chest Pain": "سینے میں درد",
"Shortness of Breath": "سانس لینے میں دشواری",
"Fatigue": "تھکاوٹ",
"Upload Prescription": "نسخہ اپ لوڈ کریں",
"Calculate Risk Score": "خطرے کا اسکور معلوم کریں",
"High Priority - Emergency Care Required": "اعلی ترجیح - ہنگامی علاج کی ضرورت",
"Medium Priority - Same Day Consultation": "درمیانی ترجیح - اسی دن مشورہ",
"Low Priority - Routine Appointment": "کم ترجیح - معمول کی ملاقات",
"Healthcare Chatbot": "ہیلتھ کیئر چیٹ بوٹ",
"Ask health-related questions": "صحت سے متعلق سوالات پوچھیں"
}
class OCRProcessor:
def __init__(self):
# Initialize EasyOCR reader with error handling
try:
self.reader = easyocr.Reader(['en']) # English only for medical text
except Exception as e:
st.error(f"OCR initialization failed: {str(e)}")
self.reader = None
def preprocess_image(self, image):
"""Enhanced image preprocessing for better OCR accuracy"""
try:
# Convert to numpy array
img_array = np.array(image)
# Convert to grayscale if colored
if len(img_array.shape) == 3:
gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
else:
gray = img_array
# Apply different preprocessing techniques
# 1. Gaussian blur to reduce noise
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
# 2. Adaptive thresholding
thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
# 3. Morphological operations to clean up the image
kernel = np.ones((2, 2), np.uint8)
processed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
return processed
except Exception as e:
st.error(f"Image processing error: {str(e)}")
return np.array(image)
def extract_text(self, image):
"""Extract text from prescription image using EasyOCR"""
try:
if self.reader is None:
return "OCR not available. Please check EasyOCR installation."
# Preprocess image
processed_image = self.preprocess_image(image)
# Perform OCR
results = self.reader.readtext(processed_image, detail=0, paragraph=True)
# Combine all detected text
extracted_text = "\n".join(results)
return extracted_text.strip() if extracted_text.strip() else "No text detected in the image."
except Exception as e:
return f"OCR Error: {str(e)}"
def calculate_ocr_accuracy(self, extracted_text):
"""Estimate OCR accuracy based on text quality"""
if not extracted_text or len(extracted_text.strip()) == 0 or "No text detected" in extracted_text:
return 0
# Basic heuristics for accuracy estimation
text_length = len(extracted_text)
word_count = len(extracted_text.split())
# Check for common medical terms
medical_terms = ['tablet', 'mg', 'ml', 'daily', 'twice', 'capsule', 'injection']
found_terms = sum(1 for term in medical_terms if term in extracted_text.lower())
# Calculate confidence score
length_score = min(100, (text_length / 50) * 100) # More text = higher confidence
word_score = min(100, (word_count / 10) * 100) # More words = higher confidence
medical_score = (found_terms / len(medical_terms)) * 100
# Weighted average
accuracy = (length_score * 0.3 + word_score * 0.3 + medical_score * 0.4)
return min(95, accuracy) # Cap at 95% for realistic estimates
class HealthcareChatbot:
def __init__(self, groq_client):
self.client = groq_client
self.system_prompt = """You are a helpful and professional healthcare assistant designed for Pakistani patients.
Provide accurate, culturally appropriate medical advice in both English and Urdu.
Focus on preventive care, symptom explanation, and when to seek medical attention.
Always emphasize that you are an AI assistant and recommend consulting healthcare professionals for serious conditions."""
def get_response(self, query, language='English'):
"""Generate healthcare chatbot response using Groq API"""
try:
if self.client is None:
return "Chatbot service is currently unavailable. Please check the API configuration."
# Enhanced system prompt based on language
enhanced_system_prompt = self.system_prompt
if language == 'Urdu':
enhanced_system_prompt += " Respond in Urdu with proper medical terminology."
else:
enhanced_system_prompt += " Respond in English with clear medical advice."
# Create conversation context
messages = [
{"role": "system", "content": enhanced_system_prompt},
{"role": "user", "content": f"Patient query: {query}"}
]
# Generate response using Groq
chat_completion = self.client.chat.completions.create(
messages=messages,
model="llama3-8b-8192", # Using LLaMA 3 8B model
temperature=0.3,
max_tokens=512,
top_p=0.9
)
response = chat_completion.choices[0].message.content
# Add disclaimer
if language == 'Urdu':
response += "\n\n⚠️ براہ کرم نوٹ کریں: یہ ایک AI اسسٹنٹ ہے۔ سنگین طبی حالات کے لیے ہمیشہ کوالیفائیڈ ڈاکٹر سے مشورہ کریں۔"
else:
response += "\n\n⚠️ Please note: This is an AI assistant. Always consult qualified doctors for serious medical conditions."
return response
except Exception as e:
error_msg = f"Error generating response: {str(e)}"
if language == 'Urdu':
return f"معذرت، میں اس وقت آپ کے سوال کا جواب نہیں دے سکتا۔ براہ کرم بعد میں کوشش کریں۔\n\n{error_msg}"
else:
return f"Sorry, I'm unable to respond to your question right now. Please try again later.\n\n{error_msg}"
def calculate_priority_score(heart_risk, diabetes_risk, hypertension_risk):
"""Calculate integrated priority score with clinical weighting"""
# Clinical severity weighting
priority = (
heart_risk * 0.45 + # Highest weight for cardiac issues
diabetes_risk * 0.25 + # Medium weight for diabetes
hypertension_risk * 0.30 # Medium weight for hypertension
)
return min(1.0, priority) # Cap at 1.0
def get_priority_recommendation(priority_score, language='English'):
"""Get priority-based recommendation with clinical thresholds"""
if priority_score >= 0.75:
if language == 'Urdu':
return "EMERGENCY_CARE", "اعلی ترجیح - فوری ہنگامی علاج کی ضرورت", "risk-high"
else:
return "EMERGENCY_CARE", "High Priority - Immediate Emergency Care Required", "risk-high"
elif priority_score >= 0.55:
if language == 'Urdu':
return "SAME_DAY_CONSULT", "درمیانی ترجیح - اسی دن مشورہ ضروری", "risk-medium"
else:
return "SAME_DAY_CONSULT", "Medium Priority - Same Day Consultation Required", "risk-medium"
else:
if language == 'Urdu':
return "ROUTINE_APPOINTMENT", "کم ترجیح - روٹین اپائنٹمنٹ", "risk-low"
else:
return "ROUTINE_APPOINTMENT", "Low Priority - Routine Appointment", "risk-low"
def validate_patient_data(age, bp_systolic, bp_diastolic, heart_rate):
"""Validate patient data for realistic clinical values"""
errors = []
if age < 1 or age > 120:
errors.append("Age must be between 1 and 120 years")
if bp_systolic < 70 or bp_systolic > 250:
errors.append("Systolic BP must be between 70 and 250 mmHg")
if bp_diastolic < 40 or bp_diastolic > 150:
errors.append("Diastolic BP must be between 40 and 150 mmHg")
if heart_rate < 30 or heart_rate > 200:
errors.append("Heart rate must be between 30 and 200 bpm")
return errors
def prepare_features_for_models(age, bp_systolic, bp_diastolic, heart_rate, cholesterol, glucose, bmi, symptoms):
"""Prepare feature arrays for different models based on their training requirements"""
# Heart Disease Model Features (adjust based on your model's training)
heart_features = np.array([[
age,
bp_systolic,
cholesterol,
heart_rate,
symptoms['chest_pain'],
symptoms['shortness_breath'],
symptoms['palpitations'],
bmi,
glucose
]])
# Diabetes Model Features
diabetes_features = np.array([[
age,
glucose,
bmi,
cholesterol,
symptoms['fatigue'],
symptoms['blurred_vision'],
bp_systolic,
heart_rate
]])
# Hypertension Model Features
hypertension_features = np.array([[
age,
bp_systolic,
bp_diastolic,
bmi,
symptoms['dizziness'],
symptoms['palpitations'],
heart_rate,
cholesterol
]])
return heart_features, diabetes_features, hypertension_features
def main():
# Load custom CSS
local_css()
init_session_state()
# Load models
with st.spinner("🔄 Loading AI models..."):
heart_model, diabetes_model, hypertension_model = load_models()
# Initialize processors
ocr_processor = OCRProcessor()
# Language selector in sidebar
with st.sidebar:
st.markdown("
🏥 AI-Priority OPD
",
unsafe_allow_html=True)
# Groq API Configuration
st.markdown("---")
st.subheader("API Configuration")
groq_api_key = st.text_input("Enter Groq API Key:", type="password",
help="Get your API key from https://console.groq.com")
if groq_api_key:
if st.session_state.groq_client is None:
st.session_state.groq_client = init_groq_client(groq_api_key)
if st.session_state.groq_client:
st.success("✅ Groq API connected successfully!")
chatbot = HealthcareChatbot(st.session_state.groq_client)
else:
st.warning("⚠️ Please enter Groq API key to enable chatbot")
chatbot = HealthcareChatbot(None)
language = st.radio(
"Select Language / زبان منتخب کریں",
["English", "Urdu"],
key="language_selector"
)
st.markdown("---")
if language == "English":
st.subheader("Quick Actions")
if st.button("🆕 New Patient Assessment", use_container_width=True):
st.session_state.patient_data = {}
st.session_state.risk_scores = {}
st.session_state.chat_history = []
st.rerun()
else:
st.subheader("فوری اقدامات")
if st.button("🆕 نیا مریض تشخیص", use_container_width=True):
st.session_state.patient_data = {}
st.session_state.risk_scores = {}
st.session_state.chat_history = []
st.rerun()
# Main header
if language == "English":
st.markdown('🏥 AI-Priority OPD System
', unsafe_allow_html=True)
st.markdown("### Smart Patient Triage and Priority Management for Pakistani Healthcare")
else:
st.markdown('🏥 AI-ترجیحی OPD سسٹم
', unsafe_allow_html=True)
st.markdown("### پاکستانی ہیلتھ کیئر کے لیے ذہین مریض کی درجہ بندی اور ترجیحی انتظام")
# Create tabs
if language == "English":
tab_names = ["Patient Assessment", "Prescription OCR", "Health Chatbot", "Analytics"]
else:
tab_names = ["مریض تشخیص", "نسخہ OCR", "ہیلتھ چیٹ بوٹ", "تجزیات"]
tab1, tab2, tab3, tab4 = st.tabs(tab_names)
with tab1:
# Patient Assessment Form
if language == "English":
st.header("👨⚕️ Patient Assessment & Risk Scoring")
else:
st.header("👨⚕️ مریض تشخیص اور خطرے کا اسکورنگ")
with st.form("patient_assessment_form"):
col1, col2 = st.columns(2)
with col1:
# Basic Information
if language == "English":
st.subheader("Personal Information")
name = st.text_input("Full Name", placeholder="Enter patient's full name")
age = st.number_input("Age", min_value=1, max_value=120, value=45,
help="Patient's age in years")
gender = st.selectbox("Gender", ["Male", "Female", "Other"])
contact = st.text_input("Contact Number", placeholder="03XX-XXXXXXX")
else:
st.subheader("ذاتی معلومات")
name = st.text_input("مکمل نام", placeholder="مریض کا مکمل نام درج کریں")
age = st.number_input("عمر", min_value=1, max_value=120, value=45,
help="مریض کی عمر سالوں میں")
gender = st.selectbox("جنس", ["مرد", "عورت", "دیگر"])
contact = st.text_input("رابطہ نمبر", placeholder="03XX-XXXXXXX")
with col2:
# Vital Signs
if language == "English":
st.subheader("Clinical Parameters")
bp_systolic = st.number_input("Blood Pressure (systolic)",
min_value=70, max_value=250, value=120,
help="Systolic blood pressure in mmHg")
bp_diastolic = st.number_input("Blood Pressure (diastolic)",
min_value=40, max_value=150, value=80,
help="Diastolic blood pressure in mmHg")
heart_rate = st.number_input("Heart Rate (bpm)",
min_value=30, max_value=200, value=72,
help="Heart beats per minute")
cholesterol = st.number_input("Cholesterol Level (mg/dL)",
min_value=100, max_value=400, value=180)
glucose = st.number_input("Blood Glucose (mg/dL)",
min_value=50, max_value=500, value=95)
bmi = st.slider("BMI", min_value=15.0, max_value=40.0, value=23.5, step=0.1)
else:
st.subheader("کلینیکل پیرامیٹرز")
bp_systolic = st.number_input("بلڈ پریشر (سسٹولک)",
min_value=70, max_value=250, value=120,
help="سسٹولک بلڈ پریشر mmHg میں")
bp_diastolic = st.number_input("بلڈ پریشر (ڈائیسٹولک)",
min_value=40, max_value=150, value=80,
help="ڈائیسٹولک بلڈ پریشر mmHg میں")
heart_rate = st.number_input("دل کی دھڑکن (bpm)",
min_value=30, max_value=200, value=72,
help="دل کی دھڑکن فی منٹ")
cholesterol = st.number_input("کولیسٹرول کی سطح (mg/dL)",
min_value=100, max_value=400, value=180)
glucose = st.number_input("خون میں گلوکوز (mg/dL)",
min_value=50, max_value=500, value=95)
bmi = st.slider("باڈی ماس انڈیکس", min_value=15.0, max_value=40.0, value=23.5, step=0.1)
# Symptoms Section
if language == "English":
st.subheader("Reported Symptoms")
col3, col4 = st.columns(2)
with col3:
chest_pain = st.checkbox("Chest Pain or Discomfort")
shortness_breath = st.checkbox("Shortness of Breath")
palpitations = st.checkbox("Heart Palpitations")
with col4:
fatigue = st.checkbox("Persistent Fatigue")
dizziness = st.checkbox("Dizziness or Lightheadedness")
blurred_vision = st.checkbox("Blurred Vision")
else:
st.subheader("رپورٹ کردہ علامات")
col3, col4 = st.columns(2)
with col3:
chest_pain = st.checkbox("سینے میں درد یا بے چینی")
shortness_breath = st.checkbox("سانس لینے میں دشواری")
palpitations = st.checkbox("دل کی دھڑکن میں اضافہ")
with col4:
fatigue = st.checkbox("مسلسل تھکاوٹ")
dizziness = st.checkbox("چکر آنا یا سر ہلکا محسوس ہونا")
blurred_vision = st.checkbox("دھندلا نظر آنا")
# Assessment Button
if language == "English":
assess_button = st.form_submit_button("🚀 Calculate Risk Score & Priority",
use_container_width=True)
else:
assess_button = st.form_submit_button("🚀 خطرے کا اسکور اور ترجیح معلوم کریں",
use_container_width=True)
if assess_button:
# Validate inputs
validation_errors = validate_patient_data(age, bp_systolic, bp_diastolic, heart_rate)
if validation_errors:
for error in validation_errors:
st.error(f"❌ {error}")
elif heart_model is None or diabetes_model is None or hypertension_model is None:
st.error("❌ AI models are not loaded properly. Please check model files.")
else:
try:
with st.spinner("🔍 Analyzing patient data and calculating risks..."):
# Prepare symptoms dictionary
symptoms_dict = {
'chest_pain': 1 if chest_pain else 0,
'shortness_breath': 1 if shortness_breath else 0,
'palpitations': 1 if palpitations else 0,
'fatigue': 1 if fatigue else 0,
'dizziness': 1 if dizziness else 0,
'blurred_vision': 1 if blurred_vision else 0
}
# Prepare features for each model
heart_features, diabetes_features, hypertension_features = prepare_features_for_models(
age, bp_systolic, bp_diastolic, heart_rate, cholesterol, glucose, bmi, symptoms_dict
)
# Get predictions from trained models
heart_risk_proba = heart_model.predict_proba(heart_features)[0][1]
diabetes_risk_proba = diabetes_model.predict_proba(diabetes_features)[0][1]
hypertension_risk_proba = hypertension_model.predict_proba(hypertension_features)[0][1]
# Apply symptom modifiers for clinical severity
if chest_pain:
heart_risk_proba = min(1.0, heart_risk_proba * 1.3)
if shortness_breath:
heart_risk_proba = min(1.0, heart_risk_proba * 1.2)
if fatigue:
diabetes_risk_proba = min(1.0, diabetes_risk_proba * 1.2)
if dizziness:
hypertension_risk_proba = min(1.0, hypertension_risk_proba * 1.3)
# Calculate integrated priority score
priority_score = calculate_priority_score(
heart_risk_proba, diabetes_risk_proba, hypertension_risk_proba
)
priority_level, recommendation, risk_class = get_priority_recommendation(
priority_score, language
)
# Store results
st.session_state.risk_scores = {
'heart': heart_risk_proba,
'diabetes': diabetes_risk_proba,
'hypertension': hypertension_risk_proba,
'priority': priority_score,
'recommendation': recommendation,
'level': priority_level
}
# Display results
st.markdown("---")
st.success("✅ Risk assessment completed successfully!")
# Risk Scores Visualization
if language == "English":
st.subheader("📊 Disease Risk Assessment")
else:
st.subheader("📊 بیماری کے خطرے کا اندازہ")
col5, col6, col7, col8 = st.columns(4)
risk_metrics = [
(heart_risk_proba, "Heart Disease", "❤️", "#FF6B6B"),
(diabetes_risk_proba, "Diabetes", "🩺", "#4ECDC4"),
(hypertension_risk_proba, "Hypertension", "💓", "#45B7D1"),
(priority_score, "Priority Score", "🎯", "#96CEB4")
]
for (value, title, emoji, color), col in zip(risk_metrics, [col5, col6, col7, col8]):
with col:
fig = go.Figure(go.Indicator(
mode = "gauge+number+delta",
value = value,
domain = {'x': [0, 1], 'y': [0, 1]},
title = {'text': f"{emoji} {title}", 'font': {'size': 14}},
gauge = {
'axis': {'range': [0, 1], 'tickwidth': 1},
'bar': {'color': color},
'steps': [
{'range': [0, 0.3], 'color': "lightgreen"},
{'range': [0.3, 0.7], 'color': "yellow"},
{'range': [0.7, 1], 'color': "red"}
],
'threshold': {
'line': {'color': "black", 'width': 4},
'thickness': 0.75,
'value': 0.7
}
}
))
fig.update_layout(height=250, margin=dict(l=10, r=10, t=50, b=10))
st.plotly_chart(fig, use_container_width=True)
# Priority Recommendation
st.markdown(f'', unsafe_allow_html=True)
if language == "English":
st.markdown(f"## 🎯 Clinical Priority Recommendation")
st.markdown(f"### {recommendation}")
st.markdown(f"**Overall Risk Score:** `{priority_score:.3f}`")
st.markdown(f"**Recommended Action:** `{priority_level.replace('_', ' ').title()}`")
# Additional clinical guidance
if priority_level == "EMERGENCY_CARE":
st.warning("🚨 **Immediate Action Required:** Patient should be directed to emergency department without delay.")
elif priority_level == "SAME_DAY_CONSULT":
st.info("ℹ️ **Urgent Consultation:** Schedule appointment within 24 hours.")
else:
st.success("✅ **Routine Care:** Schedule within regular appointment system.")
else:
st.markdown(f"## 🎯 کلینیکل ترجیحی سفارش")
st.markdown(f"### {recommendation}")
st.markdown(f"**کل خطرے کا اسکور:** `{priority_score:.3f}`")
st.markdown(f"**سفارش کردہ عمل:** `{priority_level.replace('_', ' ').title()}`")
if priority_level == "EMERGENCY_CARE":
st.warning("🚨 **فوری کارروائی ضروری:** مریض کو بغیر کسی تاخیر کے ایمرجنسی ڈیپارٹمنٹ بھیجا جائے۔")
elif priority_level == "SAME_DAY_CONSULT":
st.info("ℹ️ **فوری مشاورت:** 24 گھنٹے کے اندر اپائنٹمنٹ شیڈول کریں۔")
else:
st.success("✅ **روٹین کیئر:** معمول کی اپائنٹمنٹ سسٹم کے اندر شیڈول کریں۔")
st.markdown('
', unsafe_allow_html=True)
except Exception as e:
st.error(f"❌ Error in risk assessment: {str(e)}")
st.info("💡 Please ensure all model files are properly formatted and compatible.")
with tab2:
# Prescription OCR
if language == "English":
st.header("📄 Prescription OCR Analysis")
st.write("Upload a prescription image to extract medication information automatically")
else:
st.header("📄 نسخہ OCR تجزیہ")
st.write("دوائی کی معلومات خود بخود نکالنے کے لیے نسخہ کی تصویر اپ لوڈ کریں")
uploaded_file = st.file_uploader(
"Choose prescription image..." if language == "English" else "نسخہ تصویر منتخب کریں...",
type=['png', 'jpg', 'jpeg'],
help="Upload a clear image of the medical prescription"
)
if uploaded_file is not None:
# Display uploaded image
image = Image.open(uploaded_file)
st.image(image, caption="📷 Uploaded Prescription" if language == "English" else "📷 اپ لوڈ کردہ نسخہ",
use_column_width=True)
if st.button("🔍 Extract Text" if language == "English" else "🔍 متن نکالیں",
use_container_width=True):
with st.spinner("🔄 Processing prescription image..." if language == "English"
else "🔄 نسخہ تصویر پروسیس ہو رہی ہے..."):
extracted_text = ocr_processor.extract_text(image)
accuracy = ocr_processor.calculate_ocr_accuracy(extracted_text)
if extracted_text and "No text detected" not in extracted_text and "OCR Error" not in extracted_text:
st.success(f"✅ Text extraction completed! (Estimated Accuracy: {accuracy:.1f}%)")
if language == "English":
st.subheader("Extracted Medication Information:")
else:
st.subheader("نکالی گئی دوائی کی معلومات:")
# Display extracted text in expandable area
with st.expander("View Extracted Text" if language == "English" else "نکالا گیا متن دیکھیں", expanded=True):
st.text_area("", extracted_text, height=200, key="extracted_text")
# Basic medication analysis
if language == "English":
st.subheader("📋 Medication Analysis")
else:
st.subheader("📋 دوائی کا تجزیہ")
# Simple medication pattern detection
medications_detected = 0
if any(term in extracted_text.lower() for term in ['tablet', 'tab']):
medications_detected += 1
if any(term in extracted_text.lower() for term in ['mg', 'ml']):
medications_detected += 1
if any(term in extracted_text.lower() for term in ['daily', 'twice', 'thrice']):
medications_detected += 1
col_med1, col_med2 = st.columns(2)
with col_med1:
st.metric("Medications Detected", medications_detected)
with col_med2:
st.metric("OCR Confidence", f"{accuracy:.1f}%")
else:
st.error("❌ No text could be extracted from the image. Please try with a clearer image.")
if language == "English":
st.info("💡 Tips for better OCR results:\n- Use good lighting\n- Ensure clear focus\n- Avoid shadows\n- Straight angle photo")
else:
st.info("💡 بہتر OCR نتائج کے لیے نکات:\n- اچھی روشنی استعمال کریں\n- واضح فوکس یقینی بنائیں\n- سایوں سے پرہیز کریں\n- سیدھے زاویے کی تصویر")
with tab3:
# Healthcare Chatbot
if language == "English":
st.header("💬 Healthcare Assistant Chatbot")
st.write("Ask health-related questions and get personalized advice in English or Urdu")
else:
st.header("💬 ہیلتھ کیئر اسسٹنٹ چیٹ بوٹ")
st.write("صحت سے متعلق سوالات پوچھیں اور انگریزی یا اردو میں ذاتی مشورہ حاصل کریں")
if st.session_state.groq_client is None:
st.warning("⚠️ Please configure Groq API key in the sidebar to use the chatbot")
else:
# Display chat history
for message in st.session_state.chat_history:
with st.chat_message(message["role"]):
if message["role"] == "user":
st.markdown(message["content"])
else:
# Format bot response with better styling
st.markdown(f"**🤖 Healthcare Assistant:**\n\n{message['content']}")
# Chat input
if prompt := st.chat_input(
"Type your health question here..." if language == "English"
else "اپنا صحت کا سوال یہاں ٹائپ کریں..."
):
# Add user message to chat history
st.session_state.chat_history.append({"role": "user", "content": prompt})
# Generate bot response
with st.chat_message("assistant"):
with st.spinner("💭 Analyzing your question..." if language == "English" else "💭 آپ کا سوال تجزیہ ہو رہا ہے..."):
response = chatbot.get_response(prompt, language)
st.markdown(f"**🤖 Healthcare Assistant:**\n\n{response}")
# Add assistant response to chat history
st.session_state.chat_history.append({"role": "assistant", "content": response})
# Limit chat history to last 10 messages
if len(st.session_state.chat_history) > 10:
st.session_state.chat_history = st.session_state.chat_history[-10:]
# Quick action buttons
if language == "English":
st.subheader("Quick Health Topics")
else:
st.subheader("فوری صحت کے موضوعات")
col_qa1, col_qa2, col_qa3 = st.columns(3)
with col_qa1:
if st.button("❤️ Heart Health", use_container_width=True):
st.session_state.chat_history.append({
"role": "user",
"content": "Tell me about heart health and prevention tips"
})
st.rerun()
with col_qa2:
if st.button("🩺 Diabetes", use_container_width=True):
st.session_state.chat_history.append({
"role": "user",
"content": "What are the symptoms and management of diabetes?"
})
st.rerun()
with col_qa3:
if st.button("💓 Blood Pressure", use_container_width=True):
st.session_state.chat_history.append({
"role": "user",
"content": "How to control high blood pressure naturally?"
})
st.rerun()
with tab4:
# Analytics Dashboard
if language == "English":
st.header("📈 System Analytics & Performance")
else:
st.header("📈 سسٹم تجزیات اور کارکردگی")
# Real-time performance metrics based on actual usage
if 'risk_scores' in st.session_state and st.session_state.risk_scores:
recent_priority = st.session_state.risk_scores.get('priority', 0)
col9, col10, col11, col12 = st.columns(4)
with col9:
st.metric("Current Patient Priority", f"{recent_priority:.1%}")
with col10:
st.metric("Risk Assessment", "Completed")
with col11:
st.metric("Model Confidence", "High")
with col12:
st.metric("Processing Time", "< 2s")
else:
if language == "English":
st.info("👆 Complete a patient assessment to see analytics")
else:
st.info("👆 تجزیات دیکھنے کے لیے مریض کی تشخیص مکمل کریں")
# Analytics Charts
if 'risk_scores' in st.session_state and st.session_state.risk_scores:
col_chart1, col_chart2 = st.columns(2)
with col_chart1:
if language == "English":
st.subheader("Current Patient Risk Distribution")
else:
st.subheader("موجودہ مریض کے خطرے کی تقسیم")
risk_data = pd.DataFrame({
'Condition': ['Heart Disease', 'Diabetes', 'Hypertension'],
'Risk Score': [
st.session_state.risk_scores['heart'],
st.session_state.risk_scores['diabetes'],
st.session_state.risk_scores['hypertension']
]
})
fig = px.bar(risk_data, x='Condition', y='Risk Score',
color='Risk Score', color_continuous_scale='RdYlGn_r')
st.plotly_chart(fig, use_container_width=True)
with col_chart2:
if language == "English":
st.subheader("Priority Level")
else:
st.subheader("ترجیحی سطح")
priority_level = st.session_state.risk_scores['level']
priority_colors = {
'EMERGENCY_CARE': '#dc3545',
'SAME_DAY_CONSULT': '#ffc107',
'ROUTINE_APPOINTMENT': '#28a745'
}
fig = go.Figure(go.Indicator(
mode = "gauge+number",
value = st.session_state.risk_scores['priority'] * 100,
domain = {'x': [0, 1], 'y': [0, 1]},
title = {'text': "Priority Score"},
gauge = {
'axis': {'range': [0, 100]},
'bar': {'color': priority_colors.get(priority_level, '#2E86AB')},
'steps': [
{'range': [0, 55], 'color': "lightgray"},
{'range': [55, 75], 'color': "yellow"},
{'range': [75, 100], 'color': "red"}
]
}
))
fig.update_layout(height=300)
st.plotly_chart(fig, use_container_width=True)
if __name__ == "__main__":
main()