Coders Packet

Face Recognition Attendance System Using OpenCV, LBPH Face Recognizer in Python

By Rachit R Jindal

This is a real-world attendance system developed in Python that utilizes LBPH Face recognizer for training the data and Haar cascade classifier for detection of faces.

Face Recognition Attendance System using OpenCV:

This packet involves the use of cv2, re, pandas, pillow, os, pickle libraries of python with Haar cascade as the classifier. This packet is divided into two files, the file named "Training_data.py" for preparing data and training, the second file named "face_detection.py" for classifying faces based on training data trained from file "Training_data.py".

Data preparation and training:

Source code is given in the file "Training_data.py":

 path = os.path.dirname(__file__)

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. 

cascade = cv2.CascadeClassifier(os.path.join(path,"hcascade.xml")) 

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.

# Creating face classifer
recogniser = cv2.face.LBPHFaceRecognizer_create()
# Training the classifer 
recogniser.train(x_img,np.array(y_label))
# Saving the model as Train.yml
recogniser.save(os.path.join(path,"Train.yml"))

# Saving dictionary containg the labels as label.pickle
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.

Face Recogniser:

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 file exist append the 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)

# If file do not exist creating file attendance.csv
else:
    # Dataset contains Name and Date-Time column
    data = pd.DataFrame(columns=["Names","Date-Time"])
    data['Names'] = names
    data['Date-Time'] = date_time

# Saving attendance
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.

Download project

Reviews Report

Submitted by Rachit R Jindal (rachit99)

Download packets of source code on Coders Packet