File size: 6,587 Bytes
0983def
eb3d3f0
 
 
9905bc8
 
c3d57ff
eb3d3f0
420f765
eb3d3f0
0983def
eb3d3f0
420f765
9905bc8
39eef5a
 
 
 
71a8976
 
 
39eef5a
 
9905bc8
420f765
9905bc8
360e696
 
 
9905bc8
 
 
 
c3d57ff
 
 
 
 
 
 
 
 
f04f718
420f765
9905bc8
31ad924
9905bc8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420f765
7e2c1f5
 
 
accfefd
7e2c1f5
accfefd
7e2c1f5
accfefd
 
420f765
9e64c66
 
 
 
 
 
 
 
 
9905bc8
9e64c66
 
19e69ba
1974ae8
 
 
420f765
1974ae8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19e69ba
1974ae8
 
 
 
 
 
 
19e69ba
1974ae8
19e69ba
420f765
19e69ba
 
1974ae8
 
19e69ba
 
1974ae8
 
 
 
 
10c366b
1974ae8
f8f4a14
fcb6cb8
1974ae8
19e69ba
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import gradio as gr
import cv2
import numpy as np
import mediapipe as mp
from sklearn.linear_model import LinearRegression
import random
import pickle

# Setup for Face Mesh detection
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)

# Function to extract color features from the image
def extract_features(image, landmarks):
    red_channel = image[:, :, 2]
    green_channel = image[:, :, 1]
    blue_channel = image[:, :, 0]

    red_percent = 100 * np.mean(red_channel) / 255
    green_percent = 100 * np.mean(green_channel) / 255
    blue_percent = 100 * np.mean(blue_channel) / 255

    return [red_percent, green_percent, blue_percent]

# Mock models training (for demonstration)
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

# Load pre-trained models for Hemoglobin, SPO2, and Heart Rate using pickle
with open("hemoglobin_model_from_anemia_dataset.pkl", "rb") as f:
    hemoglobin_model = pickle.load(f)

with open("spo2_model_simulated.pkl", "rb") as f:
    spo2_model = pickle.load(f)

with open("heart_rate_model.pkl", "rb") as f:
    hr_model = pickle.load(f)

# Model dictionary setup for other tests
models = {
    "Hemoglobin": hemoglobin_model,
    "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))
}

# Function to determine risk level
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")

# Function to build an HTML table for displaying test results
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

# Analyzing image for health metrics
def analyze_image(image):
    frame_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    result = face_mesh.process(frame_rgb)
    if not result.multi_face_landmarks:
        return "<div style='color:red;'>⚠️ Face not detected in image.</div>", frame_rgb
    landmarks = result.multi_face_landmarks[0].landmark
    features = extract_features(frame_rgb, landmarks)
    test_values = {}
    r2_scores = {}
    for label in models:
        if label == "Hemoglobin":
            prediction = models[label].predict([features])[0]
            test_values[label] = prediction
            r2_scores[label] = hemoglobin_r2
        else:
            value = models[label].predict([[random.uniform(0.2, 0.5) for _ in range(7)]])[0]
            test_values[label] = value
            r2_scores[label] = 0.0  # simulate other 7D inputs

    html_output = "".join([
        f'<div style="font-size:14px;color:#888;margin-bottom:10px;">Hemoglobin R² Score: {r2_scores.get("Hemoglobin", "NA"):.2f}</div>',
        build_table("🩸 Hematology", [("Hemoglobin", test_values["Hemoglobin"], (13.5, 17.5)), ("WBC Count", test_values["WBC Count"], (4.0, 11.0)), ("Platelet Count", test_values["Platelet Count"], (150, 450))]),
        build_table("🧬 Iron Panel", [("Iron", test_values["Iron"], (60, 170)), ("Ferritin", test_values["Ferritin"], (30, 300)), ("TIBC", test_values["TIBC"], (250, 400))]),
        build_table("🧬 Liver & Kidney", [("Bilirubin", test_values["Bilirubin"], (0.3, 1.2)), ("Creatinine", test_values["Creatinine"], (0.6, 1.2)), ("Urea", test_values["Urea"], (7, 20))]),
        build_table("🧪 Electrolytes", [("Sodium", test_values["Sodium"], (135, 145)), ("Potassium", test_values["Potassium"], (3.5, 5.1))]),
        build_table("🧁 Metabolic & Thyroid", [("FBS", test_values["FBS"], (70, 110)), ("HbA1c", test_values["HbA1c"], (4.0, 5.7)), ("TSH", test_values["TSH"], (0.4, 4.0))]),
        build_table("❤️ Vitals", [("SpO2", test_values["SpO2"], (95, 100)), ("Heart Rate", test_values["Heart Rate"], (60, 100)), ("Temperature", test_values["Temperature"], (97, 99)), ("BP Systolic", test_values["BP Systolic"], (90, 120))]),
    ])
    return html_output, frame_rgb

# Gradio Interface setup
with gr.Blocks() as demo:
    gr.Markdown("""
    # 🧠 Face-Based Lab Test AI Report (Image Mode)
    Upload a face image to infer health diagnostics using AI-based analysis.
    """)
    with gr.Row():
        image_input = gr.Image(type="numpy", label="📸 Upload Face Image")
        submit_btn = gr.Button("🔍 Analyze")
    with gr.Column():
        result_html = gr.HTML(label="🧪 Health Report Table")
        result_image = gr.Image(label="📷 Key Frame Snapshot")

    submit_btn.click(fn=analyze_image, inputs=image_input, outputs=[result_html, result_image])

    gr.Markdown("""---
✅ Table Format • AI Prediction • Dynamic Summary""")

demo.launch()