Diff of /Hospital_Streamlit.py [000000] .. [be5bcf]

Switch to unified view

a b/Hospital_Streamlit.py
1
import streamlit as st
2
import pandas as pd
3
import numpy as np
4
from datetime import datetime
5
import plotly.graph_objects as go
6
import plotly.express as px
7
from streamlit_autorefresh import st_autorefresh
8
import pickle
9
import os
10
from io import BytesIO
11
import pydicom
12
import cv2
13
import random
14
from ultralytics import YOLO
15
from plotly.subplots import make_subplots
16
17
# Load languages
18
def load_languages():
19
    return {
20
        'English': {
21
            'welcome': 'Welcome',
22
            'dashboard': 'Dashboard',
23
            'profile': 'Profile',
24
            'settings': 'Settings',
25
            'emergency': 'Emergency Contact',
26
            'about': 'About Us',
27
            'prediction': 'Patient Prediction',
28
            'analytics': 'Analytics'
29
        },
30
        'Spanish': {
31
            'welcome': 'Bienvenido',
32
            'dashboard': 'Tablero',
33
            'profile': 'Perfil',
34
            'settings': 'Ajustes',
35
            'emergency': 'Contacto de Emergencia',
36
            'about': 'Sobre Nosotros',
37
            'prediction': 'Predicción de Pacientes',
38
            'analytics': 'Análisis'
39
        },
40
        'French': {
41
            'welcome': 'Bienvenue',
42
            'dashboard': 'Tableau de Bord',
43
            'profile': 'Profil',
44
            'settings': 'Paramètres',
45
            'emergency': 'Contact d\'urgence',
46
            'about': 'À Propos',
47
            'prediction': 'Prédiction de Patients',
48
            'analytics': 'Analytique'
49
        }
50
    }
51
52
# Theme configurations
53
dark_theme = {
54
    'primary_color': '#4da6ff',
55
    'background_color': '#0e1117',
56
    'secondary_bg': '#262730',
57
    'text_color': '#fafafa',
58
    'font': 'sans-serif',
59
    'card_bg': '#1a1a1a',
60
    'success_color': '#2fd36e',
61
    'warning_color': '#ffd534',
62
    'danger_color': '#ff4961'
63
}
64
65
# 3D Scatter plot for visual appeal
66
def create_3d_scatter():
67
    x = np.random.randn(100)
68
    y = np.random.randn(100)
69
    z = np.random.randn(100)
70
    
71
    fig = go.Figure(data=[go.Scatter3d(
72
        x=x, y=y, z=z,
73
        mode='markers',
74
        marker=dict(
75
            size=5,
76
            color=z,
77
            colorscale='Viridis',
78
            opacity=0.8
79
        )
80
    )])
81
    
82
    fig.update_layout(
83
        scene=dict(
84
            xaxis_title='X',
85
            yaxis_title='Y',
86
            zaxis_title='Z',
87
            bgcolor='rgba(0,0,0,0)'
88
        ),
89
        margin=dict(r=0, b=0, l=0, t=0),
90
        paper_bgcolor='rgba(0,0,0,0)',
91
        plot_bgcolor='rgba(0,0,0,0)'
92
    )
93
    
94
    return fig
95
96
def create_dynamic_dashboard():
97
    st.title("Hospital Dashboard")
98
    
99
    st_autorefresh(interval=10000, key="dashboard_refresh")
100
    
101
    current_time = datetime.now()
102
    times = pd.date_range(end=current_time, periods=20, freq='1min')
103
    
104
    # 3D Scatter plot for visual appeal
105
    st.subheader("Hospital Activity Visualization")
106
    fig_3d = create_3d_scatter()
107
    st.plotly_chart(fig_3d, use_container_width=True)
108
    
109
    # Interactive metrics with hover effect
110
    col1, col2, col3 = st.columns(3)
111
    with col1:
112
        current_patients = np.random.randint(80, 120)
113
        st.metric("Current Patients", current_patients, delta=np.random.randint(-5, 5))
114
    with col2:
115
        bed_capacity = f"{np.random.randint(60, 90)}%"
116
        st.metric("Bed Capacity", bed_capacity, delta=f"{np.random.randint(-3, 3)}%")
117
    with col3:
118
        staff_on_duty = np.random.randint(40, 60)
119
        st.metric("Staff on Duty", staff_on_duty, delta=np.random.randint(-2, 2))
120
    
121
    # Interactive charts
122
    fig = make_subplots(rows=1, cols=2, subplot_titles=("Patient Flow (Last 20 minutes)", "Department Load (%)"))
123
    
124
    # Patient Flow
125
    fig.add_trace(
126
        go.Scatter(
127
            x=times,
128
            y=np.random.randint(50, 100, size=20),
129
            name="Admissions",
130
            mode='lines+markers',
131
            line=dict(color='#4da6ff', width=3),
132
            marker=dict(size=8, symbol='circle', line=dict(color='#ffffff', width=2))
133
        ),
134
        row=1, col=1
135
    )
136
    fig.add_trace(
137
        go.Scatter(
138
            x=times,
139
            y=np.random.randint(40, 90, size=20),
140
            name="Discharges",
141
            mode='lines+markers',
142
            line=dict(color='#ff4961', width=3),
143
            marker=dict(size=8, symbol='circle', line=dict(color='#ffffff', width=2))
144
        ),
145
        row=1, col=1
146
    )
