Spaces:
Runtime error
Runtime error
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 |