Spaces:
Sleeping
Sleeping
File size: 3,196 Bytes
278cde5 | 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 | import gradio as gr
import os
import numpy as np
from PIL import Image
from sklearn.metrics.pairwise import cosine_similarity
import insightface
from insightface.app import FaceAnalysis
# -----------------------------
# Setup directories
# -----------------------------
os.makedirs("registered_faces", exist_ok=True)
os.makedirs("embeddings", exist_ok=True)
# -----------------------------
# Load ArcFace Model (InsightFace)
# -----------------------------
app = FaceAnalysis(name="buffalo_l") # ArcFace best model set
app.prepare(ctx_id=0, det_size=(640, 640)) # ctx_id=0 uses GPU if available, else CPU
# -----------------------------
# Helper: Generate Embedding
# -----------------------------
def get_embedding(image):
img = np.array(image)
faces = app.get(img)
if len(faces) == 0:
return None, "β No face detected. Try another image."
# Take first detected face
embedding = faces[0].embedding
return embedding, None
# -----------------------------
# Register New Face
# -----------------------------
def register_face(name, image):
if not name:
return "β οΈ Please enter a name."
embedding, error = get_embedding(image)
if embedding is None:
return error
# Save image & embedding
image.save(f"registered_faces/{name}.jpg")
np.save(f"embeddings/{name}.npy", embedding)
return f"β
Registered {name} successfully!"
# -----------------------------
# Recognize Face
# -----------------------------
def recognize_face(image):
embedding, error = get_embedding(image)
if embedding is None:
return error
best_match = None
highest_score = 0
for file in os.listdir("embeddings"):
if file.endswith(".npy"):
saved_emb = np.load(os.path.join("embeddings", file))
score = cosine_similarity([embedding], [saved_emb])[0][0]
if score > highest_score:
highest_score = score
best_match = file.replace(".npy", "")
# Threshold decision
if best_match and highest_score > 0.60:
return f"π’ Match Found: **{best_match}** (Similarity: {highest_score:.2f})"
return f"π΄ No match found. Best score = {highest_score:.2f}"
# -----------------------------
# Gradio UI
# -----------------------------
with gr.Blocks(title="Face Recognition Attendance System") as demo:
gr.Markdown("## π§ Facial Recognition System (ArcFace Based)")
gr.Markdown("Upload a face to register or recognize.")
with gr.Tab("π Register Employee"):
name_input = gr.Textbox(label="Employee Name")
reg_image = gr.Image(label="Upload Face", type="pil")
reg_button = gr.Button("Register")
reg_output = gr.Textbox(label="Status")
reg_button.click(register_face, inputs=[name_input, reg_image], outputs=reg_output)
with gr.Tab("π Recognize Face"):
recog_image = gr.Image(label="Upload Face", type="pil")
recog_button = gr.Button("Recognize")
recog_output = gr.Textbox(label="Result")
recog_button.click(recognize_face, inputs=recog_image, outputs=recog_output)
demo.launch(server_name="0.0.0.0", server_port=7860)
|