147
    
148
    # Department Load
149
    departments = ['ER', 'ICU', 'Surgery', 'Pediatrics', 'General']
150
    values = np.random.randint(40, 100, size=len(departments))
151
    fig.add_trace(
152
        go.Bar(
153
            x=departments,
154
            y=values,
155
            marker_color='#4da6ff',
156
            hoverinfo='y',
157
            textposition='auto',
158
            textfont=dict(color='white'),
159
            hoverlabel=dict(bgcolor='#1a1a1a', font_size=14)
160
        ),
161
        row=1, col=2
162
    )
163
    
164
    fig.update_layout(
165
        height=500,
166
        showlegend=False,
167
        paper_bgcolor='rgba(0,0,0,0)',
168
        plot_bgcolor='rgba(0,0,0,0)',
169
        font=dict(color='#fafafa'),
170
        margin=dict(l=20, r=20, t=60, b=20),
171
    )
172
    fig.update_xaxes(showgrid=False, zeroline=False)
173
    fig.update_yaxes(showgrid=True, gridcolor='rgba(255,255,255,0.1)', zeroline=False)
174
    
175
    st.plotly_chart(fig, use_container_width=True)
176
    
177
    emergency_data = pd.DataFrame({
178
        'Time': times[-5:],
179
        'Type': np.random.choice(['Critical', 'Moderate', 'Minor'], size=5),
180
        'Department': np.random.choice(['ER', 'ICU', 'Surgery'], size=5),
181
        'Status': np.random.choice(['In Progress', 'Waiting', 'Completed'], size=5)
182
    })
183
    
184
    st.subheader("Recent Emergency Cases")
185
    st.dataframe(
186
        emergency_data.style
187
        .applymap(lambda x: f'color: {dark_theme["text_color"]}; background-color: {dark_theme["card_bg"]}')
188
        .set_properties(**{'background-color': dark_theme['card_bg'], 'color': dark_theme['text_color'], 'border-color': dark_theme['primary_color']})
189
        .highlight_max(axis=0, props='color: #ff4961; font-weight: bold;')
190
        .highlight_min(axis=0, props='color: #2fd36e; font-weight: bold;'),
191
        use_container_width=True
192
    )
193
194
def user_profile_section():
195
    st.title("User Profile")
196
    
197
    if 'user_profile' not in st.session_state:
198
        st.session_state.user_profile = {
199
            'name': '',
200
            'email': '',
201
            'phone': '',
202
            'department': '',
203
            'role': '',
204
            'profile_picture': None
205
        }
206
    
207
    col1, col2 = st.columns(2)
208
    
209
    with col1:
210
        st.session_state.user_profile['name'] = st.text_input("Full Name", st.session_state.user_profile['name'])
211
        st.session_state.user_profile['email'] = st.text_input("Email", st.session_state.user_profile['email'])
212
        st.session_state.user_profile['phone'] = st.text_input("Phone", st.session_state.user_profile['phone'])
213
        
214
    with col2:
215
        st.session_state.user_profile['department'] = st.selectbox(
216
            "Department",
217
            ["Cardiology", "Emergency", "Pediatrics", "Surgery", "Other"],
218
            index=0 if not st.session_state.user_profile['department'] else None
219
        )
220
        st.session_state.user_profile['role'] = st.selectbox(
221
            "Role",
222
            ["Doctor", "Nurse", "Administrator", "Other"],
223
            index=0 if not st.session_state.user_profile['role'] else None
224
        )
225
        uploaded_file = st.file_uploader("Upload Profile Picture", type=['jpg', 'png'])
226
        if uploaded_file is not None:
227
            st.session_state.user_profile['profile_picture'] = uploaded_file
228
            st.image(uploaded_file, width=150)
229
    
230
    if st.button("Save Profile"):
231
        st.success("Profile updated successfully!")
232
233
def emergency_contact_section():
234
    st.title("Emergency Contact")
235
    
236
    st.header("Emergency Department")
237
    col1, col2, col3 = st.columns(3)
238
    
239
    with col1:
240
        st.info("📞 Emergency Hotline\n\n1-800-HOSPITAL")
241
    with col2:
242
        st.info("🚑 Ambulance Service\n\n911")
243
    with col3:
244
        st.info("👨‍⚕️ On-call Doctor\n\n+1-555-0123")
245
    
246
    st.header("Contact Form")
247
    
248
    emergency_type = st.selectbox(
249
        "Emergency Type",
250
        ["Medical Emergency", "Fire Emergency", "Security Issue", "Other"]
251
    )
252
    
253
    description = st.text_area("Description of Emergency")
254
    location = st.text_input("Location in Hospital")
255
    
256
    if st.button("Submit Emergency Alert"):
257
        if description and location:
258
            st.success("Emergency alert submitted successfully!")
259
            st.info("Emergency response team has been notified.")
260
        else:
261
            st.error("Please fill in all required fields.")
262
263
def about_us_section():
264
    st.title("About Us")
265
    
