信息发布→ 登录 注册 退出

Python+OpenCV人脸识别签到考勤系统实现(附demo)

发布时间:2026-01-11

点击量:
目录
  • 前言
  • 项目效果图
  • 项目需要的环境
    • 编译器
  • 代码部分
    • 后记
      • 项目下载

        前言

        本项目为IOT实验室人员签到考勤设计,系统实现功能:
        1.人员人脸识别并完成签到/签退
        2.考勤时间计算
        3.保存考勤数据为CSV格式(Excel表格)

        PS:本系统2D人脸识别,节约了繁琐的人脸识别训练部分,简洁快捷

        该项目为测试版,正式版会加入更多的功能,持续更新中…
        测试版项目地址我会放到结尾

        项目效果图

        系统初始化登陆界面

        主界面展示图:

        签到功能展示

        签退功能展示

        后台签到数据记录

        是否签到/退判断

        项目需要的环境

        核心环境:

        • OpenCV-Python 4.5.5.64
        • face_recognition 1.30
        • face_recognition_model 0.3.0
        • dlib 19.23.1

        UI窗体界面:

        • PyQt5 5.15.4
        • pyqt5-plugins 5.15.4.2.2
        • PyQt5-Qt5 5.15.2
        • PyQt5-sip 12.10.1
        • pyqt5-tools 5.15.4.3.2

        编译器

        Pycham 2025.1.3

        Python版本 3.9.12

        Anaconda

        辅助开发QT-designer

        项目配置

        代码部分

        核心代码

        MainWindow.py
        UI文件加载:

        class Ui_Dialog(QDialog):
            def __init__(self):
                super(Ui_Dialog, self).__init__()
                loadUi("mainwindow.ui", self)       #加载QTUI文件
        
                self.runButton.clicked.connect(self.runSlot)
        
                self._new_window = None
                self.Videocapture_ = None
        

        摄像头调用:

            def refreshAll(self):
                print("当前调用人俩检测摄像头编号(0为笔记本内置摄像头,1为USB外置摄像头):")
                self.Videocapture_ = "0"
        

        OutWindow.py
        获取当前系统时间

        class Ui_OutputDialog(QDialog):
            def __init__(self):
                super(Ui_OutputDialog, self).__init__()
                loadUi("./outputwindow.ui", self)   #加载输出窗体UI
        
                #datetime 时间模块
                now = QDate.currentDate()
                current_date = now.toString('ddd dd MMMM yyyy')  #时间格式
                current_time = datetime.datetime.now().strftime("%I:%M %p")
                self.Date_Label.setText(current_date)
                self.Time_Label.setText(current_time)
        
                self.image = None
        

        签到时间计算

            def ElapseList(self,name):
                with open('Attendance.csv', "r") as csv_file:
                    csv_reader = csv.reader(csv_file, delimiter=',')
                    line_count = 2
        
                    Time1 = datetime.datetime.now()
                    Time2 = datetime.datetime.now()
                    for row in csv_reader:
                        for field in row:
                            if field in row:
                                if field == 'Clock In':
                                    if row[0] == name:
                                        Time1 = (datetime.datetime.strptime(row[1], '%y/%m/%d %H:%M:%S'))
                                        self.TimeList1.append(Time1)
                                if field == 'Clock Out':
                                    if row[0] == name:
                                        Time2 = (datetime.datetime.strptime(row[1], '%y/%m/%d %H:%M:%S'))
                                        self.TimeList2.append(Time2)
        

        人脸识别部分

        # 人脸识别部分
                faces_cur_frame = face_recognition.face_locations(frame)
                encodes_cur_frame = face_recognition.face_encodings(frame, faces_cur_frame)
        
                for encodeFace, faceLoc in zip(encodes_cur_frame, faces_cur_frame):
                    match = face_recognition.compare_faces(encode_list_known, encodeFace, tolerance=0.50)
                    face_dis = face_recognition.face_distance(encode_list_known, encodeFace)
                    name = "unknown"    #未知人脸识别为unknown
                    best_match_index = np.argmin(face_dis)
                    if match[best_match_index]:
                        name = class_names[best_match_index].upper()
                        y1, x2, y2, x1 = faceLoc
                        cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                        cv2.rectangle(frame, (x1, y2 - 20), (x2, y2), (0, 255, 0), cv2.FILLED)
                        cv2.putText(frame, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 255), 1)
                    mark_attendance(name)
        
                return frame
        

        签到数据保存与判断

        # csv表格保存数据
                def mark_attendance(name):
                    """
                    :param name: 人脸识别部分
                    :return:
                    """
                    if self.ClockInButton.isChecked():
                        self.ClockInButton.setEnabled(False)
                        with open('Attendance.csv', 'a') as f:
                                if (name != 'unknown'):         #签到判断:是否为已经识别人脸
                                    buttonReply = QMessageBox.question(self, '欢迎 ' + name, '开始签到' ,
                                                                       QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                                    if buttonReply == QMessageBox.Yes:
        
                                        date_time_string = datetime.datetime.now().strftime("%y/%m/%d %H:%M:%S")
                                        f.writelines(f'\n{name},{date_time_string},Clock In')
                                        self.ClockInButton.setChecked(False)
        
                                        self.NameLabel.setText(name)
                                        self.StatusLabel.setText('签到')
                                        self.HoursLabel.setText('开始签到计时中')
                                        self.MinLabel.setText('')
        
                                        self.Time1 = datetime.datetime.now()
                                        self.ClockInButton.setEnabled(True)
                                    else:
                                        print('签到操作失败')
                                        self.ClockInButton.setEnabled(True)
                    elif self.ClockOutButton.isChecked():
                        self.ClockOutButton.setEnabled(False)
                        with open('Attendance.csv', 'a') as f:
                                if (name != 'unknown'):
                                    buttonReply = QMessageBox.question(self, '嗨呀 ' + name, '确认签退?',
                                                                      QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                                    if buttonReply == QMessageBox.Yes:
                                        date_time_string = datetime.datetime.now().strftime("%y/%m/%d %H:%M:%S")
                                        f.writelines(f'\n{name},{date_time_string},Clock Out')
                                        self.ClockOutButton.setChecked(False)
        
                                        self.NameLabel.setText(name)
                                        self.StatusLabel.setText('签退')
                                        self.Time2 = datetime.datetime.now()
        
                                        self.ElapseList(name)
                                        self.TimeList2.append(datetime.datetime.now())
                                        CheckInTime = self.TimeList1[-1]
                                        CheckOutTime = self.TimeList2[-1]
                                        self.ElapseHours = (CheckOutTime - CheckInTime)
                                        self.MinLabel.setText("{:.0f}".format(abs(self.ElapseHours.total_seconds() / 60)%60) + 'm')
                                        self.HoursLabel.setText("{:.0f}".format(abs(self.ElapseHours.total_seconds() / 60**2)) + 'h')
                                        self.ClockOutButton.setEnabled(True)
                                    else:
                                        print('签退操作失败')
                                        self.ClockOutButton.setEnabled(True)
        

        项目目录结构

        后记

        因为本系统没有进行人脸训练建立模型,系统误识别率较高,安全性较低
        系统优化较差,摄像头捕捉帧数较低(8-9),后台占有高,CPU利用率较高
        数据保存CSV格式,安全性较低

        正式版改进

        1.加入TensorFlow深度学习,提高系统人脸识别安全性与准确性
        2.加入MySQL数据库,对签到数据进行更安全保护,不易被修改
        3.美化优化UI设计

        项目下载

        IOT人脸识别签到系统测试版V0.99

        在线客服
        服务热线

        服务热线

        4008888355

        微信咨询
        二维码
        返回顶部
        ×二维码

        截屏,微信识别二维码

        打开微信

        微信号已复制,请打开微信添加咨询详情!