基于OpenCV的人脸识别考勤

729 阅读4分钟

人脸考勤是一种应用程序,它通过识别和记录员工的面部特征来自动跟踪和管理员工的考勤。为了实现人脸考勤系统,我们需要使用计算机视觉技术和深度学习模型来识别和比对员工的面部特征,并将这些数据与员工的考勤记录关联起来。

步骤 1:采集员工面部图像

首先,我们需要采集员工的面部图像作为训练数据集。对于这个任务,我们可以使用基于OpenCV的Python库来拍摄员工的照片。代码如下:

import cv2

# initialize camera object
cap = cv2.VideoCapture(0)

# loop that captures employee face images
while True:
    # read a frame from the camera
    ret, frame = cap.read()

    # display the captured image
    cv2.imshow('captured image', frame)

    # wait for the user to press 'c' key to capture the image
    if cv2.waitKey(1) & 0xFF == ord('c'):
        # save the captured image to file
        cv2.imwrite('employee.jpg', frame)
        break

# release the camera and close all windows
cap.release()
cv2.destroyAllWindows()

在此示例中,我们首先初始化一个摄像头对象 cap ,然后进入一个无限循环中。 在每次循环迭代中,我们从摄像头读取一个帧 frame 并将其显示在窗口上。 如果用户按下 C 键,则会将该图像保存到名为 employee.jpg 的文件中,然后退出无限循环并关闭窗口。

可以通过多次运行此代码并采集员工的面部照片来收集训练数据集。

步骤 2:训练深度学习模型

使用我们所采集的员工面部图像,我们现在可以训练一个基于深度学习技术的模型来识别不同的员工。 对于这个任务,我们可以使用OpenCV中的级联分类器(Cascade Classifier)。

代码如下:

import cv2

# define a function to detect faces in an image
def detect_faces(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
    return faces

# load employee images and create labeled dataset
img1 = cv2.imread('employee1.jpg')
faces1 = detect_faces(img1)
for (x, y, w, h) in faces1:
    cv2.rectangle(img1, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('employee1', img1)

img2 = cv2.imread('employee2.jpg')
faces2 = detect_faces(img2)
for (x, y, w, h) in faces2:
    cv2.rectangle(img2, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('employee2', img2)

# create a labeled dataset
employees = {}
employees["employee1"] = faces1
employees["employee2"] = faces2

# train a face recognizer model using the labeled dataset
recognizer = cv2.face.LBPHFaceRecognizer_create()
ids = []
images = []
for label, faces in employees.items():
    for face in faces:
        image = cv2.imread(f"{label}.jpg")
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        images.append(gray[face[1]:face[1]+face[3], face[0]:face[0]+face[2]])
        ids.append(int(label.split("employee")[1]))
recognizer.train(images, np.array(ids))

在此示例中,我们首先定义了一个函数 detect_faces() ,该函数接受一张图像并使用面部级联分类器检测其中的所有面部。 我们随后加载拍摄好的员工面部图像,并用 detect_faces() 函数检测所有的员工的面部。 然后,我们将每个员工的脸部区域存储在名为 employees 的字典中,并用整数标签作为键,名称作为值。

最后,我们使用 OpenCV 中的 LBPH (Local Binary Patterns Histograms)人脸识别器模型训练一个深度学习模型,并提供以前述的 employees 定义的面部图像和标签。

步骤 3:实时人脸检测和考勤记录

现在,我们已经拥有一种训练好的深度学习模型 接下来,我们可以使用训练好的模型在实时视频流中检测人脸,并记录每个员工的考勤时间。代码如下:

import cv2
import datetime

# initialize camera object
cap = cv2.VideoCapture(0)

# load the face recognizer model
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('model.yml')

# define a function to draw the labels on the image
def draw_labels(image, label, confidence, x, y):
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(image, label, (x, y), font, 1, (0, 255, 0), 1)
    cv2.putText(image, str(round(confidence, 2)), (x, y+30), font, 1, (0, 255, 0), 1)

# define a dictionary to store employee attendance
attendance = {}

# start the video stream and process each frame
while True:
    # read next frame from the camera
    ret, frame = cap.read()

    # convert the frame to grayscale and detect faces in it
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

    # for each detected face, predict the label and draw the attendance record
    for (x, y, w, h) in faces:
        # extract the face region from the grayscale image
        roi_gray = gray[y:y+h, x:x+w]

        # use the recognizer model to predict the label for the face
        label, confidence = recognizer.predict(roi_gray)

        # draw the label and attendance record on the image
        draw_labels(frame, f'Employee {label}', confidence, x, y)

        # check if this employee has been detected before
        now = datetime.datetime.now()
        if label in attendance:
            last_time = attendance[label]
            if (now - last_time).seconds > 30: # consider re-recording after 30 seconds of previous attendance
              attendance[label] = now
              print(f"Attendance recorded for Employee {label} at {now}")
        else:
            attendance[label] = now
            print(f"Attendance recorded for new Employee {label} at {now}")
    
    # display the resulting image
    cv2.imshow('Face Attendance', frame)

    # wait for the user to press 'q' key to quit the program
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# release the camera and close all windows
cap.release()
cv2.destroyAllWindows()

在此示例中,我们首先初始化一个摄像头对象 cap ,并加载人脸识别器模型。然后,我们在一个无限循环中,每次从摄像头读取一帧图像,并使用面部级联分类器检测其中的所有面部。 对于每个检测到的脸,我们调用识别器模型来预测其标签,并在图像上绘制标签和置信度分数。

如果该员工之前没有登记过出勤,则将其录入考勤记录,否则只有在距离前一次记录超过30秒的情况下才会重新记录。 最后,我们将考勤的详细信息输出到控制台,并在显示视频期间显示图像。