Rammohan0504 commited on
Commit
07c76c2
·
verified ·
1 Parent(s): 8110fc8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -12
app.py CHANGED
@@ -10,7 +10,7 @@ import joblib
10
  from datetime import datetime
11
  import shutil
12
  from reportlab.lib.pagesizes import letter
13
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
14
  from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
15
  from reportlab.lib import colors
16
 
@@ -47,6 +47,7 @@ def train_model(output_range):
47
  model = LinearRegression().fit(X, y)
48
  return model
49
 
 
50
  # Load models
51
  try:
52
  hemoglobin_model = joblib.load("hemoglobin_model_from_anemia_dataset.pkl")
@@ -159,7 +160,7 @@ def save_results_to_pdf(test_results, filename):
159
  return f"Error saving PDF: {str(e)}", None
160
 
161
  # Build health card layout
162
- def build_health_card(profile_image, test_results, summary, patient_name="", patient_age="", patient_gender="", patient_id="", pdf_filepath=""):
163
  from datetime import datetime
164
  current_date = datetime.now().strftime("%B %d, %Y")
165
 
@@ -202,17 +203,18 @@ def build_health_card(profile_image, test_results, summary, patient_name="", pat
202
  </div>
203
 
204
  <div style="display: flex; gap: 15px; justify-content: center; flex-wrap: wrap;">
205
- <a href="{pdf_filepath}" download="Health_Report.pdf">
206
- <button style="padding: 12px 24px; background: linear-gradient(135deg, #4caf50, #45a049); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 14px; box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3); transition: all 0.3s;">
207
- 📥 Download Report
208
- </button>
209
- </a>
 
210
  </div>
211
  </div>
212
  <style>
213
  @media print {{
214
  /* Hide input sections during print */
215
- .input-container {{ display: none; }}
216
  /* Keep only the health card visible */
217
  #health-card {{ display: block; }}
218
  }}
@@ -223,7 +225,118 @@ def build_health_card(profile_image, test_results, summary, patient_name="", pat
223
  # Initialize global variable for patient details
224
  current_patient_details = {'name': '', 'age': '', 'gender': '', 'id': ''}
225
 
226
- # Route the inputs to the correct function
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  def route_inputs(mode, image, video, patient_name, patient_age, patient_gender, patient_id):
228
  if mode == "Image" and image is None:
229
  return "<div style='color:red;'>⚠️ Error: No image provided.</div>", None
@@ -247,7 +360,7 @@ def route_inputs(mode, image, video, patient_name, patient_age, patient_gender,
247
  with gr.Blocks() as demo:
248
  gr.Markdown("""# 🧠 Face-Based Lab Test AI Report (Video Mode)""")
249
  with gr.Row():
250
- with gr.Column(elem_id="input-container"):
251
  gr.Markdown("### Patient Information")
252
  patient_name = gr.Textbox(label="Patient Name", placeholder="Enter patient name")
253
  patient_age = gr.Number(label="Age", value=25, minimum=1, maximum=120)
@@ -262,7 +375,7 @@ with gr.Blocks() as demo:
262
  video_input = gr.Video(label="Upload Face Video",
263
  sources=["upload", "webcam"])
264
  submit_btn = gr.Button("🔍 Analyze")
265
- with gr.Column(elem_id="output-container"):
266
  result_html = gr.HTML(label="🧪 Health Report Table")
267
  result_pdf = gr.File(label="Download Health Report PDF", interactive=False)
268
 
@@ -271,4 +384,4 @@ with gr.Blocks() as demo:
271
  outputs=[result_html, result_pdf])
272
 
273
  # Launch Gradio for Replit
274
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
10
  from datetime import datetime
11
  import shutil
12
  from reportlab.lib.pagesizes import letter
13
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
14
  from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
15
  from reportlab.lib import colors
16
 
 
47
  model = LinearRegression().fit(X, y)
48
  return model
49
 
50
+
51
  # Load models
52
  try:
53
  hemoglobin_model = joblib.load("hemoglobin_model_from_anemia_dataset.pkl")
 
160
  return f"Error saving PDF: {str(e)}", None
161
 
162
  # Build health card layout
163
+ def build_health_card(profile_image, test_results, summary, patient_name="", patient_age="", patient_gender="", patient_id=""):
164
  from datetime import datetime
165
  current_date = datetime.now().strftime("%B %d, %Y")
166
 
 
203
  </div>
204
 
205
  <div style="display: flex; gap: 15px; justify-content: center; flex-wrap: wrap;">
206
+ <button onclick="window.print()" style="padding: 12px 24px; background: linear-gradient(135deg, #4caf50, #45a049); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 14px; box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3); transition: all 0.3s;">
207
+ 📥 Download Report
208
+ </button>
209
+ <button style="padding: 12px 24px; background: linear-gradient(135deg, #2196f3, #1976d2); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 14px; box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);">
210
+ 📞 Find Labs Near Me
211
+ </button>
212
  </div>
213
  </div>
214
  <style>
215
  @media print {{
216
  /* Hide input sections during print */
217
+ .gradio-container {{ display: block; }}
218
  /* Keep only the health card visible */
219
  #health-card {{ display: block; }}
220
  }}
 
225
  # Initialize global variable for patient details
226
  current_patient_details = {'name': '', 'age': '', 'gender': '', 'id': ''}
227
 
228
+ # Modified analyze_face function
229
+ def analyze_face(input_data):
230
+ if isinstance(input_data, str): # Video input (file path in Replit)
231
+ cap = cv2.VideoCapture(input_data)
232
+ if not cap.isOpened():
233
+ return "<div style='color:red;'>⚠️ Error: Could not open video.</div>", None
234
+ ret, frame = cap.read()
235
+ cap.release()
236
+ if not ret:
237
+ return "<div style='color:red;'>⚠️ Error: Could not read video frame.</div>", None
238
+ else: # Image input
239
+ frame = input_data
240
+ if frame is None:
241
+ return "<div style='color:red;'>⚠️ Error: No image provided.</div>", None
242
+
243
+ # Resize image to reduce processing time
244
+ frame = cv2.resize(frame, (640, 480)) # Adjust resolution for Replit
245
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
246
+ result = face_mesh.process(frame_rgb)
247
+ if not result.multi_face_landmarks:
248
+ return "<div style='color:red;'>⚠️ Error: Face not detected.</div>", None
249
+ landmarks = result.multi_face_landmarks[0].landmark # Fixed: Use integer index
250
+ features = extract_features(frame_rgb, landmarks)
251
+ test_values = {}
252
+ r2_scores = {}
253
+
254
+ for label in models:
255
+ if label == "Hemoglobin":
256
+ prediction = models[label].predict([features])[0]
257
+ test_values[label] = prediction
258
+ r2_scores[label] = 0.385
259
+ else:
260
+ value = models[label].predict([[random.uniform(0.2, 0.5) for _ in range(7)]])[0]
261
+ test_values[label] = value
262
+ r2_scores[label] = 0.0
263
+
264
+ gray = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2GRAY)
265
+ green_std = np.std(frame_rgb[:, :, 1]) / 255
266
+ brightness_std = np.std(gray) / 255
267
+ tone_index = np.mean(frame_rgb[100:150, 100:150]) / 255 if frame_rgb[
268
+ 100:150, 100:150].size else 0.5
269
+ hr_features = [brightness_std, green_std, tone_index]
270
+ heart_rate = float(np.clip(hr_model.predict([hr_features])[0], 60, 100))
271
+ skin_patch = frame_rgb[100:150, 100:150]
272
+ skin_tone_index = np.mean(skin_patch) / 255 if skin_patch.size else 0.5
273
+ brightness_variation = np.std(cv2.cvtColor(frame_rgb,
274
+ cv2.COLOR_RGB2GRAY)) / 255
275
+ spo2_features = [heart_rate, brightness_variation, skin_tone_index]
276
+ spo2 = spo2_model.predict([spo2_features])[0]
277
+ rr = int(12 + abs(heart_rate % 5 - 2))
278
+
279
+ test_results = {
280
+ "Hematology":
281
+ build_table("🩸 Hematology",
282
+ [("Hemoglobin", test_values["Hemoglobin"], (13.5, 17.5)),
283
+ ("WBC Count", test_values["WBC Count"], (4.0, 11.0)),
284
+ ("Platelet Count", test_values["Platelet Count"],
285
+ (150, 450))]),
286
+ "Iron Panel":
287
+ build_table("🧬 Iron Panel",
288
+ [("Iron", test_values["Iron"], (60, 170)),
289
+ ("Ferritin", test_values["Ferritin"], (30, 300)),
290
+ ("TIBC", test_values["TIBC"], (250, 400))]),
291
+ "Liver & Kidney":
292
+ build_table("🧬 Liver & Kidney",
293
+ [("Bilirubin", test_values["Bilirubin"], (0.3, 1.2)),
294
+ ("Creatinine", test_values["Creatinine"], (0.6, 1.2)),
295
+ ("Urea", test_values["Urea"], (7, 20))]),
296
+ "Electrolytes":
297
+ build_table("🧪 Electrolytes",
298
+ [("Sodium", test_values["Sodium"], (135, 145)),
299
+ ("Potassium", test_values["Potassium"], (3.5, 5.1))]),
300
+ "Vitals":
301
+ build_table("❤️ Vitals",
302
+ [("SpO2", spo2, (95, 100)),
303
+ ("Heart Rate", heart_rate, (60, 100)),
304
+ ("Respiratory Rate", rr, (12, 20)),
305
+ ("Temperature", test_values["Temperature"], (97, 99)),
306
+ ("BP Systolic", test_values["BP Systolic"], (90, 120)),
307
+ ("BP Diastolic", test_values["BP Diastolic"], (60, 80))])
308
+ }
309
+
310
+ summary = "<ul><li>Your hemoglobin is a bit low — this could mean mild anemia.</li><li>Low iron storage detected — consider an iron profile test.</li><li>Elevated bilirubin — possible jaundice. Recommend LFT.</li><li>High HbA1c — prediabetes indication. Recommend glucose check.</li><li>Low SpO₂ — suggest retesting with a pulse oximeter.</li></ul>"
311
+
312
+ _, buffer = cv2.imencode('.png', frame_rgb)
313
+ profile_image_base64 = base64.b64encode(buffer).decode('utf-8')
314
+
315
+ # Use global patient details
316
+ global current_patient_details
317
+ health_card_html = build_health_card(
318
+ profile_image_base64,
319
+ test_results,
320
+ summary,
321
+ current_patient_details['name'],
322
+ current_patient_details['age'],
323
+ current_patient_details['gender'],
324
+ current_patient_details['id']
325
+ )
326
+
327
+ # Generate PDF and return for download
328
+ pdf_filename = f"Health_Report_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.pdf"
329
+ pdf_result, pdf_filepath = save_results_to_pdf(test_results, pdf_filename)
330
+
331
+ if pdf_filepath:
332
+ # Copy the PDF to a temporary directory for Gradio to serve it
333
+ temp_pdf_path = "/tmp/" + os.path.basename(pdf_filepath)
334
+ shutil.copy(pdf_filepath, temp_pdf_path)
335
+
336
+ return health_card_html, temp_pdf_path
337
+
338
+
339
+ # Modified route_inputs function
340
  def route_inputs(mode, image, video, patient_name, patient_age, patient_gender, patient_id):
341
  if mode == "Image" and image is None:
342
  return "<div style='color:red;'>⚠️ Error: No image provided.</div>", None
 
360
  with gr.Blocks() as demo:
361
  gr.Markdown("""# 🧠 Face-Based Lab Test AI Report (Video Mode)""")
362
  with gr.Row():
363
+ with gr.Column():
364
  gr.Markdown("### Patient Information")
365
  patient_name = gr.Textbox(label="Patient Name", placeholder="Enter patient name")
366
  patient_age = gr.Number(label="Age", value=25, minimum=1, maximum=120)
 
375
  video_input = gr.Video(label="Upload Face Video",
376
  sources=["upload", "webcam"])
377
  submit_btn = gr.Button("🔍 Analyze")
378
+ with gr.Column():
379
  result_html = gr.HTML(label="🧪 Health Report Table")
380
  result_pdf = gr.File(label="Download Health Report PDF", interactive=False)
381
 
 
384
  outputs=[result_html, result_pdf])
385
 
386
  # Launch Gradio for Replit
387
+ demo.launch(server_name="0.0.0.0", server_port=7860)