FaceAuthViz / app.py
Pranesh64's picture
Update app.py
3122e55 verified
import gradio as gr
import numpy as np
import cv2
import plotly.graph_objects as go
from sklearn.metrics.pairwise import cosine_distances
# =========================
# FACE SETUP
# =========================
face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
)
def extract_face(image):
if image is None:
return None, None
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
if len(faces) == 0:
return image, None
x, y, w, h = faces[0]
cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)
face = cv2.resize(gray[y:y+h, x:x+w], (64,64))
return image, face.flatten()
def embed(face):
vec = face @ np.random.randn(face.shape[0], 128)
return vec / np.linalg.norm(vec)
# =========================
# STEP FUNCTIONS
# =========================
def step_detect(img):
img, _ = extract_face(img)
return img
def step_enroll(img):
img, face = extract_face(img)
if face is None:
return img, None, "❌ No face detected"
emb = embed(face)
return img, emb, "βœ… Face enrolled"
def step_verify(img, stored):
img, face = extract_face(img)
if face is None or stored is None:
return img, "❌ Missing data", None
live = embed(face)
dist = cosine_distances([stored], [live])[0][0]
status = "πŸ”“ UNLOCKED" if dist < 0.35 else "πŸ”’ DENIED"
fig = go.Figure(go.Indicator(
mode="gauge+number",
value=dist,
title={"text": status},
gauge={"axis": {"range": [0, 1]}}
))
return img, f"Distance: {dist:.3f}", fig
# =========================
# UI
# =========================
with gr.Blocks(theme=gr.themes.Soft()) as demo:
page = gr.State(0)
stored_embedding = gr.State()
gr.Markdown("# πŸ” Face Unlock β€” How Mobile Face ID Works")
with gr.Row():
back = gr.Button("β¬… Back")
nextb = gr.Button("Next ➑")
# ---------- PAGE 0 ----------
page0 = gr.Column(visible=True)
with page0:
gr.Markdown("## πŸ“Έ Face Detection")
cam0 = gr.Image(sources=["webcam"], type="numpy")
out0 = gr.Image()
gr.Button("Detect Face").click(step_detect, cam0, out0)
# ---------- PAGE 1 ----------
page1 = gr.Column(visible=False)
with page1:
gr.Markdown("## 🧠 Face Enrollment")
cam1 = gr.Image(sources=["webcam"], type="numpy")
out1 = gr.Image()
msg1 = gr.Markdown()
gr.Button("Enroll Face").click(
step_enroll,
cam1,
[out1, stored_embedding, msg1]
)
# ---------- PAGE 2 ----------
page2 = gr.Column(visible=False)
with page2:
gr.Markdown("## πŸ”“ Face Verification")
cam2 = gr.Image(sources=["webcam"], type="numpy")
out2 = gr.Image()
msg2 = gr.Markdown()
gauge = gr.Plot()
gr.Button("Verify").click(
step_verify,
[cam2, stored_embedding],
[out2, msg2, gauge]
)
# =========================
# NAVIGATION
# =========================
def navigate(p, step):
p = min(2, max(0, p + step))
return (
p,
gr.update(visible=p == 0),
gr.update(visible=p == 1),
gr.update(visible=p == 2)
)
back.click(navigate, [page, gr.State(-1)], [page, page0, page1, page2])
nextb.click(navigate, [page, gr.State(1)], [page, page0, page1, page2])
demo.launch()