-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.py
More file actions
129 lines (103 loc) · 3.92 KB
/
test.py
File metadata and controls
129 lines (103 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from sklearn.neighbors import KNeighborsClassifier
import cv2
import pickle
import numpy as np
import os
import csv
import time
from datetime import datetime
import pyttsx3
import sys
sys.stderr = sys.stdout # Redirect stderr to stdout for Flask
def speak_message(message):
engine = pyttsx3.init()
engine.setProperty('rate', 150)
engine.setProperty('volume', 1)
engine.say(message)
engine.runAndWait()
# Start video capture
video = cv2.VideoCapture(0)
# Load the Haar Cascade classifier for face detection
face_detect = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
# Load the stored data
try:
with open('data/names.pkl', 'rb') as f:
all_names = pickle.load(f)
with open('data/ids.pkl', 'rb') as f:
all_ids = pickle.load(f)
with open('data/faces_data.pkl', 'rb') as f:
FACES = pickle.load(f)
except FileNotFoundError:
speak_message("Data files not found. Please register faces first.")
exit()
# Check if FACES array is empty
if len(FACES) == 0:
speak_message("No facial data found. Please register faces first.")
exit()
# Create a mapping from ID to Name (use first occurrence)
id_to_name = {}
for user_id, name in zip(all_ids, all_names):
if user_id not in id_to_name:
id_to_name[user_id] = name
# Train KNN with IDs as labels
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(FACES, all_ids) # Use IDs for training
COL_NAMES = ["ID", "NAME", "TIME"]
speak_message("Press P to take attendance.")
speak_message("Press Q to exit.")
while True:
ret, frame = video.read()
if not ret:
print("Failed to capture frame. Exiting...")
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_detect.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
attendance = None # Initialize attendance outside the loop
for (x, y, w, h) in faces:
crop_img = frame[y:y + h, x:x + w]
resize_img = cv2.resize(crop_img, (50, 50)).flatten().reshape(1, -1)
# Predict the ID
person_id = knn.predict(resize_img)[0]
person_name = id_to_name.get(person_id, "Unknown")
ts = time.time()
date = datetime.fromtimestamp(ts).strftime("%d-%m-%Y")
timestamp = datetime.fromtimestamp(ts).strftime("%H-%M-%S")
file_path = os.path.join("Attendance", f"Attendance_{date}.csv")
cv2.putText(frame, f"{person_name} ({person_id})", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
attendance = [person_id, person_name, timestamp]
cv2.imshow("Face Recognition", frame)
k = cv2.waitKey(1)
if k == ord('p') or k == ord('P'):
if attendance is None:
speak_message("No face detected for attendance.")
continue
# Ensure the directory exists
os.makedirs("Attendance", exist_ok=True)
file_exists = os.path.isfile(file_path)
already_marked = False
# Check if attendance already taken
if file_exists:
with open(file_path, "r", newline="") as csvfile:
reader = csv.reader(csvfile)
# Skip header
next(reader, None)
for row in reader:
if row[0] == str(attendance[0]):
already_marked = True
break
if already_marked:
speak_message(f"{attendance[1]} has already taken attendance.")
else:
with open(file_path, "a", newline="") as csvfile:
writer = csv.writer(csvfile)
if not file_exists:
writer.writerow(COL_NAMES)
writer.writerow(attendance)
speak_message(f"Attendance for {attendance[1]} is taken.")
if k == ord('q'):
speak_message("Exiting the program.")
break
video.release()
cv2.destroyAllWindows()