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)