266
    st.markdown("""
267
    ## Our Mission
268
    To provide exceptional healthcare services with compassion and innovation, 
269
    ensuring the best possible outcomes for our patients and communities.
270
    
271
    ## Our Vision
272
    To be the leading healthcare provider known for excellence in patient care, 
273
    medical research, and healthcare technology innovation.
274
    
275
    ## Our Values
276
    - **Excellence** in all aspects of healthcare
277
    - **Compassion** towards all patients
278
    - **Innovation** in medical practices
279
    - **Integrity** in our actions
280
    - **Teamwork** in our approach
281
    
282
    ## Hospital Statistics
283
    """)
284
    
285
    col1, col2, col3 = st.columns(3)
286
    
287
    with col1:
288
        st.metric("Years of Service", "50+")
289
    with col2:
290
        st.metric("Healthcare Professionals", "1000+")
291
    with col3:
292
        st.metric("Patients Served Annually", "50,000+")
293
    
294
    st.header("Our Departments")
295
    departments = [
296
        ("🫀 Cardiology", "Specialized heart care and treatment"),
297
        ("🧠 Neurology", "Expert neurological care"),
298
        ("👶 Pediatrics", "Comprehensive children's healthcare"),
299
        ("🏥 Emergency Care", "24/7 emergency services"),
300
        ("🔬 Research", "Cutting-edge medical research")
301
    ]
302
    
303
    for dept, desc in departments:
304
        st.subheader(dept)
305
        st.write(desc)
306
307
def prediction_page():
308
    st.title("Patient Readmission Prediction")
309
    
310
    col1, col2 = st.columns(2)
311
    
312
    with col1:
313
        gender = st.selectbox('Gender:', ["Female", "Male", "Other"])
314
        admission_type = st.selectbox('Admission Type:', ['Emergency', 'Urgent', 'Elective'])
315
        diagnosis = st.selectbox('Diagnosis:', ['Heart Disease', 'Diabetes', 'Injury', 'Infection'])
316
        lab_procedures = st.number_input('Number of Lab Procedures:', 1, 100, 1)
317
        medications = st.number_input('Number of Medications:', 1, 36, 1)
318
    
319
    with col2:
320
        outpatient_visits = st.number_input('Number of Outpatient Visits:', 0, 5, 0)
321
        inpatient_visits = st.number_input('Number of Inpatient Visits:', 0, 5, 0)
322
        emergency_visits = st.number_input('Number of Emergency Visits:', 0, 5, 0)
323
        num_diagnoses = st.number_input('Number of Diagnoses:', 1, 10, 1)
324
        a1c_result = st.selectbox('A1C Result:', ['Normal', 'Abnormal'])
325
    
326
    if st.button("Predict Readmission", key="predict_button"):
327
        gender_code = {"Female": 0, "Male": 1, "Other": 2}[gender]
328
        admission_code = {"Emergency": 1, "Urgent": 2, "Elective": 0}[admission_type]
329
        diagnosis_code = {"Heart Disease": 1, "Diabetes": 0, "Injury": 3, "Infection": 2}[diagnosis]
330
        a1c_code = {"Normal": 1, "Abnormal": 0}[a1c_result]
331
        
332
        input_data = np.array([[
333
            gender_code, admission_code, diagnosis_code, lab_procedures,
334
            medications, outpatient_visits, inpatient_visits,
335
            emergency_visits, num_diagnoses, a1c_code
336
        ]])
337
        
338
        try:
339
            model_path = os.path.join(os.path.dirname(__file__), "Readmission_Model.pkl")
340
            with open(model_path, "rb") as m:
341
                model = pickle.load(m)
342
            result = model.predict(input_data)[0]
343
            
344
            if result == 1:
345
                st.error("⚠️ High Risk: Readmission is Required")
346
                st.markdown("""
347
                    ### Recommended Actions:
348
                    1. Schedule follow-up appointment within 7 days
349
                    2. Review medication compliance
350
                    3. Coordinate with care management team
351
                """)
352
            else:
353
                st.success("✅ Low Risk: Readmission is Not Required")
354
                st.markdown("""
355
                    ### Recommended Actions:
356
                    1. Schedule routine follow-up within 30 days
357
                    2. Provide standard discharge instructions
358
                    3. Document any concerns for future reference
359
                """)
360
        except FileNotFoundError:
361
            st.error("Model file not found. Please ensure 'Readmission_Model.pkl' is in the correct directory.")
362
        except Exception as e:
363
            st.error(f"An error occurred during prediction: {str(e)}")
364
365
def analytics_page():
366
    st.title("Hospital Analytics Dashboard")
367
    
368
    time_period = st.selectbox(
369
        "Select Time Period",
370
        ["Last 24 Hours", "Last Week", "Last Month", "Last Year"]
371
    )
372
    
373
    if time_period == "Last 24 Hours":
374
        dates = pd.date_range(end=datetime.now(), periods=24, freq='H')
375
    elif time_period == "Last Week":
376
        dates = pd.date_range(end=datetime.now(), periods=7, freq='D')
377
    elif time_period == "Last Month":
378
        dates = pd.date_range(end=datetime.now(), periods=30, freq='D')
379
    else:
380
        dates = pd.date_range(end=datetime.now(), periods=12, freq='M')
381
    
