Attendance_system / attendance_system.py
PRIYANSHUDHAKED's picture
Upload attendance_system.py
5c3953f verified
import os
import logging
from typing import List, Tuple, Optional
import face_recognition
import numpy as np
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
class AttendanceSystem:
def __init__(self, database_dir: str):
self.database_dir = database_dir
self.database = self._load_database()
def _load_database(self) -> dict:
database = {}
for filename in os.listdir(self.database_dir):
if filename.endswith(('.jpg', '.jpeg', '.png')):
roll_number = os.path.splitext(filename)[0]
image_path = os.path.join(self.database_dir, filename)
try:
image = face_recognition.load_image_file(image_path)
encodings = face_recognition.face_encodings(image)
if encodings:
database[roll_number] = encodings[0]
else:
logging.warning(f"No face found in {filename}. Skipping.")
except Exception as e:
logging.error(f"Error processing {filename}: {str(e)}")
return database
def process_classroom_image(self, image_path: str) -> List[Tuple[str, float]]:
try:
classroom_image = face_recognition.load_image_file(image_path)
except Exception as e:
logging.error(f"Error loading classroom image: {str(e)}")
return []
face_locations = face_recognition.face_locations(classroom_image)
if not face_locations:
logging.warning("No faces detected in the classroom image.")
return []
face_encodings = face_recognition.face_encodings(classroom_image, face_locations)
matches = []
for face_encoding in face_encodings:
match = self._find_best_match(face_encoding)
if match:
matches.append(match)
return matches
def _find_best_match(self, face_encoding: np.ndarray) -> Optional[Tuple[str, float]]:
best_match = None
best_distance = float('inf')
for roll_number, known_encoding in self.database.items():
distance = face_recognition.face_distance([known_encoding], face_encoding)[0]
if distance < best_distance:
best_distance = distance
best_match = (roll_number, distance)
if best_match and best_match[1] < 0.6: # Adjust this threshold as needed
return best_match
return None
def record_attendance(self, course: str, date: str, classroom_image_path: str) -> List[str]:
matches = self.process_classroom_image(classroom_image_path)
present_students = [roll_number for roll_number, _ in matches]
logging.info(f"Recorded attendance for {len(present_students)} students in {course} on {date}")
return present_students
def add_to_database(self, roll_number: str, image_path: str) -> bool:
try:
image = face_recognition.load_image_file(image_path)
encodings = face_recognition.face_encodings(image)
if encodings:
self.database[roll_number] = encodings[0]
logging.info(f"Added {roll_number} to the database successfully.")
return True
else:
logging.warning(f"No face found in the image for {roll_number}. Not added to database.")
return False
except Exception as e:
logging.error(f"Error adding {roll_number} to database: {str(e)}")
return False