Recognizing people by their faces in pictures and video feeds is seen everywhere starting from social media to phone cameras. A face recognition system is built for matching human faces with a digital image. Ultimately what a computer recognizes is pixel values ranging from 0-255. In Computer Vision face recognition has been in since ages and has evolved over the years. Many researchers have come up with many new techniques to efficiently identify and tell apart faces. There are many use cases such as authentication and verification of users.
This article covers all the aspects of face recognition based attendance systems. It discusses the challenges faced in face recognition, the face recognition library and building the attendance marking system based on these techniques.
Challenges faced in face recognition:
Subscribe to our Newsletter
Join our editors every weekday evening as they steer you through the most significant news of the day, introduce you to fresh perspectives, and provide unexpected moments of joy
Your newsletter subscriptions are subject to AIM Privacy Policy and Terms and Conditions.
- Different lighting conditions
- Differently posing – there could be images of the same person with different face angles.
- Confusing between similar looking people
(Source – OpenCV Wiki)

Face Recognition Library
Face recognition algorithms can extract features from a face image namely positions of forehead, eyes, nose, mouth, chin, jaws.
Face Landmarks – There are 68 specific points (called landmarks) that exist on every face.
Source – Created by Brandon Amos
Face Encodings – This is the 128 encoding feature vector from a pretrained network over millions of images.
Source – face recognition library documentation
The last step is to match these encoding with the nearest possible image from a stored database.
Basic Face Matching
First, we get the location of where exactly the face is in the image using face_location() method(which gets the outline of the face) on the RGB image. Then face encodings(markings of eyes, nose, mouth, jaws which remain the same for different images of the same person) are taken using face_encodings() function which returns a list containing 128 measurements. Both these two steps are followed for the original and test image. Then a comparison between these two returned lists is done by the function compare_faces() which returns a list of boolean values(True or False). The face distance function gets the value of that by how much the two images differ. The lower the distance the better the matching and vice versa.
import cv2 import face_recognition as fr imgAng = fr.load_image_file('andrew_ng.jpg') Test = fr.load_image_file('ian_godfellow.jpg') fLoc = fr.face_locations(imgAng)[0] encodeAng = fr.face_encodings(imgAng)[0] fLocTest = fr.face_locations(Test)[0] encTest = fr.face_encodings(Test)[0] result = fr.compare_faces([encodeAng],encTest) faceDist = fr.face_distance([encodeAng],encTest) print(result,faceDist)
[True] [0.36569372]
[False] [0.6898802]
Building Face Attendance System
Now we are ready to build a realtime face attendance system wherein webcam captured frames will be matched against the existing database images and if the match is found then it’ll store it in a CSV file called ‘Attendance Register’ along with name and time of capture. Only once the file will store the matched image’s details, if the same image is received again then it’ll not update.
Path setting to the directory containing the image database. Read each image and the images array. Append the filenames into a list called Names and remove the extension.
pathlib = 'ImagesAttendance' images = [] Names = [] myList = os.listdir(pathlib) print(myList) for cl in myList: currImg = cv2.imread(f'{pathlib}/{cl}') images.append(currImg) Names.append(os.path.splitext(cl)[0]) print(Names)
Finding face encodings of images in the database and keeping them in a list to use later with incoming frames.
def DbEncodings(images): encList = [] for image in images: image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) enc = fr.face_encodings(image)[0] encList.append(enc) return encodeList
Capturing video frames
cap = cv2.VideoCapture(0)
Iterating through frames
while True: _, img = cap.read() image = cv2.resize(img,(0,0),None,0.25,0.25) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
The same process is followed by the first detection face location then getting the face encoding values.
facesInFrame = fr.face_locations(image) encodesInFrame = fr.face_encodings(image,facesInFrame)
Now the incoming images are tested against the previously-stored encodings. Then the face distance is also computed. Lastly, we call the Attendance function along with the person name who is identified.
for encodeFace,faceLoc in zip(encodesInFrame,facesInFrame): matchList = fr.compare_faces(encodeKnown,encFace) faceDist = fr.face_distance(encodeKnown,encFace) match = np.argmin(faceDist) if matchList[match]: name = Names[match].upper() Attendance(name)
Reading from attendance file, Storing data(Name and Time of entry) if previously not stored.
def Attendance(name): with open('Attendance_Register.csv','r+') as f: DataList = f.readlines() names = [] for data in DataList: ent = data.split(',') names.append(ent[0]) if name not in names: curr = datetime.now() dt = curr.strftime('%H:%M:%S') f.writelines(f'\n{name},{dt}') encodeKnown = DbEncodings(images) print('Encoding Complete')
OUTPUT
['andrew_ng.jpg', 'ian_goodfellow.jpg', 'Jayita.jpg'] ['andrew_ng', 'ian_goodfellow', 'Jayita'] Encoding Complete
Attendence_Register.csv
Name | Time |
ANDREW_NG | 15:47:33 |
IAN GOODFELLOW | 15:55:12 |
JAYITA | 16:07:45 |
Conclusion
Face recognition library being a high level deep learning library helps in identifying faces accurately. We’ve then used this to build a face attendance system which can be helpful in offices, schools or any other place reducing manual labour and automatically updating the attendance records in day-to-day life. This also notes down the time of arrival thus can acquire information about people coming in late after a specified time.
The complete code of the above implementation is uploaded as a notebook to the AIM’s GitHub repository. Please visit this link to find the notebook of this code.