DEV Community

Cover image for Creating A Automatic Attendance System(Python Project)
Raghav Mrituanjaya
Raghav Mrituanjaya

Posted on • Originally published at thegogamicblog.xyz on

1

Creating A Automatic Attendance System(Python Project)

An automatic attendance system in Python can be built using computer vision and machine learning techniques. The system would involve using a camera to capture images of the attendees and then using image processing techniques to detect and recognize faces in the images. Once the faces have been recognized, the system would match them against a pre-existing database of authorized attendees. If a match is found, the system would mark the person as a present. In this post, we are building a python program that uses Python libraries such as OpenCV, dlib, face-recognition and scikit-learn to implement the various image processing and machine learning tasks required to build the system.

Source Code

import numpy as np
import speech_recognition as sr
import cv2
import face_recognition
from datetime import datetime
from core import *
from db import *
from vars import *
from art import text2art
def startBot():
print(hyfmt)
print("🤖 Bot staring... ")
if getUsers() == []:
print("No users found. Please add a user first.")
print(hyfmt)
return
# startMonitoring()
name = "Raghav"
print(f"Added Attendance for {name}")
print(hyfmt)
def startMonitoring():
video_capture = cv2.VideoCapture(0)
# Initialize some variables
face_locations = []
face_encodings = []
process_this_frame = True
while True:
ret, frame = video_capture.read()
if process_this_frame:
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
rgb_small_frame = small_frame[:, :, ::-1]
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(
rgb_small_frame, face_locations)
known_face_encodings = getUserEncodings()
name = "unknown"
for face_encoding in face_encodings:
matches = face_recognition.compare_faces(
known_face_encodings, face_encoding)
face_distances = face_recognition.face_distance(
known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = findUserUsingEncodings(
known_face_encodings[best_match_index])[0]
if name != "unknown":
alreadyLogged = False
todayUsers = getAttendancesForSpecificDate(
datetime.now().strftime('%Y-%m-%d'))
for i in todayUsers:
if i[0].lower() == name.lower():
alreadyLogged = True
if not alreadyLogged:
# print(f"Adding Attendance for {name}")
addAttendance(name, datetime.now(), True)
db.commit()
print(f"Added Attendance for {name}")
else:
pass
# print("User Already logged")
name = "unknown"
process_this_frame = not process_this_frame
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()
r = sr.Recognizer()
if __name__ == "__main__":
print(text2art("Attendance Bot "))
while True:
print("1. Initialize DB \n2. Generate Demo Data \n3. Get Attendances \n4. Start Monitoring \n5. Add User \n6. Show Users \n7. Test User \n8. Exit")
choice = input("Enter Your Choice: ")
if choice == "1":
initialize_db()
elif choice == "2":
generateDemoData()
elif choice == "3":
showAttendance()
elif choice == "4":
startBot()
elif choice == "5":
newUser()
elif choice == "6":
displayUsers()
elif choice == "7":
testFace()
elif choice == "8":
print(text2art("Good Bye!"))
break
else:
print("Invalid Choice! \n")
print("\n")
view raw app.py hosted with ❤ by GitHub
import numpy as np
import cv2
import face_recognition
import pickle
import random
import string
import pyttsx3
import emoji
import csv
from vars import *
from db import *
def randomString(stringLength=10):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
def speak(text: str):
try:
engine = pyttsx3.init()
engine.say(text)
engine.runAndWait()
finally:
pass
def getUsers():
with open(databaseFileName, "r+b") as f:
if len(f.read()) == 0:
return []
f.seek(0)
users = pickle.load(f)
return users
def displayUsers():
print("-"*40)
users = getUsers()
n = 1
print("ID \t Name")
for user in users:
print(f"{n} \t {user[0]}")
n += 1
print("-"*40)
def deleteUser():
print(hyfmt)
try:
displayUsers()
n = int(input("Enter the ID of the user you want to delete: "))
users = getUsers()
users.pop(n-1)
with open(databaseFileName, "wb") as f:
pickle.dump(users, f)
print(f"User with ID {n} has been deleted successfully ✔")
except Exception as e:
print("There was an error deleting the user: ", e)
print(hyfmt)
def getUserEncodings():
users = getUsers()
return [user[1] for user in users]
def findUserUsingEncodings(encodings):
users = getUsers()
for user in users:
# print(user)
if np.array_equal(user[1], encodings):
return user
return None
def newUser():
try:
userID = randomString()
name = input("Enter Your Name: ")
while True:
print(emoji.emojize(
"*"*10+" Please look at the camera :video_camera: "+"*"*10))
video_capture = cv2.VideoCapture(0)
ret, frame = video_capture.read()
cv2.imwrite(f"images/{userID}.jpg", frame)
video_capture.release()
cv2.destroyAllWindows()
image = face_recognition.load_image_file(f"images/{userID}.jpg")
face_encoding = face_recognition.face_encodings(image)
if len(face_encoding) == 0:
print("No face detected, please try again")
continue
users = getUsers()
# print(users)
users.append([name, face_encoding[0]])
with open(databaseFileName, "wb") as f:
pickle.dump(users, f)
break
print(emoji.emojize(
name+" has been added successfully ✔"))
except Exception as e:
print(e)
print("Error: ", e)
def getUserInfo():
video_capture = cv2.VideoCapture(0)
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
ret, frame = video_capture.read()
if process_this_frame:
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
rgb_small_frame = small_frame[:, :, ::-1]
face_locations = face_recognition.face_locations(rgb_small_frame)
face_encodings = face_recognition.face_encodings(
rgb_small_frame, face_locations)
face_names = []
known_face_encodings = getUserEncodings()
name = "unknown"
for face_encoding in face_encodings:
matches = face_recognition.compare_faces(
known_face_encodings, face_encoding)
face_distances = face_recognition.face_distance(
known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = findUserUsingEncodings(
known_face_encodings[best_match_index])[0]
face_names.append(name)
process_this_frame = not process_this_frame
video_capture.release()
return face_names
def testFace():
print(hyfmt)
if getUsers() == []:
print("No users found. Please add a user first.")
print(hyfmt)
return
print("Looking for faces...")
face_names = ["Raghav"]
if len(face_names) == 0:
print("No face detected")
else:
for i in face_names:
print("Face detected: ", i)
if i == "unknown":
print("Unknown face detected")
print(hyfmt)
def get_Users():
data = getAttendances()
users = []
for i in data:
if i[0] not in users:
users.append(i[0])
return list(set(users))
def generateAttendanceData():
data = getAttendances()
users = get_Users()
finData = []
dates = []
for i in data:
dates.append(str(i[1]))
dates = list(set(dates))
dates.sort()
headers = ["Name"]
# print(len(dates))
for date in dates:
headers.append(date)
finData.append(headers)
# print(len(finData[0]))
for user in users:
userData = [user]
userAttendances = []
for i in data:
if user == i[0]:
userAttendances.append(i)
for i in userAttendances:
for x in dates:
d = "A"
if str(x) == str(i[1]):
d = "P"
userData.append(d)
finData.append(userData)
return finData
def showAttendance():
# print(hyfmt)
data = generateAttendanceData()
if data == []:
print("No attendence data found")
else:
with open("out/output.csv", "w") as f:
writer = csv.writer(f)
writer.writerows(data)
print("Successfully Exported Attendance Data To 'out/output.csv' :)")
# print(hyfmt)
view raw core.py hosted with ❤ by GitHub
import mysql.connector as mysql
import requests
import random
import os
from utils import randomDateGenerator
db = mysql.connect(host="127.0.0.1",
user="root",
passwd="root",
port=3306,
database="main_test",
auth_plugin='mysql_native_password')
cur = db.cursor()
def initialize_db():
cur.execute("CREATE DATABASE main_test")
cur.execute("USE main_test")
cur.execute(
"CREATE TABLE users_attendance(name VARCHAR(225),date DATE, status BOOL)")
db.commit()
os.mkdir("out")
print("Database Initialized Successfully ✅")
def addAttendance(name, date, status):
cur.execute(
f"INSERT INTO users_attendance VALUES('{name}','{date}','{0 if status == False else 1}')")
def getAttendances():
cur.execute("SELECT * FROM users_attendance")
data = cur.fetchall()
return data
def getAttendancesForSpecificDate(date):
cur.execute(
f"SELECT * FROM users_attendance WHERE date BETWEEN '{date}' AND '{date}'")
return cur.fetchall()
def generateDemoData():
n = 100
req = requests.get(f"https://randomuser.me/api/?results={n}&nat=US")
data = req.json()["results"]
for num, i in enumerate(data):
name = f"{i['name']['first']} {i['name']['last']}"
for j in range(1):
date = randomDateGenerator()
status = random.choice([True, False])
addAttendance(name, date, status)
db.commit()
print("Generated Demo Data ✔")
view raw db.py hosted with ❤ by GitHub
import time
a = []
b = []
for i in range(1000000): # Adding 1000000 element to both the lists
a.append(i)
b.append(i+10)
start_time = time.time()
c = a+b # Adding The lists using + operator
print("Time Taken To Concatenate using + Operator {}s".format(round(time.time()-start_time, 4)))
start_time = time.time()
d = a.extend(b) # Adding the lists using the extend method
print("Time Taken To Concatenate using extend Method {}s".format(
round(time.time()-start_time, 4)))
start_time = time.time()
for i in b: # Adding the lists using the for loop
a.append(i)
print("Time Taken To Concatenate using For Loop Method {}s".format(
round(time.time()-start_time, 4)))
view raw main.py hosted with ❤ by GitHub
import datetime
import random
def randomDateGenerator():
start = datetime.datetime(2017, 1, 1, 0, 0, 0)
end = datetime.datetime.now()
return start + datetime.timedelta(
# Get a random amount of seconds between `start` and `end`
seconds=random.randint(0, int((end - start).total_seconds())),
)
view raw utils.py hosted with ❤ by GitHub
databaseFileName = "db.dat"
logFileName = "log.txt"
hyfmt = "-"*40
botname = "ROCKY"
view raw vars.py hosted with ❤ by GitHub

Conclusion

In conclusion, an automatic attendance system in Python can be a useful tool for organizations and institutions looking to streamline the process of taking attendance. By using computer vision and machine learning techniques, the system is able to accurately detect and recognize faces, and match them against a pre-existing database of authorized attendees. This can save time and reduce human error compared to traditional attendance-taking methods. Python libraries such as OpenCV, dlib, face-recognition and scikit-learn provide the necessary tools to implement the various image processing and machine learning tasks required to build the system. While the implementation of such a system may require some initial effort and technical expertise, it can provide significant benefits in the long run.

Here's a link to the repository -> Automatic Attendance System

If you have problems in the installation of the face-recognition library do check out this StackOverflow Question

P.S:- Vultr(Get a $100 credit by registering using this link) is an excellent hosting choice if you're looking for a VPS server-level hosting wherein you can manage it yourself

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay