Created
January 12, 2023 11:57
-
-
Save raghavmri/657f7adf16fb187b51f3bb905bfa7d60 to your computer and use it in GitHub Desktop.
Automatic Attendance System
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ✔") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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())), | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
databaseFileName = "db.dat" | |
logFileName = "log.txt" | |
hyfmt = "-"*40 | |
botname = "ROCKY" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment