import face_recognition import os import cv2 import numpy as np import math import sys import time def face_confidence(face_distance, face_match_threshold=0.6): range = (1.0 - face_match_threshold) linear_val = (1.0 - face_distance) / (range * 2.0) if face_distance < face_match_threshold: return str(round(linear_val * 100, 2)) + "%" else: value = (linear_val + ((1.0 - linear_val) * math.pow((linear_val - 0.5) * 2, 0.2))) * 100 return str(round(value, 2)) + "%" class FaceRecognition: face_locations = [] face_encodings = [] face_names = [] known_face_encodings = [] known_face_names = [] process_current_frame = True def __init__(self): self.encode_faces() def encode_faces(self): for image in os.listdir("faces"): face_image = face_recognition.load_image_file(f'faces/{image}') face_encoding = face_recognition.face_encodings(face_image)[0] self.known_face_encodings.append(face_encoding) self.known_face_names.append(image.split(".")[0]) print(self.known_face_names) def run_recognition(self): video_capture = cv2.VideoCapture(0) # Set the window to normal so it can be resized cv2.namedWindow('Face Attendance', cv2.WINDOW_NORMAL) # Set the window to full screen cv2.setWindowProperty('Face Attendance', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) if not video_capture.isOpened(): sys.exit('Video capture is not opened') no_face_timer = 0 no_face_threshold = 2 # Adjust this to your desired timeout in seconds while True: ret, frame = video_capture.read() if self.process_current_frame: small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) rgb_small_frame = small_frame[:, :, ::-1] self.face_locations = face_recognition.face_locations(rgb_small_frame) if not self.face_locations: no_face_timer += 1 else: no_face_timer = 0 if no_face_timer >= no_face_threshold * 30: # 30 frames per second # Close the OpenCV window after the timeout break self.face_encodings = face_recognition.face_encodings(rgb_small_frame, self.face_locations) self.face_names = [] for face_encoding in self.face_encodings: matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding) name = "Unknown" confidence = 'Unknown' face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding) best_match_index = np.argmin(face_distances) if matches[best_match_index]: confidence = face_confidence(face_distances[best_match_index]) if float(confidence.split("%")[0]) > 55: name = self.known_face_names[best_match_index] confidence = face_confidence(face_distances[best_match_index]) else: name = "Unknown" confidence = 'Unknown' self.face_names.append(f'{name} {confidence}') self.process_current_frame = not self.process_current_frame for (top, right, bottom, left), name in zip(self.face_locations, self.face_names): top *= 4 right *= 4 bottom *= 4 left *= 4 cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), -1) font = cv2.FONT_HERSHEY_DUPLEX cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.8, (255, 255, 255), 1) cv2.imshow('Face Attendance', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break video_capture.release() cv2.destroyAllWindows() if __name__ == '__main__': fr = FaceRecognition() fr.run_recognition()