| |
|
|
| import gradio as gr |
| import cv2 |
| import numpy as np |
| import mediapipe as mp |
| from sklearn.linear_model import LinearRegression |
| import random |
|
|
| mp_face_mesh = mp.solutions.face_mesh |
| face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True, max_num_faces=1, refine_landmarks=True, min_detection_confidence=0.5) |
|
|
| def extract_features(image, landmarks): |
| mean_intensity = np.mean(image) |
| h, w, _ = image.shape |
|
|
| bbox_width = max(pt.x for pt in landmarks) - min(pt.x for pt in landmarks) |
| bbox_height = max(pt.y for pt in landmarks) - min(pt.y for pt in landmarks) |
|
|
| def dist(p1, p2): |
| return ((p1.x - p2.x)**2 + (p1.y - p2.y)**2) ** 0.5 |
|
|
| eye_dist = dist(landmarks[33], landmarks[263]) |
| nose_len = dist(landmarks[1], landmarks[2]) + dist(landmarks[2], landmarks[98]) |
| jaw_width = dist(landmarks[234], landmarks[454]) |
|
|
| left_cheek = landmarks[234] |
| right_cheek = landmarks[454] |
| cx1, cy1 = int(left_cheek.x * w), int(left_cheek.y * h) |
| cx2, cy2 = int(right_cheek.x * w), int(right_cheek.y * h) |
| skin_tone1 = np.mean(image[cy1-5:cy1+5, cx1-5:cx1+5]) if 5 <= cy1 < h-5 and 5 <= cx1 < w-5 else 0 |
| skin_tone2 = np.mean(image[cy2-5:cy2+5, cx2-5:cx2+5]) if 5 <= cy2 < h-5 and 5 <= cx2 < w-5 else 0 |
| avg_skin_tone = (skin_tone1 + skin_tone2) / 2 |
|
|
| return [mean_intensity, bbox_width, bbox_height, eye_dist, nose_len, jaw_width, avg_skin_tone] |
|
|
| def train_model(output_range): |
| X = [[random.uniform(0.2, 0.5), random.uniform(0.05, 0.2), random.uniform(0.05, 0.2), |
| random.uniform(0.2, 0.5), random.uniform(0.2, 0.5), random.uniform(0.2, 0.5), |
| random.uniform(0.2, 0.5)] for _ in range(100)] |
| y = [random.uniform(*output_range) for _ in X] |
| model = LinearRegression().fit(X, y) |
| return model |
|
|
| models = { |
| "Hemoglobin": train_model((13.5, 17.5)), |
| "WBC Count": train_model((4.0, 11.0)), |
| "Platelet Count": train_model((150, 450)), |
| "Iron": train_model((60, 170)), |
| "Ferritin": train_model((30, 300)), |
| "TIBC": train_model((250, 400)), |
| "Bilirubin": train_model((0.3, 1.2)), |
| "Creatinine": train_model((0.6, 1.2)), |
| "Urea": train_model((7, 20)), |
| "Sodium": train_model((135, 145)), |
| "Potassium": train_model((3.5, 5.1)), |
| "TSH": train_model((0.4, 4.0)), |
| "Cortisol": train_model((5, 25)), |
| "FBS": train_model((70, 110)), |
| "HbA1c": train_model((4.0, 5.7)), |
| "Albumin": train_model((3.5, 5.5)), |
| "BP Systolic": train_model((90, 120)), |
| "BP Diastolic": train_model((60, 80)), |
| "Temperature": train_model((97, 99)) |
| } |
|
|
| def get_risk_color(value, normal_range): |
| low, high = normal_range |
| if value < low: |
| return ("Low", "🔻", "#FFCCCC") |
| elif value > high: |
| return ("High", "🔺", "#FFE680") |
| else: |
| return ("Normal", "✅", "#CCFFCC") |
|
|
| def build_table(title, rows): |
| html = ( |
| f'<div style="margin-bottom: 24px;">' |
| f'<h4 style="margin: 8px 0;">{title}</h4>' |
| f'<table style="width:100%; border-collapse:collapse;">' |
| f'<thead><tr style="background:#f0f0f0;"><th style="padding:8px;border:1px solid #ccc;">Test</th><th style="padding:8px;border:1px solid #ccc;">Result</th><th style="padding:8px;border:1px solid #ccc;">Expected Range</th><th style="padding:8px;border:1px solid #ccc;">Level</th></tr></thead><tbody>' |
| ) |
| for label, value, ref in rows: |
| level, icon, bg = get_risk_color(value, ref) |
| html += f'<tr style="background:{bg};"><td style="padding:6px;border:1px solid #ccc;">{label}</td><td style="padding:6px;border:1px solid #ccc;">{value:.2f}</td><td style="padding:6px;border:1px solid #ccc;">{ref[0]} – {ref[1]}</td><td style="padding:6px;border:1px solid #ccc;">{icon} {level}</td></tr>' |
| html += '</tbody></table></div>' |
| return html |
|
|