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 |