382
    analytics_data = pd.DataFrame({
383
        'Date': dates,
384
        'Admissions': np.random.randint(50, 150, size=len(dates)),
385
        'Discharges': np.random.randint(40, 140, size=len(dates)),
386
        'Readmissions': np.random.randint(5, 30, size=len(dates)),
387
        'Average_Stay': np.random.uniform(2, 7, size=len(dates))
388
    })
389
    
390
    col1, col2, col3, col4 = st.columns(4)
391
    
392
    with col1:
393
        total_admissions = analytics_data['Admissions'].sum()
394
        st.metric("Total Admissions", f"{total_admissions:,}")
395
    
396
    with col2:
397
        avg_stay = analytics_data['Average_Stay'].mean()
398
        st.metric("Average Stay (days)", f"{avg_stay:.1f}")
399
    
400
    with col3:
401
        readmission_rate = (analytics_data['Readmissions'].sum() / total_admissions) * 100
402
        st.metric("Readmission Rate", f"{readmission_rate:.1f}%")
403
    
404
    with col4:
405
        bed_turnover = total_admissions / len(dates)
406
        st.metric("Daily Bed Turnover", f"{bed_turnover:.1f}")
407
    
408
    fig = make_subplots(rows=2, cols=2, subplot_titles=("Admissions vs Discharges Trend", "Readmission Trend", "Average Length of Stay Trend", "Department-wise Statistics"))
409
    
410
    # Admissions vs Discharges Trend
411
    fig.add_trace(go.Scatter(
412
        x=analytics_data['Date'],
413
        y=analytics_data['Admissions'],
414
        name="Admissions",
415
        line=dict(color='#4da6ff', width=3)
416
    ), row=1, col=1)
417
    fig.add_trace(go.Scatter(
418
        x=analytics_data['Date'],
419
        y=analytics_data['Discharges'],
420
        name="Discharges",
421
        line=dict(color='#ff4961', width=3)
422
    ), row=1, col=1)
423
    
424
    # Readmission Trend
425
    fig.add_trace(go.Scatter(
426
        x=analytics_data['Date'],
427
        y=analytics_data['Readmissions'],
428
        name="Readmissions",
429
        line=dict(color='#ffd534', width=3)
430
    ), row=1, col=2)
431
    
432
    # Average Length of Stay Trend
433
    fig.add_trace(go.Scatter(
434
        x=analytics_data['Date'],
435
        y=analytics_data['Average_Stay'],
436
        name="Average Stay",
437
        line=dict(color='#2fd36e', width=3)
438
    ), row=2, col=1)
439
    
440
    # Department-wise Statistics
441
    departments = ['Emergency', 'Surgery', 'Cardiology', 'Pediatrics', 'Neurology']
442
    occupancy_rates = np.random.uniform(60, 95, len(departments))
443
    fig.add_trace(go.Bar(
444
        x=departments,
445
        y=occupancy_rates,
446
        name="Occupancy Rate",
447
        marker_color='#4da6ff'
448
    ), row=2, col=2)
449
    
450
    fig.update_layout(
451
        height=800,
452
        showlegend=True,
453
        paper_bgcolor='rgba(0,0,0,0)',
454
        plot_bgcolor='rgba(0,0,0,0)',
455
        font=dict(color='#fafafa'),
456
        legend=dict(
457
            bgcolor='rgba(0,0,0,0)',
458
            bordercolor='rgba(0,0,0,0)'
459
        )
460
    )
461
    fig.update_xaxes(showgrid=False, zeroline=False)
462
    fig.update_yaxes(showgrid=True, gridcolor='rgba(255,255,255,0.1)', zeroline=False)
463
    
464
    st.plotly_chart(fig, use_container_width=True)
465
    
466
    st.subheader("Department-wise Statistics")
467
    dept_data = pd.DataFrame({
468
        'Department': departments,
469
        'Occupancy_Rate': occupancy_rates,
470
        'Avg_Stay': np.random.uniform(2, 8, len(departments)),
471
        'Patient_Satisfaction': np.random.uniform(75, 95, len(departments))
472
    })
473
    
474
    st.dataframe(
475
        dept_data.style.format({
476
            'Occupancy_Rate': '{:.2f}%',
477
            'Avg_Stay': '{:.2f}',
478
            'Patient_Satisfaction': '{:.2f}%'
479
        })
480
        .applymap(lambda x: f'color: {dark_theme["text_color"]}; background-color: {dark_theme["card_bg"]}')
481
        .set_properties(**{'background-color': dark_theme['card_bg'], 'color': dark_theme['text_color'], 'border-color': dark_theme['primary_color']})
482
        .highlight_max(axis=0, props='color: #2fd36e; font-weight: bold;')
483
        .highlight_min(axis=0, props='color: #ff4961; font-weight: bold;'),
484
        use_container_width=True
485
    )
486
487
def medical_image_analysis_page():
488
    st.title("Medical Image Analysis")
489
    
490
    # Disease details dictionary
