Rammohan0504 commited on
Commit
32c2dd4
·
verified ·
1 Parent(s): bb7a722

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -35
app.py CHANGED
@@ -6,7 +6,12 @@ from sklearn.linear_model import LinearRegression
6
  import random
7
  import base64
8
  import joblib
9
- from fpdf import FPDF
 
 
 
 
 
10
 
11
  # Initialize the face mesh model
12
  mp_face_mesh = mp.solutions.face_mesh
@@ -15,6 +20,7 @@ face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True,
15
  refine_landmarks=True,
16
  min_detection_confidence=0.5)
17
 
 
18
  # Functions for feature extraction
19
  def extract_features(image, landmarks):
20
  red_channel = image[:, :, 2]
@@ -27,6 +33,7 @@ def extract_features(image, landmarks):
27
 
28
  return [red_percent, green_percent, blue_percent]
29
 
 
30
  def train_model(output_range):
31
  X = [[
32
  random.uniform(0.2, 0.5),
@@ -113,34 +120,49 @@ def build_table(title, rows):
113
  return html
114
 
115
 
116
- # Generate PDF report using FPDF with support for UTF-8 characters (like emojis)
117
- def generate_pdf(report_html):
118
- pdf = FPDF()
119
- pdf.set_auto_page_break(auto=True, margin=15)
120
-
121
- # Add a page to the PDF
122
- pdf.add_page()
123
-
124
- # Add a custom font (download a TTF font that supports Unicode characters and emojis)
125
- # Here, 'Arial Unicode MS' is used as an example, but you can use any font supporting emojis
126
- # Make sure to have the TTF file in your project and pass it as an argument to add_font
127
  try:
128
- pdf.add_font('ArialUnicode', '', '/path/to/ArialUnicodeMS.ttf', uni=True)
129
- pdf.set_font('ArialUnicode', '', 12)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  except Exception as e:
131
- print(f"Error loading font: {e}")
132
- pdf.set_font('Arial', '', 12) # Fallback to a default font if custom font fails
133
-
134
- # Add a title
135
- pdf.cell(200, 10, txt="Face-Based Health Report", ln=True, align="C")
136
-
137
- # Write the report HTML content into the PDF
138
- pdf.multi_cell(0, 10, txt=report_html)
139
-
140
- # Save the PDF to a file
141
- pdf_output = "/mnt/data/health_report.pdf"
142
- pdf.output(pdf_output)
143
- return pdf_output
144
 
145
 
146
  # Build health card layout
@@ -150,6 +172,7 @@ def build_health_card(profile_image, test_results, summary, patient_name="", pat
150
 
151
  html = f"""
152
  <div id="health-card" style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 700px; margin: 20px auto; border-radius: 16px; background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%); border: 2px solid #ddd; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); padding: 30px; color: #1a1a1a;">
 
153
  <div style="background-color: rgba(255, 255, 255, 0.9); border-radius: 12px; padding: 20px; margin-bottom: 25px; border: 1px solid #e0e0e0;">
154
  <div style="display: flex; align-items: center; margin-bottom: 15px;">
155
  <div style="background: linear-gradient(135deg, #64b5f6, #42a5f5); padding: 8px 16px; border-radius: 8px; margin-right: 20px;">
@@ -184,6 +207,15 @@ def build_health_card(profile_image, test_results, summary, patient_name="", pat
184
  {summary}
185
  </div>
186
  </div>
 
 
 
 
 
 
 
 
 
187
  </div>
188
  """
189
  return html
@@ -210,6 +242,7 @@ def analyze_face(input_data):
210
  # Resize image to reduce processing time
211
  frame = cv2.resize(frame, (640, 480)) # Adjust resolution for Replit
212
  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 
213
  result = face_mesh.process(frame_rgb)
214
  if not result.multi_face_landmarks:
215
  return "<div style='color:red;'>⚠️ Error: Face not detected.</div>", None
@@ -292,10 +325,17 @@ def analyze_face(input_data):
292
  current_patient_details['gender'],
293
  current_patient_details['id']
294
  )
295
-
296
- # Generate PDF
297
- pdf_file_path = generate_pdf(health_card_html)
298
- return pdf_file_path
 
 
 
 
 
 
 
299
 
300
 
301
  # Modified route_inputs function
@@ -314,8 +354,8 @@ def route_inputs(mode, image, video, patient_name, patient_age, patient_gender,
314
  'id': patient_id
315
  }
316
 
317
- pdf_file_path = analyze_face(image if mode == "Image" else video)
318
- return pdf_file_path
319
 
320
 
321
  # Create Gradio interface
@@ -338,11 +378,13 @@ with gr.Blocks() as demo:
338
  sources=["upload", "webcam"])
339
  submit_btn = gr.Button("🔍 Analyze")
340
  with gr.Column():
341
- pdf_file = gr.File(label="Download Report (PDF)")
 
 
342
 
343
  submit_btn.click(fn=route_inputs,
344
  inputs=[mode_selector, image_input, video_input, patient_name, patient_age, patient_gender, patient_id],
345
- outputs=[pdf_file])
346
 
347
  # Launch Gradio for Replit
348
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
6
  import random
7
  import base64
8
  import joblib
9
+ import shutil
10
+ from datetime import datetime
11
+ from reportlab.lib.pagesizes import letter
12
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
13
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
14
+ from reportlab.lib import colors
15
 
16
  # Initialize the face mesh model
17
  mp_face_mesh = mp.solutions.face_mesh
 
20
  refine_landmarks=True,
21
  min_detection_confidence=0.5)
