Face Recognition based Attendance System – easiest way – best project – with source code – 2022

So guys here comes the most awaited project of machine learning Face Recognition based Attendance System. As the name says this project takes attendance using biometrics (in this case face) and is one of the most famous projects amongst college students out there. I have tried to explain each and every line in the easiest way possible. So without any further due.

Let’s do it…

Create a conda environment and install required libraries

conda create -n att python=3.6
conda activate att
pip install opencv-python numpy pillow sklearn tensorflow mtcnn pandas

Code for adding a new face in Face Recognition based Attendance System…

import cv2
import os
import joblib
import numpy as np
import time
from PIL import Image
from sklearn.svm import SVC
from mtcnn.mtcnn import MTCNN
from sklearn.metrics import accuracy_score
from tensorflow.keras.models import load_model
from sklearn.preprocessing import Normalizer, LabelEncoder

######### if these directories doesn't exist, make them #######
try:os.makedirs('faces')
except:pass

try:os.makedirs('faces/train')
except:pass

try:os.makedirs('faces/val')
except:pass


############### take name and roll no as input #################
name = input('Enter your name --> ')
roll = input('Enter your roll no --> ')

name = name+'-'+roll


######### make face folders in train and val ##################
if name in os.listdir('faces/train'):
    print('User already exist in faces')

else:    
    os.makedirs('faces/train/'+name)
    os.makedirs('faces/val/'+name)

    cap = cv2.VideoCapture(0)
    i = 0
    print()
    for i in range(5):
        print(f'Capturing starts in {5-i} seconds...')
        time.sleep(1)
    print('Taking photos...')
    while i<=200:
        ret,frame = cap.read()
        cv2.imshow('taking your pictures',frame)
        if i%5==0 and i<=150 and i!=0:
            cv2.imwrite('faces/train/'+name+'/'+str(i)+'.png',frame)
        elif i%5==0 and i>150:
            cv2.imwrite('faces/val/'+name+'/'+str(i)+'.png',frame)
        i+=1

    cv2.destroyAllWindows()
    cap.release()
    print('Successfully taken your photos...')



# Face Recognition based Attendance System
#### Below part is just training the model with the newly added face. Here we are creating model.

embedding_model = load_model('models/facenet_keras.h5')
print('Embedding Model Loaded')

# making a a mtcnn instance for detecting faces
detector = MTCNN()

def find_face(path,img_size=(160,160)):
    img = cv2.imread(path)
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    img = np.asarray(img) # converting our image obj to numpy array
    faces = detector.detect_faces(img)
    if faces:
        x,y,w,h = faces[0]['box']
        x,y=abs(x),abs(y)
        face = img[y:y+h,x:x+w]
        face = Image.fromarray(face) # converting it to image object to resize it
        face = face.resize(img_size) # resizing it
        face = np.asarray(face)      # converting it back to array
        return face
    return None


def embed(face):
    face = face.astype('float32')
    fm,fs = face.mean(),face.std()
    face = (face-fm)/fs # standardizing the data 
    face = np.expand_dims(face,axis=0) # flattening it
    embs = embedding_model.predict(face) # embedding model converts our160*160*3 vector to 128 features
    return embs[0]



def load_dataset(path):
    X = []
    y = []
    for people in os.listdir(path):
        for people_images in os.listdir(path+people):
            face = find_face(path+people+'/'+people_images)
            if face is None:continue
            emb = embed(face)
            X.append(emb)
            y.append(people)
        print('Loaded {} images of {}'.format(len(os.listdir(path+'/'+people)),people)) 
    return np.asarray(X),np.asarray(y)


########### Loading training and testing data using functions defined above #############
print('Loading train data...')
X_train, y_train = load_dataset('faces/train/')

print()

print('Loading test data...')
X_test, y_test = load_dataset('faces/val/')


# l2 normalizing the data
l2_normalizer = Normalizer('l2')

X_train = l2_normalizer.transform(X_train)
X_test  = l2_normalizer.transform(X_test)

