This project uses of cv2, re, pandas, pillow, os, pickle libraries of python with Haar cascade as the classifier. It contains into two files, "Training_data.py" for preparing data and training the model, another one "face_detection.py" for classifying faces based on training data trained from file "Training_data.py".
Refer file "Training_data.py" for code:
path = os.path.dirname(file) cascade = cv2.CascadeClassifier(os.path.join(path,"hcascade.xml"))
The above code takes the path of the current working directory for saving, creating, and searching the files that are further used in the project. The "hcascade.xml" file attached along with the source code gets loaded into the cascade variable.
for root,dirs,files in os.walk(os.path.join(path,"Im")):
# Iterating over all the images to train the face recogniser
for file in files:
# Selection of only .png and .jpg files
if file.endswith('png') or file.endswith('jpg'):
# Storing path of the image file
img_path = os.path.join(root,file)
# Storing label
label = os.path.basename(img_path)
label = label.split('.')[0]
# Storing the label in dictionary
if label not in label_dict.keys():
label_dict[label] = curr_id
curr_id += 1
_id = label_dict[label]
# Converting the image to Gray scale and converting into numpy array
img = Image.open(img_path).convert("L")
np_img = np.array(img)
# Face detection bias
faces = cascade_classifier.detectMultiScale(
np_img,
scaleFactor=1.3,
minNeighbors=2
)
for x,y,w,h in faces:
# Region of interest of the face
roi_img = np_img[y:y+h, x:x+w]
# Appending array with image data
x_img.append(roi_img)
y_label.append(_id)
The above code snnipet iterates over the directory "Im" to find the files ending with .jpg or .png format and stores the name of the image as a label to create a dictionary "label_dict". Faces store the coordinates/points for faces of the images to be used for the training set.
Image with the region of interest is stored in form of NumPy array in the "x_img" list and the label of the image in the "y_label" list.
recogniser = cv2.face.LBPHFaceRecognizer_create()
recogniser.train(x_img,np.array(y_label))
recogniser.save(os.path.join(path,"Train.yml"))
with open(os.path.join(path,"label.pickle"),'wb') as f:
pickle.dump(label_dict,f)
The above code snippet traines The LBPH Face Recognizer on the image dataset created and save the trained model in the "Train.yml" file and directory in the "label.pickle" file.
Source code for the recognizer is given in "face_detection.py":
while True:
count = 0
ret,frame = cap.read()
# Convderting BGR to Gray frame
gray_frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = cascade_classifier.detectMultiScale(
gray_frame,
scaleFactor=1.3,
minNeighbors=2
)
for x,y,w,h in faces:
# ROI-> Region Of Interest in image
roi_img = gray_frame[y:y+h, x:x+w]
# Making prediction from trained model
id_prediction,confidence = recogniser.predict(roi_img)
# confidenct >= 90
if(confidence >= 90):
text = key_from_label(id_prediction)
count = 1
if text not in names:
names.append(str(text))
date_time.append(datetime.today())
else:
text = "Unknown"
# Making rectangle around the face
cv2.rectangle(frame, (x,y), (x+w,y+h),(0,255,0),1,cv2.LINE_AA)
# Putting text around face
cv2.putText(frame,str(text),(x,y),cv2.FONT_HERSHEY_COMPLEX,1,(0,225,0),2,cv2.LINE_AA)
# Displaying frame
cv2.imshow('The attendance system',frame)
# Break if identified
if cv2.waitKey(1) & count==1:
break
The above code snippet read the frame/camera frame to detect faces using the classifier and predicts the label based on the trained model loaded into the variable "recogniser". If the accuracy of the label is greater than 90% the data is appended into the list. This system stores the names and the date-time of login to the system. Once the face is detected, the frame is closed.
data_csv = os.path.isfile(os.path.join(path,"attendance.csv"))
if data_csv==True:
# Opening File
data = pd.read_csv(os.path.join(path,"attendance.csv"))
# Appending csv
x = data.append({'Names':names[0],'Date-Time':date_time[0]},ignore_index=True)
data = x
# Droping unnecessary columns
data.dropna(axis=1,inplace=True)
else:
# Dataset contains Name and Date-Time column
data = pd.DataFrame(columns=["Names","Date-Time"])
data['Names'] = names
data['Date-Time'] = date_time
data.to_csv(os.path.join(path,"attendance.csv"))
This snippet appends the data into a pandas data frame in .csv format. If the file exists named "attendance.csv" the data is appended into the existing .csv file otherwise a new csv file named "attendance.csv" is created in the current working directory.