Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -10,6 +10,7 @@ from transformers import (
|
|
10 |
CLIPProcessor, CLIPModel,
|
11 |
AutoProcessor
|
12 |
)
|
|
|
13 |
|
14 |
# βββββββββββββββββββββββββββββ
|
15 |
# CONFIG: set your HF token here or via env var HF_TOKEN
|
@@ -114,10 +115,11 @@ BREED_LIFESPAN = {
|
|
114 |
"wire-haired fox terrier": 13.5, "yorkshire terrier": 13.3
|
115 |
}
|
116 |
|
117 |
-
# 4. VetMetrica HRQOL Framework
|
118 |
HRQOL_QUESTIONNAIRE = {
|
119 |
"vitality": {
|
120 |
-
"title": "π Vitality & Energy",
|
|
|
121 |
"questions": [
|
122 |
{
|
123 |
"id": "vitality_energy",
|
@@ -131,7 +133,7 @@ HRQOL_QUESTIONNAIRE = {
|
|
131 |
]
|
132 |
},
|
133 |
{
|
134 |
-
"id": "vitality_play",
|
135 |
"text": "How often does your dog seek out play or interaction?",
|
136 |
"options": [
|
137 |
"Always seeks play/interaction",
|
@@ -157,6 +159,7 @@ HRQOL_QUESTIONNAIRE = {
|
|
157 |
},
|
158 |
"comfort": {
|
159 |
"title": "π Comfort & Pain Management",
|
|
|
160 |
"questions": [
|
161 |
{
|
162 |
"id": "comfort_activities",
|
@@ -196,6 +199,7 @@ HRQOL_QUESTIONNAIRE = {
|
|
196 |
},
|
197 |
"emotional_wellbeing": {
|
198 |
"title": "π Emotional Wellbeing",
|
|
|
199 |
"questions": [
|
200 |
{
|
201 |
"id": "emotion_mood",
|
@@ -235,6 +239,7 @@ HRQOL_QUESTIONNAIRE = {
|
|
235 |
},
|
236 |
"alertness": {
|
237 |
"title": "π§ Alertness & Cognition",
|
|
|
238 |
"questions": [
|
239 |
{
|
240 |
"id": "alert_awareness",
|
@@ -478,9 +483,41 @@ def get_healthspan_grade(score):
|
|
478 |
else:
|
479 |
return "Critical (F)"
|
480 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
481 |
def comprehensive_healthspan_analysis(input_type, image_input, video_input, breed, age, *hrqol_responses):
|
482 |
"""Combine image/video analysis with HRQOL assessment based on input type"""
|
483 |
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
# Determine which input to use based on dropdown selection
|
485 |
if input_type == "Image Analysis":
|
486 |
selected_media = image_input
|
@@ -489,14 +526,17 @@ def comprehensive_healthspan_analysis(input_type, image_input, video_input, bree
|
|
489 |
selected_media = video_input
|
490 |
media_type = "video"
|
491 |
else:
|
492 |
-
|
|
|
493 |
|
494 |
if selected_media is None:
|
495 |
-
|
|
|
496 |
|
497 |
# Check if questionnaire is completed
|
498 |
if not hrqol_responses or all(not r for r in hrqol_responses):
|
499 |
-
|
|
|
500 |
|
501 |
# Build HRQOL responses dictionary
|
502 |
response_keys = []
|
@@ -695,7 +735,7 @@ def comprehensive_healthspan_analysis(input_type, image_input, video_input, bree
|
|
695 |
</div>
|
696 |
"""
|
697 |
|
698 |
-
|
699 |
|
700 |
def update_media_input(input_type):
|
701 |
"""Update the visibility of media inputs based on dropdown selection"""
|
@@ -704,38 +744,147 @@ def update_media_input(input_type):
|
|
704 |
else: # Video Analysis
|
705 |
return gr.update(visible=False), gr.update(visible=True)
|
706 |
|
707 |
-
#
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
712 |
""")
|
713 |
|
714 |
with gr.Row():
|
715 |
-
# Left Column - Media Input
|
716 |
with gr.Column(scale=1):
|
717 |
-
gr.
|
|
|
|
|
|
|
|
|
|
|
|
|
718 |
|
719 |
-
#
|
720 |
input_type_dropdown = gr.Dropdown(
|
721 |
choices=["Image Analysis", "Video Analysis"],
|
722 |
-
label="Select Analysis Type",
|
723 |
value="Image Analysis",
|
724 |
-
interactive=True
|
|
|
725 |
)
|
726 |
|
727 |
-
# Media input components with
|
728 |
image_input = gr.Image(
|
729 |
type="pil",
|
730 |
-
label="Upload Dog Photo or Use Webcam",
|
731 |
visible=True,
|
732 |
-
sources=["upload", "webcam"]
|
|
|
733 |
)
|
734 |
|
735 |
video_input = gr.Video(
|
736 |
-
label="Upload Video (10-30 seconds) or Record with Webcam",
|
737 |
visible=False,
|
738 |
-
sources=["upload", "webcam"]
|
|
|
739 |
)
|
740 |
|
741 |
# Update visibility based on dropdown selection
|
@@ -745,73 +894,145 @@ with gr.Blocks(title="πΆ VetMetrica HRQOL Dog Health Analyzer", theme=gr.theme
|
|
745 |
outputs=[image_input, video_input]
|
746 |
)
|
747 |
|
748 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
749 |
breed_input = gr.Dropdown(
|
750 |
STANFORD_BREEDS,
|
751 |
-
label="Dog Breed (Auto-detected if not specified)",
|
752 |
value=None,
|
753 |
-
allow_custom_value=True
|
|
|
754 |
)
|
755 |
age_input = gr.Number(
|
756 |
-
label="Chronological Age (years)",
|
757 |
precision=1,
|
758 |
value=None,
|
759 |
minimum=0,
|
760 |
maximum=25
|
761 |
)
|
762 |
|
763 |
-
# Right Column - HRQOL Questionnaire
|
764 |
with gr.Column(scale=1):
|
765 |
-
gr.
|
766 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
767 |
|
768 |
hrqol_inputs = []
|
769 |
|
770 |
for domain_key, domain_data in HRQOL_QUESTIONNAIRE.items():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
771 |
with gr.Accordion(domain_data["title"], open=True):
|
772 |
for question in domain_data["questions"]:
|
773 |
-
|
|
|
774 |
choices=question["options"],
|
775 |
label=question["text"],
|
776 |
value=None,
|
777 |
-
interactive=True
|
|
|
778 |
)
|
779 |
-
hrqol_inputs.append(
|
|
|
|
|
|
|
|
|
|
|
780 |
|
781 |
-
# Analysis Button
|
782 |
analyze_button = gr.Button(
|
783 |
-
"π¬
|
784 |
variant="primary",
|
785 |
size="lg",
|
786 |
-
|
787 |
)
|
788 |
|
789 |
-
|
790 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
791 |
output_report = gr.HTML()
|
792 |
|
793 |
-
# Connect analysis function
|
794 |
analyze_button.click(
|
795 |
fn=comprehensive_healthspan_analysis,
|
796 |
inputs=[input_type_dropdown, image_input, video_input, breed_input, age_input] + hrqol_inputs,
|
797 |
outputs=output_report
|
798 |
)
|
799 |
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
815 |
""")
|
816 |
|
817 |
if __name__ == "__main__":
|
|
|
10 |
CLIPProcessor, CLIPModel,
|
11 |
AutoProcessor
|
12 |
)
|
13 |
+
import time
|
14 |
|
15 |
# βββββββββββββββββββββββββββββ
|
16 |
# CONFIG: set your HF token here or via env var HF_TOKEN
|
|
|
115 |
"wire-haired fox terrier": 13.5, "yorkshire terrier": 13.3
|
116 |
}
|
117 |
|
118 |
+
# 4. VetMetrica HRQOL Framework with dropdown options
|
119 |
HRQOL_QUESTIONNAIRE = {
|
120 |
"vitality": {
|
121 |
+
"title": "π Vitality & Energy Assessment",
|
122 |
+
"description": "Evaluate your dog's energy levels and enthusiasm for activities",
|
123 |
"questions": [
|
124 |
{
|
125 |
"id": "vitality_energy",
|
|
|
133 |
]
|
134 |
},
|
135 |
{
|
136 |
+
"id": "vitality_play",
|
137 |
"text": "How often does your dog seek out play or interaction?",
|
138 |
"options": [
|
139 |
"Always seeks play/interaction",
|
|
|
159 |
},
|
160 |
"comfort": {
|
161 |
"title": "π Comfort & Pain Management",
|
162 |
+
"description": "Assess signs of discomfort, pain, or mobility issues",
|
163 |
"questions": [
|
164 |
{
|
165 |
"id": "comfort_activities",
|
|
|
199 |
},
|
200 |
"emotional_wellbeing": {
|
201 |
"title": "π Emotional Wellbeing",
|
202 |
+
"description": "Evaluate mood, anxiety levels, and social engagement",
|
203 |
"questions": [
|
204 |
{
|
205 |
"id": "emotion_mood",
|
|
|
239 |
},
|
240 |
"alertness": {
|
241 |
"title": "π§ Alertness & Cognition",
|
242 |
+
"description": "Assess cognitive function, awareness, and responsiveness",
|
243 |
"questions": [
|
244 |
{
|
245 |
"id": "alert_awareness",
|
|
|
483 |
else:
|
484 |
return "Critical (F)"
|
485 |
|
486 |
+
def show_loading():
|
487 |
+
"""Display loading animation"""
|
488 |
+
return """
|
489 |
+
<div style="text-align: center; padding: 40px;">
|
490 |
+
<div style="display: inline-block; width: 40px; height: 40px; border: 4px solid #f3f3f3; border-top: 4px solid #667eea; border-radius: 50%; animation: spin 1s linear infinite;"></div>
|
491 |
+
<style>
|
492 |
+
@keyframes spin {
|
493 |
+
0% { transform: rotate(0deg); }
|
494 |
+
100% { transform: rotate(360deg); }
|
495 |
+
}
|
496 |
+
</style>
|
497 |
+
<h3 style="color: #667eea; margin-top: 20px;">π¬ Analyzing Your Dog's Health...</h3>
|
498 |
+
<p style="color: #666;">Please wait while we process the image/video and questionnaire data.</p>
|
499 |
+
<div style="background: #f0f0f0; border-radius: 20px; padding: 10px; margin: 20px auto; width: 300px;">
|
500 |
+
<div style="background: linear-gradient(90deg, #667eea, #764ba2); height: 6px; border-radius: 10px; width: 0%; animation: progress 3s ease-in-out infinite;"></div>
|
501 |
+
</div>
|
502 |
+
<style>
|
503 |
+
@keyframes progress {
|
504 |
+
0% { width: 0%; }
|
505 |
+
50% { width: 80%; }
|
506 |
+
100% { width: 100%; }
|
507 |
+
}
|
508 |
+
</style>
|
509 |
+
</div>
|
510 |
+
"""
|
511 |
+
|
512 |
def comprehensive_healthspan_analysis(input_type, image_input, video_input, breed, age, *hrqol_responses):
|
513 |
"""Combine image/video analysis with HRQOL assessment based on input type"""
|
514 |
|
515 |
+
# Show loading first
|
516 |
+
yield show_loading()
|
517 |
+
|
518 |
+
# Simulate processing time
|
519 |
+
time.sleep(2)
|
520 |
+
|
521 |
# Determine which input to use based on dropdown selection
|
522 |
if input_type == "Image Analysis":
|
523 |
selected_media = image_input
|
|
|
526 |
selected_media = video_input
|
527 |
media_type = "video"
|
528 |
else:
|
529 |
+
yield "β **Error**: Please select an input type."
|
530 |
+
return
|
531 |
|
532 |
if selected_media is None:
|
533 |
+
yield f"β **Error**: Please provide a {media_type} for analysis."
|
534 |
+
return
|
535 |
|
536 |
# Check if questionnaire is completed
|
537 |
if not hrqol_responses or all(not r for r in hrqol_responses):
|
538 |
+
yield "β **Error**: Please complete the HRQOL questionnaire before analysis."
|
539 |
+
return
|
540 |
|
541 |
# Build HRQOL responses dictionary
|
542 |
response_keys = []
|
|
|
735 |
</div>
|
736 |
"""
|
737 |
|
738 |
+
yield report_html
|
739 |
|
740 |
def update_media_input(input_type):
|
741 |
"""Update the visibility of media inputs based on dropdown selection"""
|
|
|
744 |
else: # Video Analysis
|
745 |
return gr.update(visible=False), gr.update(visible=True)
|
746 |
|
747 |
+
# Custom CSS for enhanced styling
|
748 |
+
custom_css = """
|
749 |
+
/* Enhanced gradient background */
|
750 |
+
.gradio-container {
|
751 |
+
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
752 |
+
min-height: 100vh;
|
753 |
+
}
|
754 |
+
|
755 |
+
/* Card styling */
|
756 |
+
.input-card, .questionnaire-card {
|
757 |
+
background: white;
|
758 |
+
border-radius: 15px;
|
759 |
+
padding: 25px;
|
760 |
+
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
|
761 |
+
margin: 10px;
|
762 |
+
border: 1px solid #e0e6ed;
|
763 |
+
}
|
764 |
+
|
765 |
+
/* Header styling */
|
766 |
+
.main-header {
|
767 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
768 |
+
color: white;
|
769 |
+
text-align: center;
|
770 |
+
padding: 30px;
|
771 |
+
border-radius: 15px;
|
772 |
+
margin-bottom: 30px;
|
773 |
+
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
|
774 |
+
}
|
775 |
+
|
776 |
+
/* Button styling */
|
777 |
+
.analyze-button {
|
778 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
779 |
+
border: none;
|
780 |
+
color: white;
|
781 |
+
padding: 15px 30px;
|
782 |
+
font-size: 16px;
|
783 |
+
font-weight: 600;
|
784 |
+
border-radius: 25px;
|
785 |
+
cursor: pointer;
|
786 |
+
transition: all 0.3s ease;
|
787 |
+
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
788 |
+
}
|
789 |
+
|
790 |
+
.analyze-button:hover {
|
791 |
+
transform: translateY(-2px);
|
792 |
+
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
|
793 |
+
}
|
794 |
+
|
795 |
+
/* Accordion styling */
|
796 |
+
.accordion-header {
|
797 |
+
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
798 |
+
border: 1px solid #dee2e6;
|
799 |
+
border-radius: 8px;
|
800 |
+
padding: 15px;
|
801 |
+
margin: 10px 0;
|
802 |
+
cursor: pointer;
|
803 |
+
transition: all 0.3s ease;
|
804 |
+
}
|
805 |
+
|
806 |
+
.accordion-header:hover {
|
807 |
+
background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
|
808 |
+
transform: translateY(-1px);
|
809 |
+
}
|
810 |
+
|
811 |
+
/* Dropdown styling */
|
812 |
+
.gr-dropdown {
|
813 |
+
border-radius: 8px;
|
814 |
+
border: 2px solid #e0e6ed;
|
815 |
+
transition: border-color 0.3s ease;
|
816 |
+
}
|
817 |
+
|
818 |
+
.gr-dropdown:focus {
|
819 |
+
border-color: #667eea;
|
820 |
+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
821 |
+
}
|
822 |
+
|
823 |
+
/* Progress animation */
|
824 |
+
@keyframes pulse {
|
825 |
+
0% { opacity: 1; }
|
826 |
+
50% { opacity: 0.5; }
|
827 |
+
100% { opacity: 1; }
|
828 |
+
}
|
829 |
+
|
830 |
+
.loading-pulse {
|
831 |
+
animation: pulse 2s infinite;
|
832 |
+
}
|
833 |
+
"""
|
834 |
+
|
835 |
+
# Gradio Interface with Enhanced UI
|
836 |
+
with gr.Blocks(
|
837 |
+
title="πΆ VetMetrica HRQOL Dog Health Analyzer",
|
838 |
+
theme=gr.themes.Soft(),
|
839 |
+
css=custom_css
|
840 |
+
) as demo:
|
841 |
+
|
842 |
+
# Main Header
|
843 |
+
gr.HTML("""
|
844 |
+
<div class="main-header">
|
845 |
+
<h1 style="margin: 0; font-size: 2.5em; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">
|
846 |
+
π VetMetricaΒ© HRQOL Dog Health & Age Analyzer
|
847 |
+
</h1>
|
848 |
+
<p style="margin: 15px 0 0 0; font-size: 1.2em; opacity: 0.9;">
|
849 |
+
AI-powered comprehensive analysis using validated Health-Related Quality of Life metrics
|
850 |
+
</p>
|
851 |
+
</div>
|
852 |
""")
|
853 |
|
854 |
with gr.Row():
|
855 |
+
# Left Column - Enhanced Media Input
|
856 |
with gr.Column(scale=1):
|
857 |
+
gr.HTML("""
|
858 |
+
<div class="input-card">
|
859 |
+
<h2 style="color: #667eea; margin: 0 0 20px 0; text-align: center;">
|
860 |
+
πΈ Media Input Selection
|
861 |
+
</h2>
|
862 |
+
</div>
|
863 |
+
""")
|
864 |
|
865 |
+
# Enhanced dropdown with better styling
|
866 |
input_type_dropdown = gr.Dropdown(
|
867 |
choices=["Image Analysis", "Video Analysis"],
|
868 |
+
label="π Select Analysis Type",
|
869 |
value="Image Analysis",
|
870 |
+
interactive=True,
|
871 |
+
elem_classes=["gr-dropdown"]
|
872 |
)
|
873 |
|
874 |
+
# Media input components with enhanced labels
|
875 |
image_input = gr.Image(
|
876 |
type="pil",
|
877 |
+
label="π· Upload Dog Photo or Use Webcam",
|
878 |
visible=True,
|
879 |
+
sources=["upload", "webcam"],
|
880 |
+
height=300
|
881 |
)
|
882 |
|
883 |
video_input = gr.Video(
|
884 |
+
label="π₯ Upload Video (10-30 seconds) or Record with Webcam",
|
885 |
visible=False,
|
886 |
+
sources=["upload", "webcam"],
|
887 |
+
height=300
|
888 |
)
|
889 |
|
890 |
# Update visibility based on dropdown selection
|
|
|
894 |
outputs=[image_input, video_input]
|
895 |
)
|
896 |
|
897 |
+
# Enhanced optional information section
|
898 |
+
gr.HTML("""
|
899 |
+
<div style="margin: 20px 0;">
|
900 |
+
<h3 style="color: #667eea; text-align: center; margin-bottom: 15px;">
|
901 |
+
βοΈ Optional Information
|
902 |
+
</h3>
|
903 |
+
</div>
|
904 |
+
""")
|
905 |
+
|
906 |
breed_input = gr.Dropdown(
|
907 |
STANFORD_BREEDS,
|
908 |
+
label="π Dog Breed (Auto-detected if not specified)",
|
909 |
value=None,
|
910 |
+
allow_custom_value=True,
|
911 |
+
elem_classes=["gr-dropdown"]
|
912 |
)
|
913 |
age_input = gr.Number(
|
914 |
+
label="π
Chronological Age (years)",
|
915 |
precision=1,
|
916 |
value=None,
|
917 |
minimum=0,
|
918 |
maximum=25
|
919 |
)
|
920 |
|
921 |
+
# Right Column - Enhanced HRQOL Questionnaire
|
922 |
with gr.Column(scale=1):
|
923 |
+
gr.HTML("""
|
924 |
+
<div class="questionnaire-card">
|
925 |
+
<h2 style="color: #667eea; margin: 0 0 10px 0; text-align: center;">
|
926 |
+
π VetMetricaΒ© HRQOL Assessment
|
927 |
+
</h2>
|
928 |
+
<p style="text-align: center; color: #666; font-style: italic; margin-bottom: 20px;">
|
929 |
+
Complete all sections for accurate healthspan analysis
|
930 |
+
</p>
|
931 |
+
</div>
|
932 |
+
""")
|
933 |
|
934 |
hrqol_inputs = []
|
935 |
|
936 |
for domain_key, domain_data in HRQOL_QUESTIONNAIRE.items():
|
937 |
+
# Enhanced accordion header
|
938 |
+
gr.HTML(f"""
|
939 |
+
<div class="accordion-header">
|
940 |
+
<h3 style="margin: 0; color: #333;">
|
941 |
+
{domain_data['title']}
|
942 |
+
</h3>
|
943 |
+
<p style="margin: 5px 0 0 0; color: #666; font-size: 0.9em;">
|
944 |
+
{domain_data['description']}
|
945 |
+
</p>
|
946 |
+
</div>
|
947 |
+
""")
|
948 |
+
|
949 |
with gr.Accordion(domain_data["title"], open=True):
|
950 |
for question in domain_data["questions"]:
|
951 |
+
# Enhanced dropdown for each question
|
952 |
+
dropdown = gr.Dropdown(
|
953 |
choices=question["options"],
|
954 |
label=question["text"],
|
955 |
value=None,
|
956 |
+
interactive=True,
|
957 |
+
elem_classes=["gr-dropdown"]
|
958 |
)
|
959 |
+
hrqol_inputs.append(dropdown)
|
960 |
+
|
961 |
+
# Enhanced Analysis Button
|
962 |
+
gr.HTML("""
|
963 |
+
<div style="text-align: center; margin: 30px 0;">
|
964 |
+
""")
|
965 |
|
|
|
966 |
analyze_button = gr.Button(
|
967 |
+
"π¬ Analyze Comprehensive Healthspan",
|
968 |
variant="primary",
|
969 |
size="lg",
|
970 |
+
elem_classes=["analyze-button"]
|
971 |
)
|
972 |
|
973 |
+
gr.HTML("</div>")
|
974 |
+
|
975 |
+
# Enhanced Results Section
|
976 |
+
gr.HTML("""
|
977 |
+
<div style="text-align: center; margin: 30px 0 10px 0;">
|
978 |
+
<h2 style="color: #667eea; margin: 0;">
|
979 |
+
π Comprehensive HRQOL Analysis Report
|
980 |
+
</h2>
|
981 |
+
</div>
|
982 |
+
""")
|
983 |
+
|
984 |
output_report = gr.HTML()
|
985 |
|
986 |
+
# Connect analysis function with loading
|
987 |
analyze_button.click(
|
988 |
fn=comprehensive_healthspan_analysis,
|
989 |
inputs=[input_type_dropdown, image_input, video_input, breed_input, age_input] + hrqol_inputs,
|
990 |
outputs=output_report
|
991 |
)
|
992 |
|
993 |
+
# Enhanced About Section
|
994 |
+
gr.HTML("""
|
995 |
+
<div style="background: white; border-radius: 15px; padding: 25px; margin: 30px 0; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
|
996 |
+
<h2 style="color: #667eea; text-align: center; margin-bottom: 20px;">
|
997 |
+
π¬ About VetMetricaΒ© HRQOL Framework
|
998 |
+
</h2>
|
999 |
+
|
1000 |
+
<p style="text-align: center; margin-bottom: 25px; color: #666; font-size: 1.1em;">
|
1001 |
+
This tool integrates the validated <strong>VetMetricaΒ© Health-Related Quality of Life</strong> framework with advanced AI analysis:
|
1002 |
+
</p>
|
1003 |
+
|
1004 |
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin: 25px 0;">
|
1005 |
+
<div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
|
1006 |
+
<div style="font-size: 2em; margin-bottom: 10px;">π―</div>
|
1007 |
+
<h4 style="color: #667eea; margin-bottom: 10px;">Evidence-Based Assessment</h4>
|
1008 |
+
<p style="color: #666; font-size: 0.9em;">Uses clinically validated HRQOL domains (Vitality, Comfort, Emotional Wellbeing, Alertness)</p>
|
1009 |
+
</div>
|
1010 |
+
|
1011 |
+
<div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
|
1012 |
+
<div style="font-size: 2em; margin-bottom: 10px;">π€</div>
|
1013 |
+
<h4 style="color: #667eea; margin-bottom: 10px;">AI-Powered Analysis</h4>
|
1014 |
+
<p style="color: #666; font-size: 0.9em;">Combines CLIP vision models with BiomedCLIP for medical insights</p>
|
1015 |
+
</div>
|
1016 |
+
|
1017 |
+
<div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
|
1018 |
+
<div style="font-size: 2em; margin-bottom: 10px;">π</div>
|
1019 |
+
<h4 style="color: #667eea; margin-bottom: 10px;">Comprehensive Scoring</h4>
|
1020 |
+
<p style="color: #666; font-size: 0.9em;">Generates composite healthspan scores normalized by breed and age</p>
|
1021 |
+
</div>
|
1022 |
+
|
1023 |
+
<div style="text-align: center; padding: 20px; background: #f8f9fa; border-radius: 10px;">
|
1024 |
+
<div style="font-size: 2em; margin-bottom: 10px;">πΈπ₯</div>
|
1025 |
+
<h4 style="color: #667eea; margin-bottom: 10px;">Multi-Modal Input</h4>
|
1026 |
+
<p style="color: #666; font-size: 0.9em;">Both image and video analysis support upload and real-time webcam capture</p>
|
1027 |
+
</div>
|
1028 |
+
</div>
|
1029 |
+
|
1030 |
+
<div style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 8px; padding: 15px; margin: 20px 0;">
|
1031 |
+
<p style="margin: 0; color: #856404; text-align: center;">
|
1032 |
+
<strong>β οΈ Medical Disclaimer:</strong> This tool provides educational insights only. Always consult a qualified veterinarian for professional medical advice.
|
1033 |
+
</p>
|
1034 |
+
</div>
|
1035 |
+
</div>
|
1036 |
""")
|
1037 |
|
1038 |
if __name__ == "__main__":
|