#label encoding the y data
label_enc = LabelEncoder()
y_train = label_enc.fit_transform(y_train)
y_test = label_enc.transform(y_test)


############ Training SVC (Support Vector Classifier) for predicting faces ########
svc = SVC(kernel='linear',probability=True)
svc.fit(X_train,y_train)
joblib.dump(svc,'models/face_prediction_model.sav')
print()

print('SVM Model saved successfully!!')
  • Line 1-11 – Importing required libraries.
  • Line 14-21 – Check if these folders exist or not. If they don’t exist make them, else just pass.
  • Line 25-26 – Input name and roll number of the user. We are taking roll numbers because two users can have the same name but not roll numbers.
  • Line 28 – Simply merging name and roll no. and using it as the name now. For eg if the name is Sam and roll no. is 34, it would look like ‘Sam-34’.
  • Line 32-33 – Check if the user already exists in our data(faces folder) or not.
  • Line 35-57 – Add this user.
  • Line 36-37 – Make folders of this user in train and Val directory in faces directory.
  • Line 39 – Instantiate VideoCapture object to access the webcam.
  • Line 40 – Setting i as 0. We will use it as an iterator in our while loop.
  • Line 41 – Just to leave an empty line.
  • Line 42-44 – Just creating a countdown of 5 seconds.
  • Line 46 – run a while loop till i reach 200.
  • Line 47-48 – Read the image from the webcam and show it in a window.
  • Line 49-50 – From i=0 to i=150 Save every 5th image in the train folder of that user. Images will be like 5.png, 10.png, 15.png,…150.png.
  • Line 51-52 – From 150 to 200, save images in Val folder of that user.
  • Line 53 – Keep on incrementing i.
  • Line 55-57 – Release the webcam, destroy all open windows, and print the success message.
  • Now we will train our model for all the users in our dataset.
  • Line 64-65 – Loading ‘facenet_keras’ model. This model is just a Keras model which will convert our face image to a vector.
  • Line 68 – Declaring an MTCNN instance. MTCNN is used to detect faces in a frame. We have used HAARCASCADES previously. Although they were very fast but they lacked in accuracy. Whereas MTCNNs are very accurate but a bit slower.
  • Line 70-83 – Detect face using MTCNN.
  • Line 71 – Read the image
  • Line 72 – Convert to RGB.
  • Line 73 – Convert image to the array.
  • Line 74 – Find faces using the MTCNN detector.
  • Line 75-82 – If a face is found, crop it, convert the array back to the image object, resize it, convert it back to the array, and return it.
  • Line 83 – If no face is found, return None.
  • Line 86-92 – Convert face arrays to vectors using facenet_keras. Basically, facenet_keras is nothing but an Embedding layer.
  • Line 87 – Convert image to float.
  • Line 88 -Extract mean and standard deviation.
  • Line 89 – Standardize the image.
  • Line 90 – Flatten it.
  • Line 91-92 – Take out embeddings. Embedding model converts our160*160*3 vector to 128 features. This means this 128 value array will now depict our face data. And after that just return it.
  • Line 96-107 – Loading our data in X and y.
  • Line 99 – Traverse in the path received. This path will be of train directory first and Val directory the second time. This will contain folders of all users.
  • Line 100 – Get inside every user folder and take their images.
  • Line 101- Use the find_face function we declared above to extract face.
  • Line 102 – If no face is found, no need to go further, continue running the loop for the next entry.
  • Line 103 – If the program has reached this line, means the face is found, and now take its embeddings.
  • Line 104 – Append face embeddings in X.
  • Line 105 – Append names in y.
  • Line 106 – Print success message.
  • Line 107 – Return the arrays.
  • Line 111-112 – Load training data using the function declared above.
  • Line 116-117 – Load testing data using the function declared above.
  • Line 121-124 – Initialize the l2 normalizer and normalize the X data.
  • Line 126-129 – Converting names to numbers in y.
  • Line 133-138 – Train Support Vector Classifier (SVC) model and save the model.

Code for live detection in Face Recognition based Attendance System…