491
    DISEASE_DETAILS = {
492
        'Aortic enlargement': {
493
            'description': 'Abnormal enlargement of the aorta',
494
            'precautions': [
495
                'Immediate cardiovascular consultation',
496
                'Regular blood pressure monitoring',
497
                'Avoid heavy lifting and strenuous activities'
498
            ],
499
            'admission': 'Immediate hospitalization if risk of rupture'
500
        },
501
        'Cardiomegaly': {
502
            'description': 'Abnormal enlargement of the heart',
503
            'precautions': [
504
                'Restrict physical activities',
505
                'Follow strict medication regimen',
506
                'Regular cardiac monitoring'
507
            ],
508
            'admission': 'Urgent cardiac care if symptoms are severe'
509
        },
510
        'Pneumothorax': {
511
            'description': 'Collapsed or partially collapsed lung',
512
            'precautions': [
513
                'Oxygen therapy',
514
                'Chest tube insertion may be required',
515
                'Complete bed rest'
516
            ],
517
            'admission': 'Immediate hospitalization'
518
        },
519
        'No finding': {
520
            'description': 'No significant medical conditions detected',
521
            'precautions': ['Regular health check-ups'],
522
            'admission': 'Not required'
523
        }
524
    }
525
    
526
    # Ensure uploads directory exists
527
    os.makedirs('uploads', exist_ok=True)
528
    
529
    # Load YOLO model
530
    MODEL_PATH = 'yolov8n.pt'
531
    model = YOLO(MODEL_PATH)
532
    
533
    # Disease classes
534
    CLASSES = [
535
        'Aortic enlargement', 'Atelectasis', 'Calcification', 'Cardiomegaly',
536
        'Consolidation', 'ILD', 'Infiltration', 'Lung Opacity', 'Nodule/Mass',
537
        'Other lesion', 'Pleural effusion', 'Pleural thickening', 'Pneumothorax',
538
        'Pulmonary fibrosis', 'No finding'
539
    ]
540
    
541
    st.markdown("### Upload Medical Image")
542
    uploaded_file = st.file_uploader(
543
        "Choose a medical image (DICOM, JPG, PNG)", 
544
        type=['dcm', 'dicom', 'jpg', 'png']
545
    )
546
    
547
    if uploaded_file is not None:
548
        # Save the uploaded file
549
        with open(os.path.join("uploads", uploaded_file.name), "wb") as f:
550
            f.write(uploaded_file.getbuffer())
551
        
552
        file_path = os.path.join("uploads", uploaded_file.name)
553
        
554
        try:
555
            # Read the image
556
            if uploaded_file.name.endswith('.dcm') or uploaded_file.name.endswith('.dicom'):
557
                dicom = pydicom.dcmread(file_path)
558
                img = dicom.pixel_array
559
            else:
560
                img = cv2.imread(file_path)
561
                img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
562
            
563
            # Normalize and convert to RGB
564
            img = (img / img.max() * 255).astype(np.uint8)
565
            img = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
566
            
567
            # Perform inference
568
            results = model(img)
569
            
570
            # Process results
571
            predictions = []
572
            for r in results:
573
                boxes = r.boxes.xyxy.cpu().numpy()
574
                confidences = r.boxes.conf.cpu().numpy()
575
                class_ids = r.boxes.cls.cpu().numpy().astype(int)
576
                
577
                for box, confidence, class_id in zip(boxes, confidences, class_ids):
578
                    x_min, y_min, x_max, y_max = box
579
                    predictions.append({
580
                        'class_name': CLASSES[class_id],
581
                        'confidence': float(confidence),
582
                        'box': {
583
                            'x_min': int(x_min),
584
                            'y_min': int(y_min),
585
                            'x_max': int(x_max),
586
                            'y_max': int(y_max)
587
                        }
588
                    })
589
            
590
            # If no findings, add a default prediction
591
            if not predictions:
592
                predictions.append({
593
                    'class_name': 'No finding',
594
                    'confidence': 1.0,
595
                    'box': {'x_min': 0, 'y_min': 0, 'x_max': 1, 'y_max': 1}
596
                })
597
            
598
            # Visualize results
599
            visualized_img = img.copy()
600
            for pred in predictions:
601
                color = [random.randint(0, 255) for _ in range(3)]
602
                visualized_img = draw_bbox(visualized_img, 
603
                                           [pred['box']['x_min'], pred['box']['y_min'], 
604
                                            pred['box']['x_max'], pred['box']['y_max']],
605
                                           pred['class_name'], 
606
                                           pred['confidence'],
607
                                           color)
608
            
609
            st.subheader("Analysis Results")
610
            
611
            # Create responsive layout
612
            col1, col2 = st.columns([2, 1])
613
            
614
            with col1:
615
                # Display image responsively
616
                st.image(visualized_img, use_column_width=True, caption="Analyzed Medical Image")
617
            
618
            with col2:
619
                # Detailed analysis report
620
                st.markdown("### Detected Conditions")
621
                
622
                # Check if predictions exist
623
                if not predictions:
624
                    st.info("No significant findings detected.")
625
                else:
626
                    for pred in predictions:
627
                        disease = pred['class_name']
628
                        confidence = pred['confidence']
629
                        
630
                        st.markdown(f"#### {disease}")
631
                        st.markdown(f"**Confidence:** {confidence:.2%}")
632
                        
633
                        # Retrieve disease details
634
                        if disease in DISEASE_DETAILS:
635
                            details = DISEASE_DETAILS[disease]
636
                            st.markdown(f"**Description:** {details['description']}")
637
                            
638
                            st.markdown("**Precautions:**")
639
                            for precaution in details['precautions']:
640
                                st.markdown(f"- {precaution}")
641
                            
642
                            st.markdown(f"**Hospital Admission:** {details['admission']}")
643
                        
644
                        st.markdown("---")
645
            
646
            # Clean up temporary file
647
            os.remove(file_path)
648
        
649
        except Exception as e:
650
            st.error(f"An error occurred during image analysis: {str(e)}")
651
652
def draw_bbox(image, box, label, confidence, color):   
653
    alpha = 0.1
654
    alpha_box = 0.4
655
    overlay_bbox = image.copy()
656
    overlay_text = image.copy()
657
    output = image.copy()
658
659
    text_width, text_height = cv2.getTextSize(label.upper(), cv2.FONT_HERSHEY_SIMPLEX, 0.6, 1)[0]
660
    cv2.rectangle(overlay_bbox, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), color, -1)
661
    cv2.addWeighted(overlay_bbox, alpha, output, 1 - alpha, 0, output)
662
    cv2.rectangle(overlay_text, (int(box[0]), int(box[1])-7-text_height), (int(box[0])+text_width+2, int(box[1])), (0, 0, 0), -1)
663
    cv2.addWeighted(overlay_text, alpha_box, output, 1 - alpha_box, 0, output)
664
    cv2.rectangle(output, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), color, 2)
