File size: 5,767 Bytes
a737654 4935acb add9725 4935acb add9725 4935acb add9725 4935acb add9725 4935acb add9725 4935acb add9725 4935acb a737654 4935acb add9725 4935acb a737654 4935acb add9725 4935acb a737654 add9725 a737654 4935acb a295265 25d0af1 38077a1 4935acb a737654 add9725 4935acb add9725 4935acb add9725 4935acb add9725 a737654 4935acb a737654 | 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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | import gradio as gr
from api import check_liveness
EXAMPLE_IMAGES = [
["assets/1.jpg"],
["assets/2.jpg"],
["assets/3.jpg"],
["assets/4.jpg"],
["assets/5.jpg"],
["assets/6.jpg"],
]
def _normalize_keys(d: dict) -> dict:
return {k.strip().replace(" ", "_"): v for k, v in d.items()}
def _format_result_html(result: dict) -> str:
r = _normalize_keys(result)
liveness_text = r.get("liveness_result", "").lower()
is_genuine = "genuine" in liveness_text
probability = r.get("probability", 0)
if isinstance(probability, str):
try:
probability = float(probability)
except (ValueError, TypeError):
probability = 0
score = r.get("score", 0)
if isinstance(score, str):
try:
score = float(score)
except (ValueError, TypeError):
score = 0
quality = r.get("quality", 0)
if isinstance(quality, str):
try:
quality = float(quality)
except (ValueError, TypeError):
quality = 0
pct = round(max(0, min(probability, 1)) * 100)
if is_genuine:
badge_text = "✅ GENUINE / LIVE"
badge_color = "#059669"
bg_color = "#ecfdf5"
border_color = "#a7f3d0"
score_color = "#059669"
else:
badge_text = "❌ SPOOF / FAKE"
badge_color = "#dc2626"
bg_color = "#fef2f2"
border_color = "#fecaca"
score_color = "#dc2626"
html = f"""
<div style="padding: 12px 0;">
<div style="background: {bg_color}; border: 2px solid {border_color};
border-radius: 16px; padding: 24px;">
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 20px;">
<span style="font-size: 22px; font-weight: 700; color: #1e293b;">
Liveness Result
</span>
</div>
<div style="display: inline-block; padding: 8px 24px; border-radius: 999px;
background: {badge_color}; color: white; font-weight: 700;
font-size: 18px; letter-spacing: 0.5px; margin-bottom: 20px;">
{badge_text}
</div>
<div style="margin-top: 16px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 6px;">
<span style="font-weight: 600; color: #475569;">Confidence</span>
<span style="font-weight: 700; color: {score_color};">{pct}%</span>
</div>
<div style="background: #e2e8f0; border-radius: 999px; height: 10px; overflow: hidden;">
<div style="width: {pct}%; height: 100%; background: {badge_color};
border-radius: 999px;"></div>
</div>
</div>
<div style="margin-top: 14px; display: flex; gap: 24px;">
<div>
<span style="font-size: 13px; color: #94a3b8;">Quality</span>
<div style="font-weight: 600; color: #334155;">
{round(quality * 100)}%
</div>
</div>
<div>
<span style="font-size: 13px; color: #94a3b8;">Score</span>
<div style="font-weight: 600; color: #334155;">
{score:.4f}
</div>
</div>
<div>
<span style="font-size: 13px; color: #94a3b8;">Status</span>
<div style="font-weight: 600; color: #334155;">
{r.get("state", "")}
</div>
</div>
</div>
</div>
</div>
"""
return html
def process_image(image):
if image is None:
return (
'<div style="padding:20px;text-align:center;color:#94a3b8;">'
"Upload or select an example image</div>",
{"error": "No image provided"},
)
result = check_liveness(image)
if "error" in result:
return (
f'<div style="padding:20px;text-align:center;color:#dc2626;">{result["error"]}</div>',
result,
)
return _format_result_html(result), result
def create_interface():
with gr.Blocks(
title="MiniAiLive Face Liveness Detection",
theme=gr.themes.Soft(
primary_hue="emerald",
neutral_hue="slate",
),
css="""
footer {display: none !important;}
""",
) as demo:
gr.Markdown(
"""
# 🥇 MiniAiLive Face Liveness Detection
**3D Passive Face Liveness Detection · Face Anti-Spoofing** ·
<a href="https://miniai.live/face-liveness-detection/">For more details: please visit our website</a>
Upload a face image or click an example below to check liveness.
"""
)
with gr.Row(equal_height=False):
with gr.Column(scale=1, min_width=400):
image_input = gr.Image(label="Upload Image")
submit_btn = gr.Button(
"Check Liveness", variant="primary", size="lg"
)
gr.Examples(
examples=EXAMPLE_IMAGES,
inputs=image_input,
label="Example Images",
)
with gr.Column(scale=1, min_width=400):
result_html = gr.HTML(label="Result")
raw_json = gr.JSON(label="Raw Response")
submit_btn.click(
fn=process_image,
inputs=image_input,
outputs=[result_html, raw_json],
)
return demo
|