Update app.py
Browse files
app.py
CHANGED
|
@@ -173,7 +173,7 @@ class FaceAnalyzer:
|
|
| 173 |
try:
|
| 174 |
face_landmarks = results.multi_face_landmarks[0]
|
| 175 |
landmarks = [(int(p.x * frame.shape[1]), int(p.y * frame.shape[0]))
|
| 176 |
-
|
| 177 |
|
| 178 |
# Calculate EAR and MAR
|
| 179 |
left_ear = self.calculate_ear(LEFT_EYE, landmarks)
|
|
@@ -230,7 +230,7 @@ class FaceAnalyzer:
|
|
| 230 |
processed_frame = cv2.addWeighted(overlay, alpha, frame, 1 - alpha, 0)
|
| 231 |
|
| 232 |
cv2.putText(processed_frame, timer_text, (text_x, text_y),
|
| 233 |
-
|
| 234 |
|
| 235 |
return (cv2.cvtColor(processed_frame, cv2.COLOR_BGR2RGB),
|
| 236 |
f"{ear:.2f}" if ear is not None else "---",
|
|
@@ -361,8 +361,14 @@ answer_mapping = {
|
|
| 361 |
"The symptoms of burnout that I’m experiencing won’t go away. I think about frustration at work a lot": 3,
|
| 362 |
"I feel completely burned out and often wonder if I can go on. I am at the point where I may need some changes or may need to seek some sort of help": 4,
|
| 363 |
}
|
| 364 |
-
|
| 365 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
def preprocess_input(raw_dict, scaler):
|
| 367 |
# Map questionnaire answers to ints
|
| 368 |
q_encoded = [answer_mapping.get(ans, -1) for ans in raw_dict["Questionnaire Answers"]]
|
|
@@ -409,13 +415,15 @@ def preprocess_input(raw_dict, scaler):
|
|
| 409 |
return X_scaled
|
| 410 |
|
| 411 |
def predict_burnout(raw_dict):
|
|
|
|
|
|
|
|
|
|
| 412 |
X_processed = preprocess_input(raw_dict, scaler)
|
| 413 |
pred = model.predict(X_processed)
|
| 414 |
# Assuming regression or float prediction; if classifier, adapt accordingly
|
| 415 |
output_score = float(pred[0])
|
| 416 |
return output_score
|
| 417 |
|
| 418 |
-
|
| 419 |
# --- PDF Download Function ---
|
| 420 |
def download_info_pdf():
|
| 421 |
pdf_path = "info.pdf"
|
|
@@ -480,12 +488,12 @@ with gr.Blocks() as demo:
|
|
| 480 |
text_output = gr.Textbox(label="Transcribed Text")
|
| 481 |
sentiment_output = gr.Textbox(label="Sentiment Analysis (Pos, Neu, Neg, Comp)")
|
| 482 |
pitch_output = gr.Textbox(label="Pitch (Hz) ± Std Dev")
|
| 483 |
-
proceed_to_results_btn = gr.Button("Proceed to
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
|
| 485 |
-
# Results
|
| 486 |
-
with gr.TabItem("Results", id=3):
|
| 487 |
-
results_json = gr.JSON(label="Full Results (Questionnaire, EAR/MAR, Emotion, Voice, Subtypes)")
|
| 488 |
-
burnout_score_output = gr.Textbox(label="Burnout Score", interactive=False)
|
| 489 |
|
| 490 |
# Questionnaire submit → store answers + go to Face Analysis tab
|
| 491 |
def questionnaire_to_face(*answers):
|
|
@@ -561,19 +569,19 @@ with gr.Blocks() as demo:
|
|
| 561 |
outputs=[text_output, sentiment_output, pitch_output],
|
| 562 |
)
|
| 563 |
|
| 564 |
-
# Proceed to
|
| 565 |
-
def
|
| 566 |
required_keys = ["questionnaire", "face", "emotion", "voice", "subtypes"]
|
| 567 |
missing_keys = [key for key in required_keys if key not in stored_data]
|
| 568 |
|
| 569 |
if missing_keys:
|
| 570 |
-
return
|
| 571 |
|
| 572 |
try:
|
| 573 |
-
# Defensive cleaning
|
| 574 |
subtype_counts = stored_data.get("subtypes", {})
|
| 575 |
cleaned_subtypes = {str(emotion): {str(k): int(v) for k, v in subs.items()}
|
| 576 |
-
|
| 577 |
|
| 578 |
results = aggregate_results(
|
| 579 |
stored_data["questionnaire"],
|
|
@@ -582,23 +590,66 @@ with gr.Blocks() as demo:
|
|
| 582 |
stored_data["voice"],
|
| 583 |
cleaned_subtypes,
|
| 584 |
)
|
| 585 |
-
|
| 586 |
-
stored_data["results"] = results
|
| 587 |
-
|
| 588 |
# Get burnout score from model prediction
|
| 589 |
-
burnout_score = predict_burnout(results)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 590 |
|
| 591 |
-
return
|
| 592 |
except Exception as e:
|
| 593 |
-
return
|
| 594 |
-
|
| 595 |
|
| 596 |
|
| 597 |
proceed_to_results_btn.click(
|
| 598 |
-
fn=
|
| 599 |
-
outputs=[
|
| 600 |
)
|
| 601 |
|
| 602 |
|
| 603 |
if __name__ == "__main__":
|
| 604 |
-
demo.launch(
|
|
|
|
| 173 |
try:
|
| 174 |
face_landmarks = results.multi_face_landmarks[0]
|
| 175 |
landmarks = [(int(p.x * frame.shape[1]), int(p.y * frame.shape[0]))
|
| 176 |
+
for p in face_landmarks.landmark]
|
| 177 |
|
| 178 |
# Calculate EAR and MAR
|
| 179 |
left_ear = self.calculate_ear(LEFT_EYE, landmarks)
|
|
|
|
| 230 |
processed_frame = cv2.addWeighted(overlay, alpha, frame, 1 - alpha, 0)
|
| 231 |
|
| 232 |
cv2.putText(processed_frame, timer_text, (text_x, text_y),
|
| 233 |
+
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
|
| 234 |
|
| 235 |
return (cv2.cvtColor(processed_frame, cv2.COLOR_BGR2RGB),
|
| 236 |
f"{ear:.2f}" if ear is not None else "---",
|
|
|
|
| 361 |
"The symptoms of burnout that I’m experiencing won’t go away. I think about frustration at work a lot": 3,
|
| 362 |
"I feel completely burned out and often wonder if I can go on. I am at the point where I may need some changes or may need to seek some sort of help": 4,
|
| 363 |
}
|
| 364 |
+
try:
|
| 365 |
+
scaler=joblib.load('scaler.joblib')
|
| 366 |
+
model = joblib.load('model.joblib')
|
| 367 |
+
except FileNotFoundError:
|
| 368 |
+
gr.Warning("Model files not found. The app will run, but prediction will not work.")
|
| 369 |
+
scaler = None
|
| 370 |
+
model = None
|
| 371 |
+
|
| 372 |
def preprocess_input(raw_dict, scaler):
|
| 373 |
# Map questionnaire answers to ints
|
| 374 |
q_encoded = [answer_mapping.get(ans, -1) for ans in raw_dict["Questionnaire Answers"]]
|
|
|
|
| 415 |
return X_scaled
|
| 416 |
|
| 417 |
def predict_burnout(raw_dict):
|
| 418 |
+
if not scaler or not model:
|
| 419 |
+
raise RuntimeError("Model files not loaded. Cannot predict.")
|
| 420 |
+
|
| 421 |
X_processed = preprocess_input(raw_dict, scaler)
|
| 422 |
pred = model.predict(X_processed)
|
| 423 |
# Assuming regression or float prediction; if classifier, adapt accordingly
|
| 424 |
output_score = float(pred[0])
|
| 425 |
return output_score
|
| 426 |
|
|
|
|
| 427 |
# --- PDF Download Function ---
|
| 428 |
def download_info_pdf():
|
| 429 |
pdf_path = "info.pdf"
|
|
|
|
| 488 |
text_output = gr.Textbox(label="Transcribed Text")
|
| 489 |
sentiment_output = gr.Textbox(label="Sentiment Analysis (Pos, Neu, Neg, Comp)")
|
| 490 |
pitch_output = gr.Textbox(label="Pitch (Hz) ± Std Dev")
|
| 491 |
+
proceed_to_results_btn = gr.Button("Proceed to Suggestions")
|
| 492 |
+
|
| 493 |
+
# Suggestions
|
| 494 |
+
with gr.TabItem("Suggestions", id=3):
|
| 495 |
+
suggestion_output = gr.Textbox(label="Suggestion based on Burnout Score", interactive=False)
|
| 496 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
|
| 498 |
# Questionnaire submit → store answers + go to Face Analysis tab
|
| 499 |
def questionnaire_to_face(*answers):
|
|
|
|
| 569 |
outputs=[text_output, sentiment_output, pitch_output],
|
| 570 |
)
|
| 571 |
|
| 572 |
+
# Proceed to Suggestions tab
|
| 573 |
+
def proceed_to_suggestions():
|
| 574 |
required_keys = ["questionnaire", "face", "emotion", "voice", "subtypes"]
|
| 575 |
missing_keys = [key for key in required_keys if key not in stored_data]
|
| 576 |
|
| 577 |
if missing_keys:
|
| 578 |
+
return f"Error: Missing data: {', '.join(missing_keys)}. Please complete all sections.", gr.Tabs(selected=2)
|
| 579 |
|
| 580 |
try:
|
| 581 |
+
# Defensive cleaning
|
| 582 |
subtype_counts = stored_data.get("subtypes", {})
|
| 583 |
cleaned_subtypes = {str(emotion): {str(k): int(v) for k, v in subs.items()}
|
| 584 |
+
for emotion, subs in subtype_counts.items()}
|
| 585 |
|
| 586 |
results = aggregate_results(
|
| 587 |
stored_data["questionnaire"],
|
|
|
|
| 590 |
stored_data["voice"],
|
| 591 |
cleaned_subtypes,
|
| 592 |
)
|
| 593 |
+
|
|
|
|
|
|
|
| 594 |
# Get burnout score from model prediction
|
| 595 |
+
burnout_score = predict_burnout(results)
|
| 596 |
+
|
| 597 |
+
if burnout_score==0.0:
|
| 598 |
+
suggestion_text = """
|
| 599 |
+
Your burnout score lies between 0 to 20.
|
| 600 |
+
You're feeling good.
|
| 601 |
+
You're active and enjoying your work. The goal is to build habits to maintain that feeling and prevent stress from building up.
|
| 602 |
+
Maintain healthy work-life habits. This includes taking proper lunch breaks and not checking work emails after hours.
|
| 603 |
+
Practice gratitude journaling. Write down three things you are grateful for daily to build resilience.
|
| 604 |
+
Promote regular physical activity. Even a 20-minute walk can help reduce stress and improve your mood.
|
| 605 |
+
"""
|
| 606 |
+
elif burnout_score==1.0:
|
| 607 |
+
suggestion_text = """
|
| 608 |
+
Your burnout score lies between 20 to 40.
|
| 609 |
+
You're feeling a bit tired.
|
| 610 |
+
You're under a little stress, but not completely burned out. Now is the time to build in small, intentional breaks to prevent burnout.
|
| 611 |
+
Use the Pomodoro Technique: Work for 25 minutes, then take a 5-minute break. This prevents stress from building up.
|
| 612 |
+
Try Box Breathing: Inhale (4s), Hold (4s), Exhale (4s), Hold (4s). This calms your nervous system quickly.
|
| 613 |
+
Schedule "disconnect" periods. Set specific times to turn off work notifications.
|
| 614 |
+
"""
|
| 615 |
+
elif burnout_score==2.0:
|
| 616 |
+
suggestion_text = """
|
| 617 |
+
Your burnout score lies between 40 to 60.
|
| 618 |
+
You're starting to burn out.
|
| 619 |
+
You're feeling physical and emotional exhaustion. This is a critical stage. Set firm boundaries and actively manage your stress.
|
| 620 |
+
Implement a Digital Detox. Designate tech-free hours in the evening to mentally separate work from personal life.
|
| 621 |
+
Prioritize Physical Activity: Aim for 20-30 minutes of aerobic exercise, 3 times a week, to reduce stress hormones.
|
| 622 |
+
Focus on Sleep Hygiene: Ensure you get 7-9 hours of quality sleep to improve your body's ability to cope with stress.
|
| 623 |
+
"""
|
| 624 |
+
elif burnout_score==3.0:
|
| 625 |
+
suggestion_text = """
|
| 626 |
+
Your burnout score lies between 60 to 80.
|
| 627 |
+
Your burnout symptoms are persistent.
|
| 628 |
+
They won't go away, and you're thinking about work constantly. You need a more structured approach and should consider professional help.
|
| 629 |
+
Take Mandatory Time Off. Use your vacation days to fully disconnect and recharge.
|
| 630 |
+
Consider a Mindfulness-Based Stress Reduction (MBSR) course. This is a more intensive program that provides long-term stress management skills.
|
| 631 |
+
Seek Professional Help. Contact your company's Employee Assistance Program (EAP) or a therapist for confidential support.
|
| 632 |
+
"""
|
| 633 |
+
else:
|
| 634 |
+
suggestion_text = """
|
| 635 |
+
Your burnout score lies between 80 to 100.
|
| 636 |
+
You feel completely burned out.
|
| 637 |
+
You feel like you can't go on. Your health and safety are the top priority. You need immediate professional help.
|
| 638 |
+
Access Crisis Resources: If you are having thoughts of self-harm, immediately call a crisis hotline like the National Suicide Prevention Lifeline at 988.
|
| 639 |
+
Consult a Doctor Immediately. Seek urgent help from a doctor, psychologist, or psychiatrist.
|
| 640 |
+
Prioritize Health Over Work. Your health and safety are the most important thing. Work can wait.
|
| 641 |
+
"""
|
| 642 |
|
| 643 |
+
return suggestion_text, gr.Tabs(selected=3)
|
| 644 |
except Exception as e:
|
| 645 |
+
return f"Error: Failed to generate results: {str(e)}", gr.Tabs(selected=2)
|
|
|
|
| 646 |
|
| 647 |
|
| 648 |
proceed_to_results_btn.click(
|
| 649 |
+
fn=proceed_to_suggestions,
|
| 650 |
+
outputs=[suggestion_output, tabs],
|
| 651 |
)
|
| 652 |
|
| 653 |
|
| 654 |
if __name__ == "__main__":
|
| 655 |
+
demo.launch()
|