Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -767,6 +767,16 @@ def show_loading():
|
|
767 |
</style>
|
768 |
<h3 style="color: #667eea; margin-top: 20px;">π¬ Analyzing Your Dog's Health...</h3>
|
769 |
<p style="color: #666;">Please wait while we process the image/video and questionnaire data using enhanced AI models.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
770 |
</div>
|
771 |
"""
|
772 |
|
@@ -1067,7 +1077,7 @@ def update_media_input(input_type):
|
|
1067 |
else: # Video Analysis
|
1068 |
return gr.update(visible=False), gr.update(visible=True)
|
1069 |
|
1070 |
-
# Custom CSS for
|
1071 |
custom_css = """
|
1072 |
/* Enhanced gradient background */
|
1073 |
.gradio-container {
|
@@ -1075,26 +1085,16 @@ custom_css = """
|
|
1075 |
min-height: 100vh;
|
1076 |
}
|
1077 |
|
1078 |
-
/* Card styling
|
1079 |
.input-card, .questionnaire-card {
|
1080 |
background: white;
|
1081 |
border-radius: 15px;
|
1082 |
-
padding:
|
1083 |
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
|
1084 |
-
margin:
|
1085 |
border: 1px solid #e0e6ed;
|
1086 |
}
|
1087 |
|
1088 |
-
/* Clean questionnaire card */
|
1089 |
-
.clean-questionnaire-card {
|
1090 |
-
background: white;
|
1091 |
-
border-radius: 12px;
|
1092 |
-
padding: 25px;
|
1093 |
-
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
1094 |
-
margin: 10px 0;
|
1095 |
-
border: 1px solid #e8e9ea;
|
1096 |
-
}
|
1097 |
-
|
1098 |
/* Header styling */
|
1099 |
.main-header {
|
1100 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
@@ -1102,7 +1102,7 @@ custom_css = """
|
|
1102 |
text-align: center;
|
1103 |
padding: 30px;
|
1104 |
border-radius: 15px;
|
1105 |
-
margin-bottom:
|
1106 |
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
|
1107 |
}
|
1108 |
|
@@ -1125,67 +1125,47 @@ custom_css = """
|
|
1125 |
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
|
1126 |
}
|
1127 |
|
1128 |
-
/*
|
1129 |
-
.
|
1130 |
-
|
1131 |
-
border: 1px solid #
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
.clean-dropdown:focus {
|
1139 |
-
border-color: #667eea !important;
|
1140 |
-
box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1) !important;
|
1141 |
-
}
|
1142 |
-
|
1143 |
-
/* Clean form styling */
|
1144 |
-
.clean-form {
|
1145 |
-
gap: 16px !important;
|
1146 |
}
|
1147 |
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
border: 1px solid #e2e8f0;
|
1152 |
-
border-radius: 6px;
|
1153 |
-
padding: 16px;
|
1154 |
-
margin: 16px 0 8px 0;
|
1155 |
-
border-left: 4px solid #667eea;
|
1156 |
}
|
1157 |
|
1158 |
-
/*
|
1159 |
-
.
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
margin-bottom: 6px !important;
|
1164 |
-
line-height: 1.4 !important;
|
1165 |
}
|
1166 |
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
padding: 4px !important;
|
1171 |
}
|
1172 |
|
1173 |
-
/*
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
|
|
1177 |
}
|
1178 |
|
1179 |
-
|
1180 |
-
|
1181 |
-
height: 1px;
|
1182 |
-
background: #e5e7eb;
|
1183 |
-
margin: 20px 0;
|
1184 |
-
border: none;
|
1185 |
}
|
1186 |
"""
|
1187 |
|
1188 |
-
#
|
1189 |
with gr.Blocks(
|
1190 |
title="πΆ Enhanced AI Dog Health Analyzer",
|
1191 |
theme=gr.themes.Soft(),
|
@@ -1215,13 +1195,16 @@ with gr.Blocks(
|
|
1215 |
</div>
|
1216 |
""")
|
1217 |
|
|
|
1218 |
input_type_dropdown = gr.Dropdown(
|
1219 |
choices=["Image Analysis", "Video Analysis"],
|
1220 |
label="π Select Analysis Type",
|
1221 |
value="Image Analysis",
|
1222 |
-
interactive=True
|
|
|
1223 |
)
|
1224 |
|
|
|
1225 |
image_input = gr.Image(
|
1226 |
type="pil",
|
1227 |
label="π· Upload Dog Photo or Use Webcam",
|
@@ -1237,12 +1220,14 @@ with gr.Blocks(
|
|
1237 |
height=300
|
1238 |
)
|
1239 |
|
|
|
1240 |
input_type_dropdown.change(
|
1241 |
fn=update_media_input,
|
1242 |
inputs=[input_type_dropdown],
|
1243 |
outputs=[image_input, video_input]
|
1244 |
)
|
1245 |
|
|
|
1246 |
gr.HTML("""
|
1247 |
<div style="margin: 20px 0;">
|
1248 |
<h3 style="color: #667eea; text-align: center; margin-bottom: 15px;">
|
@@ -1255,7 +1240,8 @@ with gr.Blocks(
|
|
1255 |
STANFORD_BREEDS,
|
1256 |
label="π Dog Breed (Auto-detected if not specified)",
|
1257 |
value=None,
|
1258 |
-
allow_custom_value=True
|
|
|
1259 |
)
|
1260 |
age_input = gr.Number(
|
1261 |
label="π
Chronological Age (years)",
|
@@ -1265,68 +1251,49 @@ with gr.Blocks(
|
|
1265 |
maximum=25
|
1266 |
)
|
1267 |
|
1268 |
-
# Right Column -
|
1269 |
with gr.Column(scale=1):
|
1270 |
-
# Clean questionnaire header
|
1271 |
gr.HTML("""
|
1272 |
-
<div class="
|
1273 |
-
<
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
</p>
|
1280 |
-
</div>
|
1281 |
</div>
|
1282 |
""")
|
1283 |
|
1284 |
hrqol_inputs = []
|
1285 |
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
# Clean question form field
|
1301 |
for question in domain_data["questions"]:
|
1302 |
-
#
|
1303 |
-
gr.HTML(f"""
|
1304 |
-
<div style="margin: 16px 0;">
|
1305 |
-
<label style="display: block; font-size: 0.95em; font-weight: 500; color: #374151; margin-bottom: 8px; line-height: 1.4;">
|
1306 |
-
{question["text"]}
|
1307 |
-
</label>
|
1308 |
-
</div>
|
1309 |
-
""")
|
1310 |
-
|
1311 |
dropdown = gr.Dropdown(
|
1312 |
choices=question["options"],
|
1313 |
-
label="",
|
1314 |
-
placeholder="Select your answer...",
|
1315 |
value=None,
|
1316 |
interactive=True,
|
1317 |
-
|
1318 |
-
elem_classes=["clean-dropdown"]
|
1319 |
)
|
1320 |
hrqol_inputs.append(dropdown)
|
1321 |
-
|
1322 |
-
# Clean separator between sections (except last)
|
1323 |
-
if i < len(HRQOL_QUESTIONNAIRE) - 1:
|
1324 |
-
gr.HTML('<hr class="clean-separator">')
|
1325 |
|
1326 |
-
#
|
1327 |
gr.HTML("""
|
1328 |
<div style="text-align: center; margin: 30px 0;">
|
1329 |
-
<div style="background: white; padding: 20px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.08); margin: 0 10px;">
|
1330 |
""")
|
1331 |
|
1332 |
analyze_button = gr.Button(
|
@@ -1336,10 +1303,7 @@ with gr.Blocks(
|
|
1336 |
elem_classes=["analyze-button"]
|
1337 |
)
|
1338 |
|
1339 |
-
gr.HTML(""
|
1340 |
-
</div>
|
1341 |
-
</div>
|
1342 |
-
""")
|
1343 |
|
1344 |
# Enhanced Results Section
|
1345 |
output_report = gr.HTML()
|
|
|
767 |
</style>
|
768 |
<h3 style="color: #667eea; margin-top: 20px;">π¬ Analyzing Your Dog's Health...</h3>
|
769 |
<p style="color: #666;">Please wait while we process the image/video and questionnaire data using enhanced AI models.</p>
|
770 |
+
<div style="background: #f0f0f0; border-radius: 20px; padding: 10px; margin: 20px auto; width: 300px;">
|
771 |
+
<div style="background: linear-gradient(90deg, #667eea, #764ba2); height: 6px; border-radius: 10px; width: 0%; animation: progress 3s ease-in-out infinite;"></div>
|
772 |
+
</div>
|
773 |
+
<style>
|
774 |
+
@keyframes progress {
|
775 |
+
0% { width: 0%; }
|
776 |
+
50% { width: 80%; }
|
777 |
+
100% { width: 100%; }
|
778 |
+
}
|
779 |
+
</style>
|
780 |
</div>
|
781 |
"""
|
782 |
|
|
|
1077 |
else: # Video Analysis
|
1078 |
return gr.update(visible=False), gr.update(visible=True)
|
1079 |
|
1080 |
+
# Custom CSS for enhanced styling
|
1081 |
custom_css = """
|
1082 |
/* Enhanced gradient background */
|
1083 |
.gradio-container {
|
|
|
1085 |
min-height: 100vh;
|
1086 |
}
|
1087 |
|
1088 |
+
/* Card styling */
|
1089 |
.input-card, .questionnaire-card {
|
1090 |
background: white;
|
1091 |
border-radius: 15px;
|
1092 |
+
padding: 25px;
|
1093 |
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
|
1094 |
+
margin: 10px;
|
1095 |
border: 1px solid #e0e6ed;
|
1096 |
}
|
1097 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1098 |
/* Header styling */
|
1099 |
.main-header {
|
1100 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
1102 |
text-align: center;
|
1103 |
padding: 30px;
|
1104 |
border-radius: 15px;
|
1105 |
+
margin-bottom: 30px;
|
1106 |
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
|
1107 |
}
|
1108 |
|
|
|
1125 |
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
|
1126 |
}
|
1127 |
|
1128 |
+
/* Accordion styling */
|
1129 |
+
.accordion-header {
|
1130 |
+
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
1131 |
+
border: 1px solid #dee2e6;
|
1132 |
+
border-radius: 8px;
|
1133 |
+
padding: 15px;
|
1134 |
+
margin: 10px 0;
|
1135 |
+
cursor: pointer;
|
1136 |
+
transition: all 0.3s ease;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1137 |
}
|
1138 |
|
1139 |
+
.accordion-header:hover {
|
1140 |
+
background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
|
1141 |
+
transform: translateY(-1px);
|
|
|
|
|
|
|
|
|
|
|
1142 |
}
|
1143 |
|
1144 |
+
/* Dropdown styling */
|
1145 |
+
.gr-dropdown {
|
1146 |
+
border-radius: 8px;
|
1147 |
+
border: 2px solid #e0e6ed;
|
1148 |
+
transition: border-color 0.3s ease;
|
|
|
|
|
1149 |
}
|
1150 |
|
1151 |
+
.gr-dropdown:focus {
|
1152 |
+
border-color: #667eea;
|
1153 |
+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
|
|
1154 |
}
|
1155 |
|
1156 |
+
/* Progress animation */
|
1157 |
+
@keyframes pulse {
|
1158 |
+
0% { opacity: 1; }
|
1159 |
+
50% { opacity: 0.5; }
|
1160 |
+
100% { opacity: 1; }
|
1161 |
}
|
1162 |
|
1163 |
+
.loading-pulse {
|
1164 |
+
animation: pulse 2s infinite;
|
|
|
|
|
|
|
|
|
1165 |
}
|
1166 |
"""
|
1167 |
|
1168 |
+
# Gradio Interface with Enhanced UI
|
1169 |
with gr.Blocks(
|
1170 |
title="πΆ Enhanced AI Dog Health Analyzer",
|
1171 |
theme=gr.themes.Soft(),
|
|
|
1195 |
</div>
|
1196 |
""")
|
1197 |
|
1198 |
+
# Enhanced dropdown with better styling
|
1199 |
input_type_dropdown = gr.Dropdown(
|
1200 |
choices=["Image Analysis", "Video Analysis"],
|
1201 |
label="π Select Analysis Type",
|
1202 |
value="Image Analysis",
|
1203 |
+
interactive=True,
|
1204 |
+
elem_classes=["gr-dropdown"]
|
1205 |
)
|
1206 |
|
1207 |
+
# Media input components with enhanced labels
|
1208 |
image_input = gr.Image(
|
1209 |
type="pil",
|
1210 |
label="π· Upload Dog Photo or Use Webcam",
|
|
|
1220 |
height=300
|
1221 |
)
|
1222 |
|
1223 |
+
# Update visibility based on dropdown selection
|
1224 |
input_type_dropdown.change(
|
1225 |
fn=update_media_input,
|
1226 |
inputs=[input_type_dropdown],
|
1227 |
outputs=[image_input, video_input]
|
1228 |
)
|
1229 |
|
1230 |
+
# Enhanced optional information section
|
1231 |
gr.HTML("""
|
1232 |
<div style="margin: 20px 0;">
|
1233 |
<h3 style="color: #667eea; text-align: center; margin-bottom: 15px;">
|
|
|
1240 |
STANFORD_BREEDS,
|
1241 |
label="π Dog Breed (Auto-detected if not specified)",
|
1242 |
value=None,
|
1243 |
+
allow_custom_value=True,
|
1244 |
+
elem_classes=["gr-dropdown"]
|
1245 |
)
|
1246 |
age_input = gr.Number(
|
1247 |
label="π
Chronological Age (years)",
|
|
|
1251 |
maximum=25
|
1252 |
)
|
1253 |
|
1254 |
+
# Right Column - SHORTENED HRQOL Questionnaire
|
1255 |
with gr.Column(scale=1):
|
|
|
1256 |
gr.HTML("""
|
1257 |
+
<div class="questionnaire-card">
|
1258 |
+
<h2 style="color: #667eea; margin: 0 0 10px 0; text-align: center;">
|
1259 |
+
π Streamlined HRQOL Assessment
|
1260 |
+
</h2>
|
1261 |
+
<p style="text-align: center; color: #666; font-style: italic; margin-bottom: 20px;">
|
1262 |
+
Complete all 4 comprehensive questions for accurate healthspan analysis
|
1263 |
+
</p>
|
|
|
|
|
1264 |
</div>
|
1265 |
""")
|
1266 |
|
1267 |
hrqol_inputs = []
|
1268 |
|
1269 |
+
for domain_key, domain_data in HRQOL_QUESTIONNAIRE.items():
|
1270 |
+
# Enhanced accordion header
|
1271 |
+
gr.HTML(f"""
|
1272 |
+
<div class="accordion-header">
|
1273 |
+
<h3 style="margin: 0; color: #333;">
|
1274 |
+
{domain_data['title']}
|
1275 |
+
</h3>
|
1276 |
+
<p style="margin: 5px 0 0 0; color: #666; font-size: 0.9em;">
|
1277 |
+
{domain_data['description']}
|
1278 |
+
</p>
|
1279 |
+
</div>
|
1280 |
+
""")
|
1281 |
+
|
1282 |
+
with gr.Accordion(domain_data["title"], open=True):
|
|
|
1283 |
for question in domain_data["questions"]:
|
1284 |
+
# Enhanced dropdown for each question
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1285 |
dropdown = gr.Dropdown(
|
1286 |
choices=question["options"],
|
1287 |
+
label=question["text"],
|
|
|
1288 |
value=None,
|
1289 |
interactive=True,
|
1290 |
+
elem_classes=["gr-dropdown"]
|
|
|
1291 |
)
|
1292 |
hrqol_inputs.append(dropdown)
|
|
|
|
|
|
|
|
|
1293 |
|
1294 |
+
# Enhanced Analysis Button
|
1295 |
gr.HTML("""
|
1296 |
<div style="text-align: center; margin: 30px 0;">
|
|
|
1297 |
""")
|
1298 |
|
1299 |
analyze_button = gr.Button(
|
|
|
1303 |
elem_classes=["analyze-button"]
|
1304 |
)
|
1305 |
|
1306 |
+
gr.HTML("</div>")
|
|
|
|
|
|
|
1307 |
|
1308 |
# Enhanced Results Section
|
1309 |
output_report = gr.HTML()
|