Jerry Zhang
Created December 29, 2019

Classroom Attendance Tracker

Easily track attendance in large classroom settings

AdvancedFull instructions provided15 hours67
Classroom Attendance Tracker

Things used in this project

Hardware components

NVIDIA Jetson Nano Developer Kit
NVIDIA Jetson Nano Developer Kit
×1
Flash Memory Card, MicroSD Card
Flash Memory Card, MicroSD Card
×1
Webcam, Logitech® HD Pro
Webcam, Logitech® HD Pro
×1
Power Supply 5V 4A
×1

Story

Read more

Code

helper.py

Python
#!/usr/bin/python3  
import smtplib

sender_mail = 'sender@gmail.com' # attendance email
pwd = 'password' # attendance email account password
smtpObj = smtplib.SMTP('gmail.com',587)  
smtpObj.login(sender_mail,password)  
f = open("attendance.txt","r")
lines = f.readlines()
for line in lines:
  student_name = line[:line.find(",")] # file is formatted so that name and email are separated with a comma.
  student_email = line[(line.find(",") + 1):]
  receivers_mail = [student_email]  
  message = """Dear %s,
  Your attendance has been recorded. 
  """%(student_name)  
  try:   
     smtpObj.sendmail(sender_mail, receivers_mail, message)  
     print("Successfully sent email")  
  except Exception:  
     print("Error: unable to send email")  
f.close()

main.py

Python
Main Facial Recognition Program
import face_recognition
import cv2
import numpy as np
import os

f = open("attendance.txt","w+")

video_capture = cv2.VideoCapture(0) # Captures video from the default camera. 

path = '/' # Uses this path to look for student image files (files stored in JPG format) File name is as follows: "First Last, Email.jpg"

known_face_encodings = []
known_face_names = []
for root, directories, files in os.walk(path):
    for file in files:
        if '.jpg' in file:
            current_image = face_recognition.load_image_file(os.path.join(root, file))
            current_face_encoding = face_recognition.face_encodings(current_image)[0]
            known_face_encodings.append(current_face_encoding)
            known_face_names.append(file[:-4]) # Adds names and emails into list without the .jpg part of the filename

# Initialize variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True

while True:
    # Grab a single frame of video
    ret, frame = video_capture.read()

    # Resize frame of video to 1/2 size for faster face recognition processing
    small_frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)

    # Convert the image from BGR color (which OpenCV uses) to RGB color (which the face_recognition library uses)
    rgb_small_frame = small_frame[:, :, ::-1]

    # Only process every other frame of video to save time
    if process_this_frame:
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

        face_names = []
        for face_encoding in face_encodings:
            # See if the face is a match for the known face(s)
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
            name = "Unknown"

            # Use the known face with the smallest distance to the new face
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = known_face_names[best_match_index]
                f.write(name) # adds name to file to be processed by helper.py

            face_names.append(name)

    process_this_frame = not process_this_frame # Process every other frame

    # Display the results
    for (top, right, bottom, left), name in zip(face_locations, face_names):
        # Scale back up face locations since the frame we detected in was scaled to 1/2 size
        top *= 2
        right *= 2
        bottom *= 2
        left *= 2

        # Draw a box around the face
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

        # Draw a label with a name below the face
        cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)

    # Display the resulting image
    cv2.imshow('Video', frame)

    # Hit 'q' on the keyboard to quit!
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()
f.close()

Credits

Jerry Zhang

Jerry Zhang

11 projects • 15 followers

Comments