attendance / app.py
Rasleen's picture
Update app.py
0b20aa4 verified
raw
history blame
5.28 kB
import os
import cv2
import torch
import numpy as np
import streamlit as st
import requests
from PIL import Image
from glob import glob
from insightface.app import FaceAnalysis
import torch.nn.functional as F
# Set the device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Global Variables
IMAGE_SHAPE = 640
data_path = 'employees'
webcam_path = 'captured_image.jpg'
# Set Streamlit title
st.title("AIML-Student Attendance System")
# Load employee image paths
image_paths = glob(os.path.join(data_path, '*.jpg'))
# Initialize Face Analysis
app = FaceAnalysis(name="buffalo_l") # ArcFace model
app.prepare(ctx_id=0 if torch.cuda.is_available() else -1, det_size=(IMAGE_SHAPE, IMAGE_SHAPE))
# Define function to match face embeddings
def prod_function(app, prod_path, webcam_img_pil):
np_webcam = np.array(webcam_img_pil)
cv2_webcam = cv2.cvtColor(np_webcam, cv2.COLOR_RGB2BGR)
webcam_faces = app.get(cv2_webcam)
if not webcam_faces:
return [], cv2_webcam
results = []
for webcam_face in webcam_faces:
webcam_emb = torch.tensor(webcam_face.embedding, dtype=torch.float32)
similarity_scores = []
for path in prod_path:
img = cv2.imread(path)
faces = app.get(img, max_num=1)
if not faces:
similarity_scores.append(torch.tensor(-1.0))
continue
face_emb = torch.tensor(faces[0].embedding, dtype=torch.float32)
score = F.cosine_similarity(face_emb, webcam_emb, dim=0)
similarity_scores.append(score)
similarity_scores = torch.stack(similarity_scores)
best_match_idx = torch.argmax(similarity_scores)
best_score = similarity_scores[best_match_idx].item()
# Get coordinates
x1, y1, x2, y2 = [int(i) for i in webcam_face.bbox]
if best_score >= 0.6:
matched_name = os.path.basename(prod_path[best_match_idx]).split('.')[0]
else:
matched_name = "Unknown"
results.append({'bbox': (x1, y1, x2, y2), 'name': matched_name})
return results, cv2_webcam
# Streamlit tabs
about_tab, app_tab, register_tab = st.tabs(["About the app", "Face Recognition", "Register new Student"])
with about_tab:
st.markdown("""
# πŸ‘οΈβ€πŸ—¨οΈ AI-Powered Face Recognition Attendance System
Secure and Accurate Attendance using Vision Transformer + ArcFace Embeddings.
- **Automated, contactless attendance logging**
- **Uses InsightFace ArcFace embeddings for recognition**
- **Real-time logging with confidence scoring**
- **Future Scope: Mask-aware recognition, Group detection, and more**
""")
with app_tab:
enable = st.checkbox("Enable camera")
picture = st.camera_input("Take a picture", disabled=not enable)
if picture is not None:
with st.spinner("Analyzing face..."):
image_pil = Image.open(picture)
matches, image_bgr = prod_function(app, image_paths, image_pil)
if not matches:
st.warning("No face detected in the captured image.")
else:
# st.write("Similarity Scores:", prediction_scores)
for match in matches:
x1, y1, x2, y2 = match['bbox']
matched_name = match['name']
color = (0, 255, 0) if matched_name != "Unknown" else (0, 0, 255)
cv2.rectangle(image_bgr, (x1, y1), (x2, y2), color, 2)
cv2.putText(image_bgr, matched_name, (x1, y2 + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
if matched_name != "Unknown":
# recognized = False
# for score, idx in matches:
# if matched_score >= 0.6:
# matched_name = os.path.basename(image_paths[match_idx]).split('.')[0]
# st.success(f"βœ… Welcome: {matched_name}")
# recognizes=True
# Send attendance via POST
url = "https://nielit-attendance.glitch.me/adds"
data = {'rno': 15, 'sname': matched_name, 'sclass': 7}
try:
response = requests.post(url, data=data)
if response.status_code == 200:
st.success(f"Attendance marked successfully for {matched_name}.")
else:
st.warning(f"Failed to update attendance for {matched_name}.")
except Exception as e:
st.error(f"Request failed: {e}")
else:
st.warning("❌ Face match not found or too low confidence.")
# Convert back to RGB for display
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
st.image(image_rgb, caption="Detected Faces", use_container_width=True)