人脸识别签到系统

1、运用场景

课堂签到,上班打卡,进出门身份验证。

2、功能架构

人脸录入,打卡签到,声音提醒,打卡信息导出:
人脸识别签到打卡系统一站式开发【基于PyQt5的CS架构软件】_ico

3、技术栈

python3.8,sqlite3,opencv,face_recognition,PyQt5,csv

第三方库:

asgiref==3.8.1
click==8.1.7
colorama==0.4.6
comtypes==1.4.4
dlib @ file:dlib-19.19.0-cp38-cp38-win_amd64.whl.whl#sha256=89a19fe0003e2fa2ff33264b5abba82443056f915b2339feb167569b4446a460
et-xmlfile==1.1.0
face-recognition==1.3.0
face_recognition_models==0.3.0
numpy==1.24.4
opencv-python==4.10.0.84
openpyxl==3.1.5
pillow==10.3.0
pypiwin32==223
PyQt5==5.15.10
PyQt5-Qt5==5.15.2
PyQt5-sip==12.13.0
pyttsx3==2.90
pytz==2024.1
pywin32==306
sqlparse==0.5.0
typing_extensions==4.12.2

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

4、人脸识别流程图

1、导入库
2、编写UI界面
3、打开摄像头录入人脸信息
4、比对人脸信息并发出声音提醒
5、导出打卡信息
6、打包成exe可执行文件
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

人脸识别签到打卡系统一站式开发【基于PyQt5的CS架构软件】_ico_02

5、数据库

5.1、用户表
字段描述类型大小
id主键integer
name姓名text256
account账号text256
password密码text256
is_admin是否为管理员integer
icon_feature人脸特征blob1024
addtime添加时间text256

sql语句:

PRAGMA foreign_keys = false;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS "user";
CREATE TABLE "user" (
  "id" INTEGER NOT NULL,
  "name" TEXT(256),
  "account" TEXT(256),
  "password" TEXT(256),
  "is_admin" integer,
  "icon_feature" blob(1024),
  "addtime" TEXT(256),
  PRIMARY KEY ("id")
);

PRAGMA foreign_keys = true;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
5.2、记录表
字段描述类型大小
id主键integer
userid用户idinteger
name用户姓名text256
is_login是否登录:0 :登录,1:上班打卡,2:下班打卡integer
content打卡日志text256
addtime添加时间text256

sql语句:

PRAGMA foreign_keys = false;

-- ----------------------------
-- Table structure for logs
-- ----------------------------
DROP TABLE IF EXISTS "logs";
CREATE TABLE "logs" (
  "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  "userid" INTEGER,
  "name" TEXT(256),
  "is_login" integer,
  "content" TEXT(256),
  "addtime" TEXT
);

-- ----------------------------
-- Auto increment value for logs
-- ----------------------------
UPDATE "sqlite_sequence" SET seq = 12 WHERE name = 'logs';

PRAGMA foreign_keys = true;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

6、UI界面

6.1、主界面
主要功能:
1、摄像头实时采集人脸数据
2、账号密码打卡
3、输出打卡结果
4、语音播放
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
6.2、人脸录入功能
功能:
1、管理员登录
2、账号密码修改
3、人脸信息更改
4、用户信息更改
5、用户信息录入
6、摄像头采集人脸数据
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
6.3、打卡记录
功能:
1、打卡记录查询
2、打卡记录输出
3、打卡记录导出excel文件,并使用橙色标记异常情况,可在输出框直接打开文件
  • 1.
  • 2.
  • 3.
  • 4.
6.4、代码
# -*- coding: utf-8 -*-

"""
@contact: 微&*&*&信 1257309054
@file: main.py
@time: 2024/6/30 11:09
@author: LDC
"""
class OpenLoginCameraThread(QThread):
    # 摄像头打开多线程
    _signal_thread = pyqtSignal(str)

    def __init__(self, parent=None):
        super(OpenLoginCameraThread, self).__init__(parent)
        self.window = parent
        self.qmut = QMutex()  # 互斥量
        self.is_exit_run = False  # 默认人脸识别里面的摄像头是循环打开的
        self.cap = None

    def get_capture(self):
        '''
        打开摄像头
        :return:
        '''
        try:
            self.cap = cv2.VideoCapture(0)
            w, h = 640, 360

            self.cap.set(3, w)
            self.cap.set(4, h)
            return True
        except Exception as e:
            self.cap = None
            self.window.sign_in_info.setText('打开摄像头失败,{}'.format(e))
            return False

    def open_login_camera(self):
        '''
        打开摄像头
        :return:
        '''

        self.is_close_camera = False  # 设备摄像头打开
        while 1:
            if self.is_exit_run:
                break
            if not self.cap:
                if not self.get_capture():
                    time.sleep(3)
                    continue
            try:
                success, img = self.cap.read()  # 读取图片
                mirrow = cv2.flip(img, 1)
                width, height = mirrow.shape[:2]  # 行:宽,列:高

                # 显示图片
                image_show = cv2.cvtColor(mirrow, cv2.COLOR_BGR2RGB)  # opencv读的通道是BGR,要转成RGB
                camera_img = QtGui.QImage(image_show.data, height, width, QImage.Format_RGB888)

                self.window.label_video.setPixmap(QPixmap.fromImage(camera_img))  # 往显示视频的Label里显示QImage

                is_face, icon_feature = self.window.get_face_feature(camera_img)
                if is_face:
                    user = self.window.compare_feature(icon_feature)
                    if user:
                        self._signal_thread.emit(json.dumps({'user': user}))  # 把人脸信息传回主进程
                        time.sleep(1)
                    else:
                        self._signal_thread.emit(json.dumps({'info': '人脸未录入!'}))
                else:
                    self._signal_thread.emit(json.dumps({'info': '获取人脸失败,请打开摄像头,对准人脸!'}))
            except:
                pass

        # 释放摄像头 release camera
        self.cap.release()
        self.cap = None

    def run(self):
        self.is_exit_run = False
        print('人脸识别进入循环,打开摄像头')
        self.open_login_camera()
        print('人脸识别已退出循环,关闭摄像头')

    def stop(self):
        # 改变线程状态与终止
        self.is_exit_run = True
        self.wait()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
6.5、效果