Create a face recognition attendance system using Python

face recognition attendance system using python

Introduction

Ditching punch cards and time sheets, let’s code our way to a smarter future! In this hands-on tutorial, we’ll build a face recognition attendance system using Python, a popular language that opens doors to both learning and real-world applications.

Skip the advanced systems and join me as we craft our own, mastering essential Python skills along the way. Forget the inefficiency of manual methods; this project promises accuracy, convenience, and a glimpse into the future of attendance tracking. So, fire up your laptops and embark on this coding adventure – let’s build a system that’s both powerful and practical!

The Project Details

Hey there! So, I worked on this cool project using OpenCV and the face-recognition library. Picture this: you’ve got two folders, one called ‘Image’ and the other ‘Records,’ plus a nifty program file called ‘attendance.py.’

The ‘Images’ Folder

Now, the ‘Image’ folder is where the magic happens. It’s got pictures of your folks – in my case, I threw in some shots of my buddies to give you a feel. Feel free to toss in any other pics you need.

Let’s dive into the program. It scans faces through your webcam, and if it recognizes someone, voila! It whips up a CSV file. Just once, though, no need to worry about creating a new file each day. For instance, if it spots a face on the 1st of January 2024, it’ll craft a CSV named “record_01_01_2024.csv.”

What’s super cool is that you’re off the hook from manually creating CSV files daily. At midnight, like clockwork, a new CSV file for the next day gets generated (only if the program is running), and it kicks off a fresh recording.

Now, inside the program, I’ve set up a different thread for reading video frames via the webcam. Why? Well, I wanted to sidestep any lag while the camera does its thing. Smart, right?

Requirements and Installations

