sikeaditya commited on
Commit
164ae98
Β·
verified Β·
1 Parent(s): bfc2bc2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +218 -0
app.py ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from google import genai
3
+ from PIL import Image
4
+ import os
5
+ from typing import Tuple, Optional
6
+ import logging
7
+
8
+ # Configure logging
9
+ logging.basicConfig(level=logging.INFO)
10
+ logger = logging.getLogger(__name__)
11
+
12
+ class MRIScanAnalyzer:
13
+ def __init__(self, api_key: str):
14
+ """Initialize the MRI Scan Analyzer with API key and configuration."""
15
+ self.client = genai.Client(api_key=api_key)
16
+ self.setup_page_config()
17
+ self.apply_custom_styles()
18
+
19
+ @staticmethod
20
+ def setup_page_config() -> None:
21
+ """Configure Streamlit page settings."""
22
+ st.set_page_config(
23
+ page_title="MRI Scan Analytics",
24
+ page_icon="🧠",
25
+ layout="wide"
26
+ )
27
+
28
+ @staticmethod
29
+ def apply_custom_styles() -> None:
30
+ """Apply custom CSS styles with improved dark theme."""
31
+ st.markdown("""
32
+ <style>
33
+ :root {
34
+ --background-color: #1a1a1a;
35
+ --secondary-bg: #2d2d2d;
36
+ --text-color: #e0e0e0;
37
+ --accent-color: #4CAF50;
38
+ --border-color: #404040;
39
+ --hover-color: #45a049;
40
+ }
41
+ .main { background-color: var(--background-color); }
42
+ .stApp { background-color: var(--background-color); }
43
+
44
+ .stButton>button {
45
+ width: 100%;
46
+ background-color: var(--accent-color);
47
+ color: white;
48
+ padding: 0.75rem;
49
+ border-radius: 6px;
50
+ border: none;
51
+ font-weight: 600;
52
+ transition: background-color 0.3s ease;
53
+ }
54
+ .stButton>button:hover {
55
+ background-color: var(--hover-color);
56
+ }
57
+
58
+ .report-container {
59
+ background-color: var(--secondary-bg);
60
+ padding: 2rem;
61
+ border-radius: 12px;
62
+ margin: 1rem 0;
63
+ border: 1px solid var(--border-color);
64
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
65
+ }
66
+ </style>
67
+ """, unsafe_allow_html=True)
68
+
69
+ def analyze_image(self, img: Image.Image) -> Tuple[Optional[str], Optional[str]]:
70
+ """
71
+ Analyze MRI scan image using Gemini AI.
72
+ Returns a tuple of (doctor_analysis, patient_analysis).
73
+ """
74
+ try:
75
+ prompts = {
76
+ "doctor": """
77
+ Provide a structured analysis of this MRI scan for medical professionals without including any introductory or acknowledgment phrases.
78
+ Follow the structure below:
79
+
80
+ 1. Imaging Observations
81
+ - Describe key anatomical structures, signal intensities, and any contrast differences
82
+
83
+ 2. Diagnostic Findings
84
+ - Identify abnormalities and potential areas of concern
85
+
86
+ 3. Clinical Correlation
87
+ - Suggest possible differential diagnoses and recommendations for further evaluation
88
+
89
+ 4. Technical Quality
90
+ - Comment on image quality, positioning, and any artifacts present
91
+ """,
92
+ "patient": """
93
+ Explain the findings of this MRI scan in clear, simple terms for a patient without including any introductory or acknowledgment phrases.
94
+ Follow the structure below:
95
+
96
+ 1. What We See
97
+ - Describe the part of the body shown and any notable features in everyday language
98
+
99
+ 2. What It Means
100
+ - Provide a simple explanation of the findings and their potential implications
101
+
102
+ 3. Next Steps
103
+ - Outline any recommendations or follow-up actions in a patient-friendly manner
104
+ """
105
+ }
106
+
107
+ responses = {}
108
+ for audience, prompt in prompts.items():
109
+ response = self.client.models.generate_content(
110
+ model="gemini-2.0-flash",
111
+ contents=[prompt, img]
112
+ )
113
+ responses[audience] = response.text if hasattr(response, 'text') else None
114
+
115
+ return responses["doctor"], responses["patient"]
116
+
117
+ except Exception as e:
118
+ logger.error(f"Analysis failed: {str(e)}")
119
+ return None, None
120
+
121
+ def run(self):
122
+ """Run the Streamlit MRI scan analysis application."""
123
+ st.title("🧠 MRI Scan Analytics")
124
+ st.markdown("""
125
+ Advanced MRI scan analysis powered by AI. Upload your scan for instant
126
+ insights tailored for both medical professionals and patients.
127
+ """)
128
+
129
+ col1, col2 = st.columns([1, 1.5])
130
+ with col1:
131
+ uploaded_file = self.handle_file_upload()
132
+ with col2:
133
+ if uploaded_file:
134
+ self.process_analysis(uploaded_file)
135
+ else:
136
+ self.show_instructions()
137
+
138
+ self.show_footer()
139
+
140
+ def handle_file_upload(self) -> Optional[object]:
141
+ """Handle file upload and display image preview."""
142
+ uploaded_file = st.file_uploader(
143
+ "Upload MRI Scan Image",
144
+ type=["png", "jpg", "jpeg"],
145
+ help="Supported formats: PNG, JPG, JPEG"
146
+ )
147
+
148
+ if uploaded_file:
149
+ img = Image.open(uploaded_file)
150
+ st.image(img, caption="Uploaded MRI Scan", use_container_width =True)
151
+
152
+ with st.expander("Image Details"):
153
+ st.write(f"**Filename:** {uploaded_file.name}")
154
+ st.write(f"**Size:** {uploaded_file.size/1024:.2f} KB")
155
+ st.write(f"**Format:** {img.format}")
156
+ st.write(f"**Dimensions:** {img.size[0]}x{img.size[1]} pixels")
157
+
158
+ return uploaded_file
159
+
160
+ def process_analysis(self, uploaded_file: object) -> None:
161
+ """Process the uploaded MRI image and display analysis."""
162
+ if st.button("πŸ” Analyze MRI Scan", key="analyze_button"):
163
+ with st.spinner("Analyzing MRI scan..."):
164
+ img = Image.open(uploaded_file)
165
+ doctor_analysis, patient_analysis = self.analyze_image(img)
166
+
167
+ if doctor_analysis and patient_analysis:
168
+ tab1, tab2 = st.tabs(["πŸ“‹ Medical Report", "πŸ‘₯ Patient Summary"])
169
+
170
+ with tab1:
171
+ st.markdown("### Medical Professional's Report")
172
+ st.markdown(f"<div class='report-container'>{doctor_analysis}</div>",
173
+ unsafe_allow_html=True)
174
+
175
+ with tab2:
176
+ st.markdown("### Patient-Friendly Explanation")
177
+ st.markdown(f"<div class='report-container'>{patient_analysis}</div>",
178
+ unsafe_allow_html=True)
179
+ else:
180
+ st.error("Analysis failed. Please try again.")
181
+
182
+ @staticmethod
183
+ def show_instructions() -> None:
184
+ """Display instructions when no image is uploaded."""
185
+ st.info("πŸ‘ˆ Upload an MRI scan image to begin analysis")
186
+
187
+ with st.expander("ℹ️ How it works"):
188
+ st.markdown("""
189
+ 1. **Upload** your MRI scan image
190
+ 2. Click **Analyze**
191
+ 3. Receive two detailed reports:
192
+ - Technical analysis for medical professionals
193
+ - Patient-friendly explanation
194
+ """)
195
+
196
+ @staticmethod
197
+ def show_footer() -> None:
198
+ """Display the application footer."""
199
+ st.markdown("---")
200
+ st.markdown(
201
+ """
202
+ <div style='text-align: center'>
203
+ <p style='color: #888888; font-size: 0.8em;'>
204
+ UNDER DEVELOPMENT
205
+ </p>
206
+ </div>
207
+ """,
208
+ unsafe_allow_html=True
209
+ )
210
+
211
+ if __name__ == "__main__":
212
+ # Get API key from environment variable or set directly here
213
+ api_key = os.getenv("GEMINI_API_KEY")
214
+ if not api_key:
215
+ st.error("Please set GEMINI_API_KEY environment variable")
216
+ else:
217
+ analyzer = MRIScanAnalyzer(api_key)
218
+ analyzer.run()