import numpy as np
import cv2
from mtcnn.mtcnn import MTCNN
import os
import joblib
import pandas as pd
from PIL import Image
from sklearn.svm import SVC
import datetime
import csv
import time
from mtcnn.mtcnn import MTCNN
from sklearn.metrics import accuracy_score
from tensorflow.keras.models import load_model
from sklearn.preprocessing import Normalizer, LabelEncoder

# Face Recognition based Attendance System
embedding_model = load_model('models/facenet_keras.h5')
print('Embedding Model Loaded')

ML_model = joblib.load('models/face_prediction_model.sav')
print('Loaded ML Model')

detector = MTCNN()

def find_face(img,img_size=(160,160)):
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    img = np.asarray(img) # converting our image obj to numpy array
    faces = detector.detect_faces(img)
    if faces:
        x,y,w,h = faces[0]['box']
        x,y=abs(x),abs(y)
        face = img[y:y+h,x:x+w]
        face = Image.fromarray(face) # converting it to image object to resize it
        face = face.resize(img_size) # resizing it
        face = np.asarray(face)      # converting it back to array
        return face,x,y,w,h
    return None,None,None,None,None



def embed(face):
    face = face.astype('float32')
    fm,fs = face.mean(),face.std()
    face = (face-fm)/fs
    face = np.expand_dims(face,axis=0)
    embs = embedding_model.predict(face)
    return embs[0]


#for converting ids to names
def id2name(id):
    x = os.listdir('faces/train/')
    return x[id]


def mark_attendance(name,roll):

    roll_list = []
    
    if not os.path.isdir('Attendance'):
        os.makedirs('Attendance')
        
    date=time.asctime()[8:10]
    month=time.asctime()[4:7]
    year=time.asctime()[-4:]
    tim=time.asctime()[11:16]
    
    # if csv of current date doesn't exist, make it
    if (date+'-'+month+'-'+year+'.csv')  not in os.listdir('Attendance/'):
        att = pd.DataFrame(columns=['Roll','Name','Time'])
        att.to_csv('Attendance/'+date+'-'+month+'-'+year+'.csv')
        
    # here we are just selecting these 3 columns everytime and ignoring the index column    
    att = pd.DataFrame(pd.read_csv('Attendance/'+date+'-'+month+'-'+year+'.csv'))
    att = att[['Roll','Name','Time']]
    
    for i in range(len(att)):
        roll_list.append(str(att.loc[i]['Roll']))
    

    if roll not in roll_list:
        att1 = pd.DataFrame({'Name':[name], 'Roll':[roll], 'Time':[datetime.datetime.now().strftime("%H:%M:%S")]})
        att = att.append(att1,ignore_index=False)
    else:
        prev_time = att[att['Roll']==int(roll)]['Time'].iloc[-1]
        curr_time = datetime.datetime.now().time().strftime("%H:%M:%S")
        #here we are just checking the time difference between previous timestamp and current time
        if datetime.datetime.strptime(curr_time, '%H:%M:%S') - datetime.datetime.strptime(prev_time, '%H:%M:%S') > datetime.timedelta(minutes=5):
            att1 = pd.DataFrame({'Name':[name], 'Roll':[roll], 'Time':[datetime.datetime.now().strftime("%H:%M:%S")]})
            att = att.append(att1,ignore_index=False)

    att.to_csv('Attendance/'+date+'-'+month+'-'+year+'.csv')

# Face Recognition based Attendance System
cap = cv2.VideoCapture(0)
i = 0

while 1:
    i+=1
    ret,frame = cap.read()
    if i>10:
        face,x,y,w,h = find_face(frame)
        if face is not None:
            face_emb = embed(face)
            pred = ML_model.predict(face_emb.reshape(1,-1))
            name = str(id2name(pred[0]))
            if name:
                mark_attendance(name.split('-')[0],name.split('-')[1])
                cv2.rectangle(frame,(x,y),(x+w,y+h),(178,88,239),1)
                cv2.putText(frame,name,(x,y-10),cv2.FONT_HERSHEY_TRIPLEX,0.8,(178,88,239),1,cv2.LINE_AA)
        cv2.imshow('live',frame)
    
    if cv2.waitKey(1)==27:
        break
        
