-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadd_faces.py
More file actions
151 lines (120 loc) · 4.69 KB
/
add_faces.py
File metadata and controls
151 lines (120 loc) · 4.69 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import cv2
import pickle
import numpy as np
import os
import pyttsx3
# Add to top
import argparse
# Remove these lines:
# speak_message("Please enter your name.")
# name = input("Enter Your Name: ")
# speak_message("Please enter your ID.")
# user_id = input("Enter Your ID: ")
# Initialize the text-to-speech engine
engine = pyttsx3.init()
engine.setProperty('rate', 150) # Speed of speech
engine.setProperty('volume', 1.0) # Volume level (0.0 to 1.0)
def speak_message(message):
"""Function to speak a message using pyttsx3."""
print(message) # Print the message to the console
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")
faces_data = []
i = 0
# Replace input() with argparse
parser = argparse.ArgumentParser()
parser.add_argument('--name', required=True)
parser.add_argument('--id', required=True)
args = parser.parse_args()
name = args.name
user_id = args.id
# Check if the ID already exists
data_dir = 'data'
if os.path.exists(data_dir):
if os.path.exists(os.path.join(data_dir, 'ids.pkl')):
with open(os.path.join(data_dir, 'ids.pkl'), 'rb') as f:
existing_ids = pickle.load(f)
if user_id in existing_ids:
speak_message(f"ID {user_id} already exists. Exiting the program.")
exit()
else:
os.makedirs(data_dir)
# Initialize the list for names and ids
names = []
ids = []
speak_message("Starting facial data collection. Please look at the camera.")
while True:
# Read each frame from the video
ret, frame = video.read()
# Check if the frame was captured successfully
if not ret:
speak_message("Failed to capture frame. Exiting the program.")
break
# Convert the frame to grayscale
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Detect faces in the frame
faces = face_detect.detectMultiScale(gray, 1.3, 5)
# Draw rectangles around detected faces and add text
for (x, y, w, h) in faces:
crop_img = frame[y:y + h, x:x + w]
resize_img = cv2.resize(crop_img, (50, 50))
if len(faces_data) < 100 and i % 10 == 0:
faces_data.append(resize_img)
names.append(name)
ids.append(user_id)
i += 1
# Draw name above the face rectangle
cv2.putText(frame, name, (x, y - 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2)
# Draw ID below the name
cv2.putText(frame, f"ID: {user_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)
# Display collection status
cv2.putText(frame, f"Faces Collected: {len(faces_data)}/100", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2)
# Display the frame
cv2.imshow("Frame", frame)
# Exit the loop when 'q' key is pressed or when 100 faces are collected
k = cv2.waitKey(1)
if k == ord('q') or len(faces_data) == 100:
speak_message("Facial data collection completed. Saving your data.")
break
# Release video capture and destroy windows
video.release()
cv2.destroyAllWindows()
# Convert faces_data to numpy array and flatten each image
faces_data = np.array(faces_data)
faces_data = faces_data.reshape(len(faces_data), -1)
# Save names, IDs, and faces data
if not os.path.exists(os.path.join(data_dir, 'names.pkl')):
with open(os.path.join(data_dir, 'names.pkl'), 'wb') as f:
pickle.dump(names, f)
with open(os.path.join(data_dir, 'ids.pkl'), 'wb') as f:
pickle.dump(ids, f)
else:
with open(os.path.join(data_dir, 'names.pkl'), 'rb') as f:
existing_names = pickle.load(f)
with open(os.path.join(data_dir, 'ids.pkl'), 'rb') as f:
existing_ids = pickle.load(f)
existing_names += names
existing_ids += ids
with open(os.path.join(data_dir, 'names.pkl'), 'wb') as f:
pickle.dump(existing_names, f)
with open(os.path.join(data_dir, 'ids.pkl'), 'wb') as f:
pickle.dump(existing_ids, f)
# Save faces data
if not os.path.exists(os.path.join(data_dir, 'faces_data.pkl')):
with open(os.path.join(data_dir, 'faces_data.pkl'), 'wb') as f:
pickle.dump(faces_data, f)
else:
with open(os.path.join(data_dir, 'faces_data.pkl'), 'rb') as f:
existing_faces = pickle.load(f)
existing_faces = np.append(existing_faces, faces_data, axis=0)
with open(os.path.join(data_dir, 'faces_data.pkl'), 'wb') as f:
pickle.dump(existing_faces, f)
speak_message("Your facial data has been saved successfully. Thank you!")