If Python isn’t already a resident on your system, fear not! Grab the latest version from their website (https://www.python.org/). Once settled, remember to install the following libraries using the provided commands.

Note that, before installing the face_recognition library, it’s necessary to install two other libraries—namely, cmake and dlib.

pip install cmake
pip install dlib
pip install face_recognition
pip install opencv-python
pip install numpy

Setting Up the Project

Before we unleash our Python Countdown Timer, let’s get our workspace organized:

  • Create a separate folder for this Python project named “Attendance-System”.
  • Establish one additional sub-directory within this folder with the title ‘Images’.
  • Store the students or your friends images into the ‘Images’ folder.
  • Within the main folder, declare a Python file named attendance.py.

Import the Modules

Let’s kick off our coding journey by bringing in some essential modules.

import os
import cv2
import time
import numpy as np
from threading import Thread
import face_recognition as fr

Exclude Some People

Now, to make our system tailored for educational institutes, we’ll exclude certain individuals like the Head of Department, Principal, and any unknown faces. You can easily specify these exclusions by adding their names to a Python list. If anyone from this list shows up on camera, the program will skip recording their attendance.

exclude_names = ['Unknown', 'HOD', 'Principal']

Define the ‘VideoStream’ Class

class VideoStream:
    def __init__(self, stream):
        self.video = cv2.VideoCapture(stream)
        # Setting the FPS for the video stream
        self.video.set(cv2.CAP_PROP_FPS, 60)

        if self.video.isOpened() is False:
            print("Can't accessing the webcam stream.")
            exit(0)

        self.grabbed , self.frame = self.video.read()

        self.stopped = True
        
        self.thread = Thread(target=self.update)
        self.thread.daemon = True
    
    def start(self):
        self.stopped = False
        self.thread.start()

    def update(self):
        while True :
            if self.stopped is True :
                break
            self.grabbed , self.frame = self.video.read()

        self.video.release()

    def read(self):
        return self.frame

    def stop(self):
        self.stopped = True

Here, we define a VideoStream class for handling video streams. It initializes with a specified video stream, sets the frames per second (FPS) to 60, and checks if the webcam stream is accessible. The class includes methods to start, stop, and read frames from the video stream. The actual video stream runs in a separate thread to ensure smooth operation.

Encode the Faces

Let’s define a function named encode_faces that encodes facial features from images in the “./Images” directory.

def encode_faces():
    encoded_data = {}

    for dirpath, dnames, fnames in os.walk("./Images"):
        for f in fnames:
            if f.endswith(".jpg") or f.endswith(".png"):
                face = fr.load_image_file("Images/" + f)
                encoding = fr.face_encodings(face)[0]
                encoded_data[f.split(".")[0]] = encoding

    # return encoded data of images
    return encoded_data

It walks through the directory, loads JPG or PNG files, extracts facial encodings, and stores them in a dictionary named encoded_data with filenames (excluding extensions) as keys. The function then returns this dictionary containing the encoded facial data.

Keep the Record of Attendance

def Attendance(name):
    # It will get the current date
    today = time.strftime('%d_%m_%Y')
    # To create a file if it doesn't exists
    f = open(f'Records/record_{today}.csv', 'a')
    f.close()

    # It will read the CSV file and check if the name
    # is already present there or not.
    # If the name doesn't exist there, it'll be added
    # to a list called 'names'
    with open(f'Records/record_{today}.csv', 'r') as f:
        data = f.readlines()
        names = []
        for line in data:
            entry = line.split(',')
            names.append(entry[0])

    # It will check it the name is in the list 'names'
    # or not. If not then, the name will be added to
    # the CSV file along with the entering time
    with open(f'Records/record_{today}.csv', 'a') as fs:
        if name not in names:
            current_time = time.strftime('%H:%M:%S')
            if name not in exclude_names:
                fs.write(f"\n{name}, {current_time}")

The Attendance function takes a person’s name as input and performs the following actions:

  • Retrieves the current date.
  • Creates a CSV file named “record_{today}.csv” in the “Records” directory if it doesn’t already exist.
  • Reads the existing CSV file to check if the input name is already present; if not, it adds the name to a list called ‘names.’
  • If the input name is not in the ‘names’ list, and it’s not in a predefined list of excluded names, the function appends the name and the current time to the CSV file.

In essence, this code is managing attendance records for a given date by updating a CSV file with the names and entry times of individuals.

Putting it All Together

if __name__ == "__main__":
    faces = encode_faces()
    encoded_faces = list(faces.values())
    faces_name = list(faces.keys())
    video_frame = True

    # Initialize and start multi-thread video input
    # stream from the WebCam.
    # 0 refers to the default WebCam
    video_stream = VideoStream(stream=0)
    video_stream.start()

    while True:
        if video_stream.stopped is True:
            break
        else :
            frame = video_stream.read()

            if video_frame:
                face_locations = fr.face_locations(frame)
                unknown_face_encodings = fr.face_encodings(frame, \
                face_locations)

                face_names = []
                for face_encoding in unknown_face_encodings:
                    # Comapring the faces
                    matches = fr.compare_faces(encoded_faces, \
                    face_encoding)
                    name = "Unknown"

                    face_distances = fr.face_distance(encoded_faces,\
                    face_encoding)
                    best_match_index = np.argmin(face_distances)
                    if matches[best_match_index]:
                        name = faces_name[best_match_index]

                    face_names.append(name)

            video_frame = not video_frame

            for (top, right, bottom, left), name in zip(face_locations,\
            face_names):
                # Draw a rectangular box around the face
                cv2.rectangle(frame, (left-20, top-20), (right+20, \
                bottom+20), (0, 255, 0), 2)
                # Draw a Label for showing the name of the person
                cv2.rectangle(frame, (left-20, bottom -15), \
                (right+20, bottom+20), (0, 255, 0), cv2.FILLED)
                font = cv2.FONT_HERSHEY_DUPLEX
                # Showing the name of the detected person through 
                # the WebCam
                cv2.putText(frame, name, (left -20, bottom + 15), \
                font, 0.85, (255, 255, 255), 2)
                
                # Call the function for attendance
                Attendance(name)

        # delay for processing a frame 
        delay = 0.04
        time.sleep(delay)

        cv2.imshow('frame' , frame)
        key = cv2.waitKey(1)
        # Press 'q' for stop the executing of the program
        if key == ord('q'):
            break

    video_stream.stop()

    # closing all windows 
    cv2.destroyAllWindows()

This code is the main logic for our Project that performs real-time face recognition through the webcam feed. Here’s a brief overview:

  • It starts by encoding faces using a predefined function called encode_faces() and sets up variables for face data.
  • Initializes a video stream from the webcam using a multi-threaded approach for smoother performance.
  • Enters a continuous loop to capture and process video frames.
  • Utilizes face_recognition library to identify faces in each frame and compares them with the pre-encoded faces.
  • Draws rectangles around detected faces and displays the names of recognized individuals.
  • Calls the Attendance function to mark the attendance of the recognized person.
  • Implements a delay for frame processing and displays the processed frame in a window.
  • Allows the user to stop the program by pressing ‘q.’
  • Finally, stops the video stream and closes all windows when the program is terminated.

Output

See how effortlessly our face recognition system tracks attendance! Watch the video to uncover the magic behind it.

The Output

Summary

Welcome to an exciting journey into the realm of cutting-edge technology! In this step-by-step tutorial, we crafted a powerful Face Recognition Attendance System using Python and the face_recognition library.

Imagine a world where your webcam transforms into a digital gatekeeper, effortlessly tracking and identifying faces. Our attendance system not only captures video frames but also performs a seamless face detection, comparing each face with a database of pre-stored faces.

Now, here’s the cherry on top: Every entry into our attendance system becomes a chapter in a digital diary. We log names, IDs, and entry times into a daily CSV file, creating a comprehensive record of each day’s attendance.

But wait, there’s more! Each day brings forth a new CSV file, making future record searches a breeze. No more digging through mountains of data – just a neat, organized system at your fingertips.

No more punch cards, no more forgotten sign-ins. Just a quick glance at the camera and you’re clocked in!

Want more delightful Python Projects? You’re in luck! Explore a treasure trove of them on our dedicated page – Python Projects with Source Code! Below are a few instances to spark your interest.

If you have any burning questions about this Python project, drop them in the comments below. I’m here and ready to help you out.

Happy Coding!

Share your love
Subhankar Rakshit
Subhankar Rakshit

Hey there! I’m Subhankar Rakshit, the brains behind PySeek. I’m a Post Graduate in Computer Science. PySeek is where I channel my love for Python programming and share it with the world through engaging and informative blogs.

Articles: 147