cap.release()
cv2.destroyAllWindows()

# This was the code for Face Recognition based Attendance System.
  • Line 1-15 – Importing required libraries.
  • Line 18-19 – Importing embedding model.
  • Line 21-22 – Importing saved face recognition model.
  • Line 26-48 – We have discussed these functions above.
  • Line 52-54 – A utility function to convert id to name. Because as you remember that we converted names to numbers above using LabelEncoder and now in the final results, we don’t want numbers, we want names.
  • Line 57-93 – Mark attendance. This is the main motive of Face Recognition based Attendance System.
  • We are getting name and roll no as inputs to this function.
  • Line 61-62 – If there is no folder named Attendance, make it.
  • Line 64-67 – Extract today’s date, month, year, and time.
  • Line 70-72 – Check if today’s attendance file already exists in the Attendance folder or not. If not then create a data frame in pandas with columns as Roll, Name, and Time and save it in CSV format in the Attendance folder.
  • Line 75-76 – Open the Attendance CSV file of today’s date and just take the 3 columns(to be on the safe side).
  • Line 78-79 – Create a list of all roll numbers in today’s attendance, which means take roll numbers of all persons whose today’s attendance is marked.
  • Line 82-84 – If the current user is not in today’s attendance simply insert its name, roll, and time in today’s attendance. We are just making one more data frame with our entry and appending it to our main data frame.
  • Line 85-91 – If this user is already in today’s attendance the check if his last entry was at least 5 minutes ago, if it is true then mark the attendance again, else do not mark. Means if he was detected 5 minutes ago or earlier then mark his attendance again. If it’s not 5 minutes since his last entry does not mark.
  • Line 93 – Save everything to today’s attendance.
  • Line 99-115 – Final infinite loop for taking attendance in Face Recognition based Attendance System.
  • Line 100 – Read images from the frame.
  • Line 101 – Only start taking images when we are ahead 10 frames because starting 5 6 frames are just black images because the camera is just starting at that time.
  • Line 102 – Find face using a function defined above.
  • Line 103-106 – If a face is found, take its embedding, use our trained model to make predictions, convert the prediction number to name.
  • Line 107 – If we get the name, means everything is going well till now.
  • Line 108 – Call mark attendance and send name and roll no of the user.
  • Line 109 -110 – Show a rectangle around the face and put the name around the rectangle.
  • Line 111 – Show results.
  • Line 117-118 – Release the camera object, destroy all open windows.

Folders hierarchy

Face Recognition based Attendance System
  • This should be the main hierarchy of folders.
Face Recognition based Attendance System
  • This should be inside the faces folder.
Face Recognition based Attendance System
  • Download facenet_keras.h5 from the link below and paste it into the models folder.
  • face_prediction_model.sav will be present when you add atleast 1 face.

Download Source code for Face Recognition based Attendance System…

Download facenet_keras.h5 file for Face Recognition based Attendance System…

Do let me know if there’s any query regarding the Face Recognition based Attendance System by contacting me on email or LinkedIn.

This Face Recognition based Attendance System uses advanced techniques like MTCNN and embeddings to enhance the performance of the model.

So this is all for this blog folks, thanks for reading it and I hope you are taking something with you after reading this and till the next time ?…

Read my previous post: FLIGHT PRICE PREDICTION WITH FLASK APP

Check out my other machine learning projectsdeep learning projectscomputer vision projectsNLP projectsFlask projects at machinelearningprojects.net.

4 thoughts on “Face Recognition based Attendance System – easiest way – best project – with source code – 2022”

  1. Yakubu Nuhu Danjuma

    Great and wonderful project, keep it up. Sir I try executing program, but got this error: ValueError: bad marshal data (unknown type code), how to fix the problem. Thank you

  2. Rajesh pradhan

    Hlw , I am getting some error when I will execute the following code. So I need you help to fix it
    How did I connect with you in mail or in linked in ?
    Please attach your I’d name

Leave a Comment

Your email address will not be published.