665
    cv2.putText(output, label.upper(), (int(box[0]), int(box[1])-5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 1, cv2.LINE_AA)
666
    cv2.putText(output, f"{confidence:.2f}", (int(box[0]), int(box[3])+20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1, cv2.LINE_AA)
667
    return output
668
669
import google.generativeai as genai
670
from typing import List
671
from datetime import datetime
672
from fpdf import FPDF
673
import io
674
import PIL.Image
675
from gtts import gTTS
676
import base64
677
678
def chatbot_page():
679
    st.title("🏥 Hospital AI Assistant")
680
    st.write("Chat with our AI assistant for hospital-related queries and image analysis.")
681
682
    # Language settings in sidebar
683
    st.sidebar.title("Language Settings")
684
    language = st.sidebar.radio("Choose Response Language:", ["English", "Hindi", "Marathi"])
685
686
    # Configure Gemini API
687
    genai.configure(api_key=st.secrets["google"]["api_key"])
688
    
689
    # Initialize models
690
    text_model = genai.GenerativeModel('gemini-pro')
691
    vision_model = genai.GenerativeModel('gemini-pro-vision')
692
    
693
    if "chat_history" not in st.session_state:
694
        st.session_state.chat_history = []
695
        st.session_state.chat = text_model.start_chat(history=[])
696
697
    # Image upload section
698
    uploaded_image = st.file_uploader("📤 Upload an image for analysis", type=['jpg', 'jpeg', 'png'])
699
    
700
    if uploaded_image:
701
        # Save and display uploaded image
702
        image = PIL.Image.open(uploaded_image)
703
        st.image(image, caption="Uploaded Image", use_column_width=True)
704
        
705
        # Add image analysis button
706
        # if st.button("🔍 Analyze Image"):
707
        #     with st.spinner("Analyzing image..."):
708
        #         try:
709
        #             prompt = f"Analyze this medical image and describe what you see in {language.lower()}. If it's not a medical image, please provide a general description."
710
        #             response = vision_model.generate_content([prompt, image])
711
                    
712
        #             if response and hasattr(response, "text"):
713
        #                 analysis_text = response.text
714
        #                 st.session_state.chat_history.append({
715
        #                     "role": "assistant",
716
        #                     "content": analysis_text,
717
        #                     "type": "image_analysis"
718
        #                 })
719
                        
720
        #                 # Add text-to-speech option
721
        #                 st.write("#### 📢 Listen to the analysis:")
722
        #                 if st.button("🔊 Play Analysis"):
723
        #                     lang_code = 'hi' if language == "Hindi" else 'mr' if language == "Marathi" else 'en'
724
        #                     tts = gTTS(text=analysis_text, lang=lang_code)
725
        #                     audio = BytesIO()
726
        #                     tts.write_to_fp(audio)
727
        #                     audio.seek(0)
728
        #                     audio_base64 = base64.b64encode(audio.read()).decode()
729
        #                     audio_tag = f'<audio controls autoplay><source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3"></audio>'
730
        #                     st.markdown(audio_tag, unsafe_allow_html=True)
731
        #         except Exception as e:
732
        #             st.error(f"Error during image analysis: {str(e)}")
733
734
    # Display chat history
735
    for message in st.session_state.chat_history:
736
        with st.chat_message(message["role"]):
737
            st.write(message["content"])
738
            if message.get("type") == "image_analysis":
739
                # Add audio playback option for image analysis
740
                if st.button(f"🔊 Play Response", key=f"play_{len(st.session_state.chat_history)}"):
741
                    lang_code = 'hi' if language == "Hindi" else 'mr' if language == "Marathi" else 'en'
742
                    tts = gTTS(text=message["content"], lang=lang_code)
743
                    audio = BytesIO()
744
                    tts.write_to_fp(audio)
745
                    audio.seek(0)
746
                    audio_base64 = base64.b64encode(audio.read()).decode()
747
                    audio_tag = f'<audio controls autoplay><source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3"></audio>'
748
                    st.markdown(audio_tag, unsafe_allow_html=True)
749
750
    # Chat input
751
    if prompt := st.chat_input("Ask me anything about the hospital..."):
752
        st.session_state.chat_history.append({"role": "user", "content": prompt})
753
        with st.chat_message("user"):
754
            st.write(prompt)
755
        
756
        try:
757
            # Handle regular text queries
758
            response = text_model.generate_content([
759
                f"Respond in {language.lower()} to the following query: {prompt}"
760
            ])
761
            bot_response = response.text
762
            st.session_state.chat_history.append({
763
                "role": "assistant",
764
                "content": bot_response,
765
                "type": "text"
766
            })
767
            with st.chat_message("assistant"):
768
                st.write(bot_response)
769
                # Add audio option for text responses
770
                # if st.button("🔊 Play Response", key=f"play_text_{len(st.session_state.chat_history)}"):
771
                #     lang_code = 'hi' if language == "Hindi" else 'mr' if language == "Marathi" else 'en'
772
                #     tts = gTTS(text=bot_response, lang=lang_code)
773
                #     audio = BytesIO()
774
                #     tts.write_to_fp(audio)
775
                #     audio.seek(0)
776
                #     audio_base64 = base64.b64encode(audio.read()).decode()
777
                #     audio_tag = f'<audio controls autoplay><source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3"></audio>'
778
                #     st.markdown(audio_tag, unsafe_allow_html=True)
779
        except Exception as e:
780
            st.error(f"Error: {str(e)}")
781
    
782
    # Export options
783
    # st.sidebar.title("Chat Options")
784
    # if st.sidebar.button("🗑️ Clear Chat"):
785
    #     st.session_state.chat_history = []
786
    #     st.session_state.chat = text_model.start_chat(history=[])
787
    #     st.experimental_rerun()
788
    
789
    if st.sidebar.button("📥 Export Chat"):
790
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
791
        txt_content = ""
792
        for msg in st.session_state.chat_history:
793
            txt_content += f"{msg['role'].title()}: {msg['content']}\n\n"
794
        
795
        st.sidebar.download_button(
796
            "📄 Download Chat",
797
            data=txt_content,
798
            file_name=f"chat_export_{timestamp}.txt",
799
            mime="text/plain"
800
        )
801
802
    # Footer
803
    st.markdown("---")
804
    st.markdown("Made with ❤️ for Tatva-AI")
805
# Add chatbot to main navigation
806
import tensorflow as tf
807
from PIL import Image
808
809
# Add this function after the medical_image_analysis_page() function
810
def brain_tumor_detection_page():
811
    st.title("Brain Tumor Detection")
812
    
813
    def load_model_with_custom_objects(model_path):
814
        def custom_depthwise_conv2d(*args, **kwargs):
815
            if 'groups' in kwargs:
816
                del kwargs['groups']
817
            return tf.keras.layers.DepthwiseConv2D(*args, **kwargs)
818
        
819
        custom_objects = {
820
            'DepthwiseConv2D': custom_depthwise_conv2d,
821
            'tf': tf
822
        }
823
        
824
        try:
825
            model = tf.keras.models.load_model(
826
                model_path, 
827
                custom_objects=custom_objects,
828
                compile=False
829
            )
830
            return model
831
        except Exception as e:
832
            st.error(f"Model loading failed: {e}")
833
            return None
834
835
    def preprocess_image(image):
836
        image = image.convert("RGB")
837
        image = image.resize((224, 224))
838
        image_array = np.array(image) / 255.0
839
        image_array = np.expand_dims(image_array, axis=0)
840
        return image_array
841
842
    model_path = 'models/keras_model.h5'
843
    model = load_model_with_custom_objects(model_path)
844
    
845
    if model is None:
846
        st.error("Could not load the model.")
847
        return
848
    
849
    uploaded_file = st.file_uploader("Upload brain scan image", type=['jpg', 'png', 'jpeg'])
850
    
851
    if uploaded_file is not None:
852
        image = Image.open(uploaded_file)
853
        st.image(image, caption="Uploaded Scan", use_column_width=True)
854
        
855
        try:
856
            processed_image = preprocess_image(image)
857
            predictions = model.predict(processed_image)
858
            
859
            CLASS_LABELS = ["Pituitary", "No Tumor", "Meningioma", "Glioma"]
860
            
861
            st.subheader("Prediction Results:")
862
            for label, prob in zip(CLASS_LABELS, predictions[0]):
863
                st.progress(float(prob))
864
                st.write(f"{label}: {prob*100:.2f}%")
865
            
866
            predicted_class = CLASS_LABELS[np.argmax(predictions)]
867
            st.success(f"Predicted Condition: {predicted_class}")
868
            
869
        except Exception as e:
870
            st.error(f"Analysis failed: {e}")
871
872
873
def main():
874
    st.set_page_config(
875
        page_title="Hospital Management System",
876
        layout="wide",
877
        initial_sidebar_state="expanded"
878
    )
879
    
880
    if 'language' not in st.session_state:
881
        st.session_state.language = 'English'
882
    
883
    languages = load_languages()
884
    
885
    # Sidebar Navigation
886
    with st.sidebar:
887
        st.markdown("<h2 style=' color: #4da6ff;'>Tatva AI</h2>", unsafe_allow_html=True)
888
889
        st.image("logo.jpeg", width=100)
890
        
891
        if 'user_profile' in st.session_state and st.session_state.user_profile['name']:
892
            st.write(f"Welcome, {st.session_state.user_profile['name']}")
893
            if st.session_state.user_profile['profile_picture']:
894
                st.image(st.session_state.user_profile['profile_picture'], width=100)
895
        
896
        # Navigation menu
897
        menu_options = [
898
            "Dashboard", 
899
            "Patient Prediction", 
900
            "Analytics", 
901
            "Brain Tumor Detection",
902
            "Medical Image Analysis",
903
            "User Profile", 
904
            "Emergency Contact", 
905
            "About Us", 
906
            "Settings",
907
            "Chatbot" 
908
        ]
909
        
910
        selected_page = st.selectbox(
911
            languages[st.session_state.language]['welcome'],
912
            menu_options
913
        )
914
    
915
     
916
    if selected_page == "Chatbot":
917
        chatbot_page()
918
    # Page rendering based on selection
919
    if selected_page == "Dashboard":
920
        create_dynamic_dashboard()
921
    elif selected_page == "Patient Prediction":
922
        prediction_page()
923
    elif selected_page == "Brain Tumor Detection":
924
        brain_tumor_detection_page()
925
    elif selected_page == "Analytics":
926
        analytics_page()
927
    elif selected_page == "Medical Image Analysis":
928
        medical_image_analysis_page()
929
    elif selected_page == "User Profile":
930
        user_profile_section()
931
    elif selected_page == "Emergency Contact":
932
        emergency_contact_section()
933
    elif selected_page == "About Us":
934
        about_us_section()
935
    elif selected_page == "Settings":
936
        st.title("Settings")
937
        
938
        st.subheader("Language Settings")
939
        new_language = st.selectbox(
940
            "Select Language",
941
            list(languages.keys()),
942
            index=list(languages.keys()).index(st.session_state.language)
943
        )
944
        if new_language != st.session_state.language:
945
            st.session_state.language = new_language
946
            st.experimental_rerun()
947
        
948
        st.subheader("Theme Settings")
949
        theme = st.selectbox(
950
            "Choose Theme",
951
            ["Dark"]
952
        )
953
        
954
        current_theme = dark_theme
955
        st.markdown(f"""
956
            <style>
957
            :root {{
958
                --primary-color: {current_theme['primary_color']};
959
                --background-color: {current_theme['background_color']};
960
                --secondary-bg: {current_theme['secondary_bg']};
961
                --text-color: {current_theme['text_color']};
962
                --font: {current_theme['font']};
963
                --card-bg: {current_theme['card_bg']};
964
                --success-color: {current_theme['success_color']};
965
                --warning-color: {current_theme['warning_color']};
966
                --danger-color: {current_theme['danger_color']};
967
            }}
968
            </style>
969
        """, unsafe_allow_html=True)
970
971
    # Add 3D effect and continuous movement
972
    st.markdown("""
973
    <script>
974
    const cursor = document.createElement('div');
975
    cursor.className = 'custom-cursor';
976
    document.body.appendChild(cursor);
977
978
    document.addEventListener('mousemove', (e) => {
979
        cursor.style.left = e.clientX + 'px';
980
        cursor.style.top = e.clientY + 'px';
981
        
982
        const elements = document.querySelectorAll('.stPlotlyChart, .stDataFrame, .stMetric');
983
        elements.forEach(el => {
984
            const rect = el.getBoundingClientRect();
985
            const x = (e.clientX - rect.left) / rect.width - 0.5;
986
            const y = (e.clientY - rect.top) / rect.height - 0.5;
987
            el.style.transform = `perspective(1000px) rotateY(${x * 5}deg) rotateX(${-y * 5}deg)`;
988
        });
989
    });
990
    </script>
991
    <style>
992
    .custom-cursor {
993
        width: 20px;
994
        height: 20px;
995
        border: 2px solid #ffffff;
996
        border-radius: 50%;
997
        position: fixed;
998
        pointer-events: none;
999
        z-index: 9999;
1000
        mix-blend-mode: difference;
1001
    }
1002
    .stPlotlyChart, .stDataFrame, .stMetric {
1003
        transition: transform 0.1s ease;
1004
    }
1005
    .stMetric {
1006
        background: linear-gradient(145deg, rgba(26,26,26,0.6) 0%, rgba(26,26,26,0.8) 100%);
1007
        border-radius: 10px;
1008
        padding: 10px;
1009
        box-shadow: 0 4px 6px rgba(0,0,0,0.1);
1010
    }
1011
    .stMetric:hover {
1012
        background: linear-gradient(145deg, rgba(26,26,26,0.8) 0%, rgba(26,26,26,1) 100%);
1013
    }
1014
    </style>
1015
    """, unsafe_allow_html=True)
1016
1017
if __name__ == "__main__":
1018
    main()