DjPapzin commited on
Commit
9aeb50f
·
1 Parent(s): e979b3c

Initial commit of healthcare AI dashboard

Browse files
.env.example ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ AI71_API_KEY= # Get at https://marketplace.ai71.ai/api-keys
2
+ ROBOFLOW_API_KEY= # Get at https://app.roboflow.com/
3
+
4
+ INFERENCE_API_URL=
5
+ INFERENCE_API_KEY=
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ FINAL_MODEL.keras filter=lfs diff=lfs merge=lfs -text
37
+ FINAL_MODEL.zip filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.pyc
2
+ __pycache__/
3
+ db.sqlite3
4
+ .env
5
+ .conda/
6
+ .venv/
7
+ .vscode/
8
+
9
+ backend/.hc_backend
10
+ backend/api/migrations/*
11
+
12
+ frontend/.hc_frontend
13
+ .aider*
14
+ frontend/.streamlit/secrets.toml
.streamlit/secrets.toml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ INFERENCE_API_URL = "https://detect.roboflow.com"
2
+ INFERENCE_API_KEY = "LSbJ0tl3WTLn4Aqar0Sp"
3
+ AI71_API_KEY = "api71-api-1a7b704d-f950-4507-95cc-c26ce3457d75"
FINAL_MODEL.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dff0eafd711bccd941d3cca9bff29202c4b4e40a4ef2d814986137d997ccfd13
3
+ size 228465191
FINAL_MODEL.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f52580d34f88e9e82e55de047acdbf8df2ed2e8c3caf54240d1dac4e8fcbc7f3
3
+ size 185936347
LICENSE.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) [2024] [Rust Rover]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
PROJECT_OVERVIEW.md ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Project Overview - Medi Scape
2
+ Medi Scape is a healthcare application that allows users to upload prescription images, which are then processed to extract and analyze the text. The key components include image processing, text recognition, and context understanding using machine learning models.
3
+
4
+ ### Workflow Steps
5
+
6
+ 1. **User Uploads Prescription Image**
7
+ - **Frontend**: User uploads an image via the Streamlit app.
8
+ - **Action**: The image is sent to the backend for processing.
9
+
10
+ 2. **Backend Receives Image**
11
+ - **Backend**: The Django server receives the uploaded image.
12
+ - **Action**: The backend calls the Doctor's Handwriting Detection API to detect handwriting.
13
+
14
+ 3. **Doctor's Handwriting Detection API**
15
+ - **API**: The uploaded image is processed to detect bounding boxes and classify the handwritten text.
16
+ - **Action**: The API returns the bounding boxes and classified text to the backend.
17
+
18
+ 4. **Backend Calls OCR Model**
19
+ - **Backend**: Extract bounding boxes and classes from the API response.
20
+ - **Action**: Send the bounding boxes to an OCR model to convert the handwriting to text.
21
+
22
+ 5. **Backend Processes OCR Text**
23
+ - **Backend**: The OCR model returns the detected text.
24
+ - **Action**: Send the detected text to the Falcon LLM model via the AI71 API for context understanding.
25
+
26
+ 6. **Falcon LLM Model via AI71 API**
27
+ - **API**: The detected text is processed for context understanding by the Falcon LLM model.
28
+ - **Action**: The processed text is returned to the backend.
29
+
30
+ 7. **Backend Sends Final Results to Frontend**
31
+ - **Backend**: The final processed text received from the AI71 API.
32
+ - **Action**: Send the final results back to the frontend (Streamlit app) for user display.
33
+
34
+ ### Checklist / To-Do List
35
+
36
+ 1. **Frontend Development**:
37
+ - [x] Implement image upload functionality in the Streamlit app.
38
+ - [x] Ensure the image is correctly sent to the backend.
39
+
40
+ 2. **Backend Development**:
41
+ - [x] Set up Django server to receive and handle uploaded images.
42
+ - [x] Integrate Doctor's Handwriting Detection API to process the images.
43
+ - [x] Extract bounding boxes and classes from the API response.
44
+ - [x] Integrate OCR model to convert bounding boxes to text.
45
+ - [x] Process the OCR text using the Falcon LLM model via AI71 API.
46
+ - [x] Send the final processed text to the frontend.
47
+
48
+ 3. **API Integration**:
49
+ - [x] Ensure proper integration of the Doctor's Handwriting Detection API.
50
+ - [x] Ensure proper integration of the Falcon LLM model via AI71 API.
51
+ - [x] Implement fallback solutions (like iframes) for Streamlit if API integration fails.
52
+
53
+ 4. **Deployment**:
54
+ - [x] Deploy the handwriting classification API on HuggingFace.
55
+ - [x] Deploy the Streamlit app and ensure it is linked correctly with the backend.
56
+ - [x] Hide the HuggingFace name in the deployed interface for security reasons.
57
+
58
+ 5. **Testing and Validation**:
59
+ - [x] Test the entire workflow from image upload to final text display.
60
+ - [x] Validate the accuracy of the handwriting detection and OCR models.
61
+ - [x] Ensure the Falcon LLM model provides accurate and contextually relevant text analysis.
62
+
63
+ 6. **Documentation and Communication**:
64
+ - [x] Document the workflow and API integration steps.
65
+ - [x] Communicate with the team leader for the exact prompt required for the healthcare automation part.
66
+ - [x] Keep the team updated on progress and any issues encountered.
67
+
68
+ 7. **Deadline Management**:
69
+ - [x] Ensure all tasks are completed by the deadline (August 6).
70
+
app.py ADDED
@@ -0,0 +1,505 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ from utils.ai71_utils import get_ai71_response
4
+ from datetime import datetime
5
+ import cv2
6
+ import numpy as np
7
+ from PIL import Image
8
+ import supervision as sv
9
+ import matplotlib.pyplot as plt
10
+ import io
11
+ import os
12
+ from inference_sdk import InferenceHTTPClient
13
+ from bs4 import BeautifulSoup
14
+ import tensorflow as tf
15
+ import pandas as pd
16
+ from sklearn.feature_extraction.text import CountVectorizer
17
+ from sklearn.model_selection import train_test_split
18
+ from sklearn.linear_model import LogisticRegression
19
+ from sklearn.metrics import accuracy_score, classification_report
20
+ import nltk
21
+ import re
22
+ from nltk.tokenize import word_tokenize
23
+ from nltk.corpus import stopwords
24
+
25
+ # Download NLTK data (only needs to be done once)
26
+ nltk.download('punkt')
27
+ nltk.download('stopwords')
28
+ nltk.download('wordnet')
29
+
30
+ # --- Preprocess text function (moved outside session state) ---
31
+ def preprocess_text(text):
32
+ # Convert to lowercase
33
+ text = text.lower()
34
+
35
+ cleaned_text = re.sub(r'[^a-zA-Z0-9\s\,]', ' ', text)
36
+ # Tokenize text
37
+ tokens = word_tokenize(cleaned_text)
38
+
39
+ # Remove stop words
40
+ stop_words = set(stopwords.words('english'))
41
+ tokens = [word for word in tokens if word not in stop_words]
42
+
43
+ # Rejoin tokens into a single string
44
+ cleaned_text = ' '.join(tokens)
45
+
46
+ return cleaned_text
47
+
48
+ st.title("Medi Scape Dashboard")
49
+
50
+ # --- Session State Initialization ---
51
+ if 'disease_model' not in st.session_state:
52
+ try:
53
+ model_path = 'FINAL_MODEL.zip'
54
+ print(f"Attempting to load disease model from: {model_path}")
55
+ print(f"Model file exists: {os.path.exists(model_path)}")
56
+ st.session_state.disease_model = tf.keras.models.load_model(model_path)
57
+ print("Disease model loaded successfully!")
58
+ except FileNotFoundError:
59
+ st.error("Disease classification model not found. Please ensure 'FINAL_MODEL.zip' is in the same directory as this app.")
60
+ st.session_state.disease_model = None
61
+
62
+ # Load the vectorizer
63
+ if 'vectorizer' not in st.session_state:
64
+ try:
65
+ vectorizer_path = "vectorizer.pkl"
66
+ print(f"Attempting to load vectorizer from: {vectorizer_path}")
67
+ print(f"Vectorizer file exists: {os.path.exists(vectorizer_path)}")
68
+ st.session_state.vectorizer = pd.read_pickle(vectorizer_path)
69
+ print("Vectorizer loaded successfully!")
70
+ except FileNotFoundError:
71
+ st.error("Vectorizer file not found. Please ensure 'vectorizer.pkl' is in the same directory as this app.")
72
+ st.session_state.vectorizer = None
73
+
74
+ if 'model_llm' not in st.session_state:
75
+ # --- Load pre-trained model and vectorizer ---
76
+ st.session_state.model_llm = LogisticRegression()
77
+ try:
78
+ llm_model_path = "logistic_regression_model.pkl"
79
+ print(f"Attempting to load LLM model from: {llm_model_path}")
80
+ print(f"LLM Model file exists: {os.path.exists(llm_model_path)}")
81
+ st.session_state.model_llm = pd.read_pickle(llm_model_path)
82
+ print("LLM model loaded successfully!")
83
+ except FileNotFoundError:
84
+ st.error("LLM model file not found. Please ensure 'logistic_regression_model.pkl' is in the same directory.")
85
+ st.session_state.model_llm = None
86
+
87
+ # Load datasets (only for reference, not used for training)
88
+ dataset_1 = pd.read_csv("Symptoms_Detection/training_data.csv")
89
+ dataset_2 = pd.read_csv("Symptoms_Detection/Symptom2Disease.csv")
90
+
91
+ # Create symptoms_text column (only for reference, not used for training)
92
+ dataset_1['symptoms_text'] = dataset_1.apply(lambda row: ','.join([col for col in dataset_1.columns if row[col] == 1]), axis=1)
93
+ final_dataset = pd.DataFrame(dataset_1[["prognosis", "symptoms_text"]])
94
+ final_dataset.columns = ['label', 'text']
95
+
96
+ # Combine datasets (only for reference, not used for training)
97
+ df_combined = pd.concat([final_dataset, dataset_2[['label', 'text']]], axis=0, ignore_index=True)
98
+
99
+ # Store in session state (only for reference, not used for training)
100
+ st.session_state.df_combined = df_combined
101
+ # --- End of Session State Initialization ---
102
+
103
+ # Load the disease classification model
104
+ try:
105
+ disease_model = tf.keras.models.load_model('FINAL_MODEL.zip')
106
+ except FileNotFoundError:
107
+ st.error("Disease classification model not found. Please ensure 'FINAL_MODEL.zip' is in the same directory as this app.")
108
+ disease_model = None
109
+
110
+ # Sidebar Navigation
111
+ st.sidebar.title("Navigation")
112
+ page = st.sidebar.radio("Go to", ["Home", "AI Chatbot Diagnosis", "Drug Identification", "Disease Detection", "Outbreak Alert"])
113
+
114
+ # Access secrets using st.secrets
115
+ if "INFERENCE_API_URL" not in st.secrets or "INFERENCE_API_KEY" not in st.secrets:
116
+ st.error("Please make sure to set your secrets in the Streamlit secrets settings.")
117
+ else:
118
+ # Initialize the Inference Client
119
+ CLIENT = InferenceHTTPClient(
120
+ api_url=st.secrets["INFERENCE_API_URL"],
121
+ api_key=st.secrets["INFERENCE_API_KEY"]
122
+ )
123
+
124
+ # Function to preprocess the image
125
+ def preprocess_image(image_path):
126
+ # Load the image
127
+ image = cv2.imread(image_path)
128
+
129
+ # Convert to grayscale
130
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
131
+
132
+ # Remove noise
133
+ blurred = cv2.GaussianBlur(gray, (5, 5), 0)
134
+
135
+ # Thresholding/Binarization
136
+ _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
137
+
138
+ # Dilation and Erosion
139
+ kernel = np.ones((1, 1), np.uint8)
140
+ dilated = cv2.dilate(binary, kernel, iterations=1)
141
+ eroded = cv2.erode(dilated, kernel, iterations=1)
142
+
143
+ # Edge detection
144
+ edges = cv2.Canny(eroded, 100, 200)
145
+
146
+ # Deskewing
147
+ coords = np.column_stack(np.where(edges > 0))
148
+ angle = cv2.minAreaRect(coords)[-1]
149
+ if angle < -45:
150
+ angle = -(90 + angle)
151
+ else:
152
+ angle = -angle
153
+
154
+ (h, w) = edges.shape[:2]
155
+ center = (w // 2, h // 2)
156
+ M = cv2.getRotationMatrix2D(center, angle, 1.0)
157
+ deskewed = cv2.warpAffine(edges, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
158
+
159
+ # Find contours
160
+ contours, _ = cv2.findContours(deskewed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
161
+
162
+ # Draw contours on the original image
163
+ contour_image = image.copy()
164
+ cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)
165
+
166
+ return contour_image
167
+
168
+ def get_x1(detection):
169
+ return detection.xyxy[0][0]
170
+
171
+ # Access secrets using st.secrets
172
+ if "INFERENCE_API_URL" not in st.secrets or "INFERENCE_API_KEY" not in st.secrets:
173
+ st.error("Please make sure to set your secrets in the Streamlit secrets settings.")
174
+ else:
175
+ # Initialize the Inference Client
176
+ CLIENT = InferenceHTTPClient(
177
+ api_url=st.secrets["INFERENCE_API_URL"],
178
+ api_key=st.secrets["INFERENCE_API_KEY"]
179
+ )
180
+
181
+ # Function to preprocess the image
182
+ def preprocess_image(image_path):
183
+ # Load the image
184
+ image = cv2.imread(image_path)
185
+
186
+ # Convert to grayscale
187
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
188
+
189
+ # Remove noise
190
+ blurred = cv2.GaussianBlur(gray, (5, 5), 0)
191
+
192
+ # Thresholding/Binarization
193
+ _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
194
+
195
+ # Dilation and Erosion
196
+ kernel = np.ones((1, 1), np.uint8)
197
+ dilated = cv2.dilate(binary, kernel, iterations=1)
198
+ eroded = cv2.erode(dilated, kernel, iterations=1)
199
+
200
+ # Edge detection
201
+ edges = cv2.Canny(eroded, 100, 200)
202
+
203
+ # Deskewing
204
+ coords = np.column_stack(np.where(edges > 0))
205
+ angle = cv2.minAreaRect(coords)[-1]
206
+ if angle < -45:
207
+ angle = -(90 + angle)
208
+ else:
209
+ angle = -angle
210
+
211
+ (h, w) = edges.shape[:2]
212
+ center = (w // 2, h // 2)
213
+ M = cv2.getRotationMatrix2D(center, angle, 1.0)
214
+ deskewed = cv2.warpAffine(edges, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
215
+
216
+ # Find contours
217
+ contours, _ = cv2.findContours(deskewed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
218
+
219
+ # Draw contours on the original image
220
+ contour_image = image.copy()
221
+ cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)
222
+
223
+ return contour_image
224
+
225
+ def get_x1(detection):
226
+ return detection.xyxy[0][0]
227
+
228
+ # --- Prediction function (using session state) ---
229
+ def predict_disease(symptoms):
230
+ if st.session_state.vectorizer is not None and st.session_state.model_llm is not None:
231
+ preprocessed_symptoms = preprocess_text(symptoms)
232
+ symptoms_vectorized = st.session_state.vectorizer.transform([preprocessed_symptoms])
233
+ prediction = st.session_state.model_llm.predict(symptoms_vectorized)
234
+ return prediction[0]
235
+ else:
236
+ st.error("Unable to make prediction. Vectorizer or LLM model is not loaded.")
237
+ return None
238
+
239
+ # --- New function to analyze X-ray with LLM ---
240
+ def analyze_xray_with_llm(predicted_class):
241
+ prompt = f"""
242
+ Based on a chest X-ray analysis, the predicted condition is {predicted_class}.
243
+ Please provide a concise summary of this condition, including:
244
+ - A brief description of the condition.
245
+ - Common symptoms associated with it.
246
+ - Potential causes.
247
+ - General treatment approaches.
248
+ - Any other relevant information for a patient.
249
+ """
250
+ llm_response = get_ai71_response(prompt)
251
+ st.write("## LLM Analysis of X-ray Results:")
252
+ st.write(llm_response)
253
+
254
+ if page == "Home":
255
+ st.markdown("## Welcome to Medi Scape")
256
+ st.write("Medi Scape is an AI-powered healthcare application designed to streamline the process of understanding and managing medical information. It leverages advanced AI models to provide features such as prescription analysis, disease detection from chest X-rays, and symptom-based diagnosis assistance.")
257
+
258
+ st.markdown("## Features")
259
+ st.write("Medi Scape provides various AI-powered tools for remote healthcare, including:")
260
+ features = [
261
+ "**AI Chatbot Diagnosis:** Interact with an AI chatbot for preliminary diagnosis and medical information.",
262
+ "**Drug Identification:** Upload a prescription image to identify medications and access relevant details.",
263
+ "**Doctor's Handwriting Identification:** Our system can accurately recognize and process doctor's handwriting.",
264
+ "**Disease Detection:** Upload a chest X-ray image to detect potential diseases.",
265
+ "**Outbreak Alert:** Stay informed about potential disease outbreaks in your area."
266
+ ]
267
+ for feature in features:
268
+ st.markdown(f"- {feature}")
269
+
270
+ st.markdown("## How it Works")
271
+ steps = [
272
+ "**Upload:** You can upload a prescription image for drug identification or a chest X-ray image for disease detection.",
273
+ "**Process:** Our AI models will analyze the image and extract relevant information.",
274
+ "**Results:** You will receive identified drug names, uses, side effects, and more, or a potential disease diagnosis."
275
+ ]
276
+ for i, step in enumerate(steps, 1):
277
+ st.markdown(f"{i}. {step}")
278
+
279
+ st.markdown("## Key Features")
280
+ key_features = [
281
+ "**AI-Powered:** Leverages advanced AI models for accurate analysis and diagnosis.",
282
+ "**User-Friendly:** Simple and intuitive interface for easy navigation and interaction.",
283
+ "**Secure:** Your data is protected and handled with confidentiality."
284
+ ]
285
+ for feature in key_features:
286
+ st.markdown(f"- {feature}")
287
+
288
+ st.markdown("Please use the sidebar to navigate to different features.")
289
+
290
+ elif page == "AI Chatbot Diagnosis":
291
+ st.write("Enter your symptoms separated by commas:")
292
+ symptoms_input = st.text_area("Symptoms:")
293
+ if st.button("Diagnose"):
294
+ if symptoms_input:
295
+ # --- Pipeline 1 Implementation ---
296
+ # 1. Symptom Input (already done with st.text_area)
297
+ # 2. Regression Prediction
298
+ regression_prediction = predict_disease(symptoms_input)
299
+
300
+ if regression_prediction is not None:
301
+ # 3. LLM Prompt Enhancement
302
+ prompt = f"""The predicted condition based on a symptom analysis is {regression_prediction}.
303
+ Provide a detailed explanation of this condition, including possible causes, common symptoms,
304
+ and general treatment approaches. Also, suggest when a patient should consult a doctor."""
305
+
306
+ # 4. LLM Output
307
+ llm_response = get_ai71_response(prompt)
308
+
309
+ # 5. Combined Output
310
+ st.write("## Logistic Regression Prediction:")
311
+ st.write(regression_prediction)
312
+
313
+ st.write("## LLM Explanation:")
314
+ st.write(llm_response)
315
+ # --- End of Pipeline 1 Implementation ---
316
+
317
+ else:
318
+ st.write("Please enter your symptoms.")
319
+
320
+ elif page == "Drug Identification":
321
+ st.write("Upload a prescription image for drug identification.")
322
+ uploaded_file = st.file_uploader("Upload prescription", type=["png", "jpg", "jpeg"])
323
+
324
+ if uploaded_file is not None:
325
+ # Display the uploaded image
326
+ image = Image.open(uploaded_file)
327
+ st.image(image, caption="Uploaded Prescription", use_column_width=True)
328
+
329
+ if st.button("Process Prescription"):
330
+ # Save the image to a temporary file
331
+ temp_image_path = "temp_image.jpg"
332
+ image.save(temp_image_path)
333
+
334
+ # Preprocess the image
335
+ preprocessed_image = preprocess_image(temp_image_path)
336
+
337
+ # Perform inference
338
+ result_doch1 = CLIENT.infer(preprocessed_image, model_id="doctor-s-handwriting/1")
339
+
340
+ # Extract labels and detections
341
+ labels = [item["class"] for item in result_doch1["predictions"]]
342
+ detections = sv.Detections.from_inference(result_doch1)
343
+
344
+ # Sort detections and labels
345
+ sorted_indices = sorted(range(len(detections)), key=lambda i: get_x1(detections[i]))
346
+ sorted_detections = [detections[i] for i in sorted_indices]
347
+ sorted_labels = [labels[i] for i in sorted_indices]
348
+
349
+ # Convert list to string
350
+ resulting_string = ''.join(sorted_labels)
351
+
352
+ # Display results
353
+ st.subheader("Processed Prescription")
354
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
355
+
356
+ # Plot bounding boxes
357
+ image_with_boxes = preprocessed_image.copy()
358
+ for detection in sorted_detections:
359
+ x1, y1, x2, y2 = detection.xyxy[0]
360
+ cv2.rectangle(image_with_boxes, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), 2)
361
+ ax1.imshow(cv2.cvtColor(image_with_boxes, cv2.COLOR_BGR2RGB))
362
+ ax1.set_title("Bounding Boxes")
363
+ ax1.axis('off')
364
+
365
+ # Plot labels
366
+ image_with_labels = preprocessed_image.copy()
367
+ for i, detection in enumerate(sorted_detections):
368
+ x1, y1, x2, y2 = detection.xyxy[0]
369
+ label = sorted_labels[i]
370
+ cv2.putText(image_with_labels, label, (int(x1), int(y1) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
371
+ ax2.imshow(cv2.cvtColor(image_with_labels, cv2.COLOR_BGR2RGB))
372
+ ax2.set_title("Labels")
373
+ ax2.axis('off')
374
+
375
+ st.pyplot(fig)
376
+
377
+ st.write("Extracted Text from Prescription:", resulting_string)
378
+
379
+ # Prepare prompt for LLM
380
+ prompt = f"""Analyze the following prescription text:
381
+ {resulting_string}
382
+
383
+ Please provide:
384
+ 1. Identified drug name(s)
385
+ 2. Full name of each identified drug
386
+ 3. Primary uses of each drug
387
+ 4. Common side effects
388
+ 5. Recommended dosage (if identifiable from the text)
389
+ 6. Any warnings or precautions
390
+ 7. Potential interactions with other medications (if multiple drugs are identified)
391
+ 8. Any additional relevant information for the patient
392
+
393
+ If any part of the prescription is unclear or seems incomplete, please mention that and provide information about possible interpretations or matches. Always emphasize the importance of consulting a healthcare professional for accurate interpretation and advice."""
394
+
395
+ # Get LLM response
396
+ llm_response = get_ai71_response(prompt)
397
+
398
+ st.subheader("AI Analysis of the Prescription")
399
+ st.write(llm_response)
400
+
401
+ # Remove the temporary image file
402
+ os.remove(temp_image_path)
403
+
404
+ else:
405
+ st.info("Please upload a prescription image to proceed.")
406
+
407
+ elif page == "Disease Detection":
408
+ st.write("Upload a chest X-ray image for disease detection.")
409
+ uploaded_image = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
410
+
411
+ if uploaded_image is not None and st.session_state.disease_model is not None:
412
+ # Display the image
413
+ img_opened = Image.open(uploaded_image).convert('RGB')
414
+ image_pred = np.array(img_opened)
415
+ image_pred = cv2.resize(image_pred, (150, 150))
416
+
417
+ # Convert the image to a numpy array
418
+ image_pred = np.array(image_pred)
419
+
420
+ # Rescale the image (if the model was trained with rescaling)
421
+ image_pred = image_pred / 255.0
422
+
423
+ # Add an extra dimension to match the input shape (1, 150, 150, 3)
424
+ image_pred = np.expand_dims(image_pred, axis=0)
425
+
426
+ # Predict using the model
427
+ prediction = st.session_state.disease_model.predict(image_pred)
428
+
429
+ # Get the predicted class
430
+ predicted_ = np.argmax(prediction)
431
+
432
+ # Decode the prediction
433
+ if predicted_ == 0:
434
+ predicted_class = "Covid"
435
+ elif predicted_ == 1:
436
+ predicted_class = "Normal Chest X-ray"
437
+ else:
438
+ predicted_class = "Pneumonia"
439
+
440
+ st.image(image_pred, caption='Input image by user', use_column_width=True)
441
+ st.write("Prediction Classes for different types:")
442
+ st.write("COVID: 0")
443
+ st.write("Normal Chest X-ray: 1")
444
+ st.write("Pneumonia: 2")
445
+ st.write("\n")
446
+ st.write("DETECTED DISEASE DISPLAY")
447
+ st.write(f"Predicted Class : {predicted_}")
448
+ st.write(predicted_class)
449
+
450
+ # Analyze X-ray results with LLM
451
+ analyze_xray_with_llm(predicted_class)
452
+ else:
453
+ st.write("Please upload an image file or ensure the disease model is loaded.")
454
+
455
+ elif page == "Outbreak Alert":
456
+ st.markdown("## **Disease Outbreak News (from WHO)**")
457
+
458
+ # Fetch WHO news page
459
+ url = "https://www.who.int/news-room/events"
460
+ response = requests.get(url)
461
+ response.raise_for_status() # Raise an exception for bad status codes
462
+
463
+ soup = BeautifulSoup(response.content, 'html.parser')
464
+
465
+ # Find news articles (adjust selectors if WHO website changes)
466
+ articles = soup.find_all('div', class_='list-view--item')
467
+
468
+ for article in articles[:5]: # Display the top 5 news articles
469
+ title_element = article.find('a', class_='link-container')
470
+ if title_element:
471
+ title = title_element.text.strip()
472
+ link = title_element['href']
473
+ date_element = article.find('span', class_='date')
474
+ date = date_element.text.strip() if date_element else "Date not found"
475
+
476
+ # Format date
477
+ date_parts = date.split()
478
+ if len(date_parts) >= 3:
479
+ try:
480
+ formatted_date = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d")
481
+ except ValueError:
482
+ formatted_date = date # Keep the original date if formatting fails
483
+ else:
484
+ formatted_date = date
485
+
486
+ # Display news item in a card-like container
487
+ with st.container():
488
+ st.markdown(f"**{formatted_date}**")
489
+ st.markdown(f"[{title}]({link})")
490
+ st.markdown("---")
491
+ else:
492
+ st.write("Could not find article details.")
493
+
494
+ # Auto-scroll to the bottom of the chat container
495
+ st.markdown(
496
+ """
497
+ <script>
498
+ const chatContainer = document.querySelector('.st-chat-container');
499
+ if (chatContainer) {
500
+ chatContainer.scrollTop = chatContainer.scrollHeight;
501
+ }
502
+ </script>
503
+ """,
504
+ unsafe_allow_html=True,
505
+ )
covid_from_website.png ADDED
logistic_regression_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cfd5b38cded9c2b4426bb8cc9f337cd078973f5488e2692f3ecd21db3cc41c96
3
+ size 601655
normal_from_website.jpeg ADDED
pneumoni_from_Website.png ADDED
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tensorflow
2
+ streamlit
3
+ requests
4
+ ai71
5
+ python-dotenv
6
+ opencv-python
7
+ supervision
8
+ matplotlib
9
+ Pillow
10
+ inference-sdk
11
+ tensorflow
12
+ beautifulsoup4
13
+ scikit-learn
14
+ nltk
utils/ai71_utils.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ai71 import AI71
2
+ import os
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+ AI71_API_KEY = os.getenv("AI71_API_KEY")
8
+ client = AI71(AI71_API_KEY)
9
+
10
+ def get_ai71_response(user_input):
11
+ system_prompt = """You are an advanced AI assistant specializing in healthcare and prescription analysis. Your role is to:
12
+
13
+ 1. Analyze prescription images and extracted text to identify medications accurately.
14
+ 2. Provide detailed information about identified drugs, including their full names, primary uses, common side effects, recommended dosages, and any relevant warnings or precautions.
15
+ 3. Assist in interpreting unclear or incomplete drug names, offering possible matches and relevant information.
16
+ 4. Support general healthcare queries, offering informative and helpful responses while maintaining medical accuracy.
17
+ 5. Aid in potential disease diagnosis based on symptoms, always recommending professional medical consultation.
18
+ 6. Provide information on public health issues, including outbreak alerts and preventive measures.
19
+
20
+ Remember to always prioritize patient safety. Encourage users to consult healthcare professionals for personalized medical advice, diagnosis, or treatment. Your role is to inform and assist, not to replace professional medical consultation."""
21
+
22
+ messages = [
23
+ {"role": "system", "content": system_prompt},
24
+ {"role": "user", "content": user_input}
25
+ ]
26
+
27
+ response = client.chat.completions.create(
28
+ messages=messages,
29
+ model="tiiuae/falcon-180B-chat",
30
+ stream=False,
31
+ max_tokens=500 # Added max_tokens parameter
32
+ )
33
+
34
+ return response.choices[0].message.content