22
 
23
+
24
  # Functions for feature extraction
25
  def extract_features(image, landmarks):
26
  red_channel = image[:, :, 2]
 
33
 
34
  return [red_percent, green_percent, blue_percent]
35
 
36
+
37
  def train_model(output_range):
38
  X = [[
39
  random.uniform(0.2, 0.5),
 
120
  return html
121
 
122
 
123
+ # Function to save the health report to PDF
124
+ def save_results_to_pdf(test_results, filename):
 
 
 
 
 
 
 
 
 
125
  try:
126
+ # Create a PDF document
127
+ doc = SimpleDocTemplate(filename, pagesize=letter)
128
+ styles = getSampleStyleSheet()
129
+
130
+ # Define custom styles
131
+ title_style = ParagraphStyle(
132
+ name='Title',
133
+ fontSize=16,
134
+ leading=20,
135
+ alignment=1, # Center
136
+ spaceAfter=20,
137
+ textColor=colors.black,
138
+ fontName='Helvetica-Bold'
139
+ )
140
+ body_style = ParagraphStyle(
141
+ name='Body',
142
+ fontSize=12,
143
+ leading=14,
144
+ spaceAfter=10,
145
+ textColor=colors.black,
146
+ fontName='Helvetica'
147
+ )
148
+
149
+ # Build the PDF content
150
+ flowables = []
151
+
152
+ # Add title
153
+ flowables.append(Paragraph("Health Report", title_style))
154
+
155
+ # Add test results to the report
156
+ for label, value in test_results.items():
157
+ line = f"{label}: {value}"
158
+ flowables.append(Paragraph(line, body_style))
159
+ flowables.append(Spacer(1, 12))
160
+
161
+ # Build the PDF
162
+ doc.build(flowables)
163
+ return f"PDF saved successfully as {filename}", filename
164
  except Exception as e:
165
+ return f"Error saving PDF: {str(e)}", None
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
 
168
  # Build health card layout
 
172
 
173
  html = f"""
174
  <div id="health-card" style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 700px; margin: 20px auto; border-radius: 16px; background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%); border: 2px solid #ddd; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); padding: 30px; color: #1a1a1a;">
175
+
176
  <div style="background-color: rgba(255, 255, 255, 0.9); border-radius: 12px; padding: 20px; margin-bottom: 25px; border: 1px solid #e0e0e0;">
177
  <div style="display: flex; align-items: center; margin-bottom: 15px;">
178
  <div style="background: linear-gradient(135deg, #64b5f6, #42a5f5); padding: 8px 16px; border-radius: 8px; margin-right: 20px;">
 
207
  {summary}
208
  </div>
209
  </div>
210
+
211
+ <div style="display: flex; gap: 15px; justify-content: center; flex-wrap: wrap;">
212
+ <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;">
213
+ 📥 Download Report
214
+ </button>
215
+ <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);">
216
+ 📞 Find Labs Near Me
217
+ </button>
218
+ </div>
219
  </div>
220
  """
221
  return html
 
242
  # Resize image to reduce processing time
243
  frame = cv2.resize(frame, (640, 480)) # Adjust resolution for Replit
244
  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
245
+ # Provide image dimensions to mediapipe to avoid NORM_RECT warning
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
 
325
  current_patient_details['gender'],
326
  current_patient_details['id']
327
  )
328
+
329
+ # Generate PDF and return for download
330
+ pdf_filename = f"Health_Report_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.pdf"
331
+ pdf_result, pdf_filepath = save_results_to_pdf(test_results, pdf_filename)
332
+
333
+ if pdf_filepath:
334
+ # Copy the PDF to a temporary directory for Gradio to serve it
335
+ temp_pdf_path = "/tmp/" + os.path.basename(pdf_filepath)
336
+ shutil.copy(pdf_filepath, temp_pdf_path)
337
+
338
+ return health_card_html, temp_pdf_path
339
 
340
 
341
  # Modified route_inputs function
 
354
  'id': patient_id
355
  }
356
 
357
+ health_card_html, pdf_file_path = analyze_face(image if mode == "Image" else video)
358
+ return health_card_html, pdf_file_path
359
 
360
 
361
  # Create Gradio interface
 
378
  sources=["upload", "webcam"])
379
  submit_btn = gr.Button("🔍 Analyze")
380
  with gr.Column():
381
+ result_html = gr.HTML(label="🧪 Health Report Table")
382
+ result_image = gr.Image(label="📷 Key Frame Snapshot")
383
+ result_pdf = gr.File(label="Download Health Report PDF")
384
 
385
  submit_btn.click(fn=route_inputs,
386
  inputs=[mode_selector, image_input, video_input, patient_name, patient_age, patient_gender, patient_id],
387
+ outputs=[result_html, result_pdf])
388
 
389
  # Launch Gradio for Replit
390
  demo.launch(server_name="0.0.0.0", server_port=7860)