Advertisement
dan-masek

Cleaned up https://stackoverflow.com/q/77551372/3962537

Nov 26th, 2023
1,488
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.49 KB | None | 0 0
  1. import face_recognition
  2. import os, sys
  3. import cv2
  4. import numpy as np
  5. import pandas as pd
  6. import datetime
  7. import traceback
  8.  
  9. class FaceRecognition:
  10.     def __init__(self):
  11.         self.known_face_encodings, self.known_face_names = self.encode_faces()
  12.         self.attendance_df = self.load_or_create_attendance_file()
  13.         self.process_current_frame = True
  14.         self.color_border = (0, 0, 255)
  15.         self.color_text = (255, 255, 255)
  16.         self.process_scale = 0.25
  17.  
  18.     def encode_faces(self):
  19.         known_face_encodings = []
  20.         known_face_names = []
  21.  
  22.         for image in os.listdir('faces'):
  23.             face_image = face_recognition.load_image_file(f'./faces/{image}')
  24.             face_encodings = face_recognition.face_encodings(face_image)
  25.  
  26.             if len(face_encodings) > 0:
  27.                 known_face_encodings.append(face_encodings[0])
  28.                 known_face_names.append(image.split('.')[0])
  29.  
  30.         print("Known faces:", known_face_names)
  31.         return known_face_encodings, known_face_names
  32.    
  33.     def load_or_create_attendance_file(self):
  34.         attendance_file_path = 'attendance.xlsx'
  35.  
  36.         if os.path.exists(attendance_file_path):
  37.             return pd.read_excel(attendance_file_path, index_col=0)
  38.         else:
  39.             # Create a new DataFrame with student names
  40.             student_names = [name.split('.')[0] for name in os.listdir('faces')]
  41.             attendance_df = pd.DataFrame(index=student_names, columns=['Date'])
  42.             attendance_df.to_excel(attendance_file_path)
  43.             return attendance_df
  44.  
  45.     def mark_attendance(self, name):
  46.         today = datetime.date.today().strftime("%Y-%m-%d")
  47.         if today not in self.attendance_df.columns:
  48.             self.attendance_df[today] = ''
  49.  
  50.         self.attendance_df.at[name, today] = 'p'
  51.         self.attendance_df.to_excel('attendance.xlsx')
  52.        
  53.     def process_frame(self, frame):
  54.         face_locations = face_recognition.face_locations(frame)
  55.         if not face_locations:
  56.             print("No faces found.")
  57.             return []
  58.  
  59.         print(f"Found {len(face_locations)} face(s): {face_locations}")
  60.  
  61.         face_encodings = face_recognition.face_encodings(frame, face_locations)
  62.  
  63.         found_faces = []
  64.         for i, face_encoding in enumerate(face_encodings):
  65.             print(f"* Analyzing face #{i}")
  66.            
  67.             matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding)
  68.             face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding)
  69.             best_match_index = np.argmin(face_distances)
  70.            
  71.             print(f"** Best #{best_match_index} | {list(zip(face_distances, matches))}")
  72.             if matches[best_match_index]:
  73.                 name = self.known_face_names[best_match_index]
  74.                 found_faces.append((name, face_locations[i]))
  75.                 print(f"   -> Matched as {name}")
  76.             else:
  77.                 print("   -> No good match.")
  78.                
  79.         return found_faces
  80.        
  81.     def draw_annotation(self, frame, name, position):
  82.         (top, right, bottom, left) = map(lambda x: 4 * x, position)
  83.  
  84.         cv2.rectangle(frame, (left, top), (right, bottom + 35), self.color_border , 2)
  85.         cv2.rectangle(frame, (left, bottom), (right, bottom + 35), self.color_border , -1)
  86.         cv2.putText(frame, name, (left + 6, bottom + 35 - 6), cv2.FONT_HERSHEY_DUPLEX, 0.8, self.color_text, 1)
  87.        
  88.         return frame
  89.  
  90.     def run_recognition(self, video_file):
  91.         video_file_path = os.path.abspath(video_file)
  92.  
  93.         if not os.path.exists(video_file_path):
  94.             raise FileNotFoundError(f"Video file not found: {video_file_path}")
  95.  
  96.         video_capture = cv2.VideoCapture(video_file_path)
  97.         if not video_capture.isOpened():
  98.             raise RuntimeError(f"Unable to read file: {video_file_path}")
  99.  
  100.         try:
  101.             frame_number = -1
  102.             while True:
  103.                 frame_number += 1
  104.                 ret, frame = video_capture.read()
  105.                 if not ret:
  106.                     print("Video capture completed. Exiting...")
  107.                     break
  108.  
  109.                 if self.process_current_frame:
  110.                     print(f"Frame #{frame_number} -- ", end="")
  111.                     small_frame = cv2.resize(frame, None, fx=self.process_scale, fy=self.process_scale)
  112.                     rgb_small_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB)
  113.                    
  114.                     found_faces = self.process_frame(rgb_small_frame)
  115.                    
  116.                     for name, position in found_faces:
  117.                         print(f"* Marking attendance for {name}")
  118.                         self.mark_attendance(name)
  119.                         self.draw_annotation(frame, name, position)
  120.  
  121.                 # self.process_current_frame = not self.process_current_frame
  122.                 cv2.putText(frame, f"Frame {frame_number}", (10, 40), cv2.FONT_HERSHEY_DUPLEX, 1.0, self.color_text, 1)
  123.                 cv2.imshow("Face Recognition", frame)
  124.                 if cv2.waitKey(1) == ord('q'):
  125.                     break
  126.         except Exception as e:
  127.             print("An error occurred. Full backtrace:")
  128.             traceback.print_exc()
  129.         finally:
  130.             video_capture.release()
  131.             cv2.destroyAllWindows()
  132.  
  133. if __name__ == "__main__":
  134.     video_file_path = 'video.mp4'
  135.     fr = FaceRecognition()
  136.     fr.run_recognition(video_file_path)
  137.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement