文章目录
- 写在前面
- 项目分析
- 需求分析
- 1.数据模型
- 2.打卡功能
- 3.数据维护
- 4.考勤报表
- 系统设计
- 项目设计
- 1.文件系统
- 2.数据模块
- 3.工具模块
- 4.服务模块
- 5.人脸识别
- 6.主函数
- 运行结果
- 写在后面
写在前面
本期内容:基于OpenCV的WANT公司人脸识别打卡系统。
项目需求:
- pycharm
- opencv
- numpy
项目下载路径:https://download.csdn.net/download/m0_68111267/88754360
项目分析
社会上很多公司,学院都需要使用手机或者智能软件进行打卡签到。随着计算机技术的飞速发展,计算机视觉技术也越来越成熟了,例如人脸识别只需要几行代码就可以实现。打卡系统一般通过摄像头扫描人脸的特征,利用人脸的差异识别不同的人员。本文将利用Python的OpenCV简单实现一个公司打卡系统。
需求分析
打卡系统有 3 个核心功能: 录入打卡人的资料、员工打卡和查看打卡记录, 在满足核心功能的基础上需要完善一些附加功能和功能细节。在开发 MR 智能视频打卡系统前, 先对本系统的一些需求进行如下拆解和分析。
1.数据模型
本系统不使用第三方数据库, 所有数据都以文本的形式保存在文件中,因此要规范数据内容和格式, 建立统一模型。若把软件的使用者设定为“公司”,那么打卡者身份可设定为“员工”, 程序中数据模型就应该是员工数据类。每一位员工都有姓名,“姓名”就作为员工类中必备的数据之一。
因为员工可能会重名, 所以必须使用另一种标记作为员工身份的认证,即为每一位员工添加不重复的员工编号。员工编号的格式为从 1 开始递增数字, 每添加一位新员工,员工编号就+1。员工类中添加“员工编号”。
系统中必须保存所有员工的照片用于人脸识别。为了区分每位员工的照片文件,程序使用“员工特征码 + 随机值. png”的规则为照片文件命名。如果使用员工编号作为特征码, 1号员工和 11号员工的文件名容易发生混淆,所以特征码不能使用员工编号, 而是一种长度一致、复杂性高、不重复的字符串。员工类中添加“特征码”。
员工与编号、姓名、特征码是一对一的关系, 但员工与打卡记录是一对多的关系, 所以打卡记录可以放在员工类中保存,而不是单独保存在打卡记录模型中。打卡记录需要记录每一位员工的具体打卡时间,并能以报表的形式体现。可以使用字段保存打卡记录模型,员工姓名作为key, 该员工的打卡记录列表作为 value。
2.打卡功能
人脸打卡依赖于人脸识别功能。本程序可以使用 OpenCV 提供的人脸识别器实现此功能, 建议使用正确率较高的 LBPH 识别器, 其他识别器也可以考虑,但需要做好测试验证。系统通过拍照保存员工的照片样本。当员工面对摄像头时,按 Enter键就可以生成一张正面特写照片文件。为了增加识别准确率, 每位员工应拍3 张照片,也就是按3 次 Enter键才能完成录入操作。每次员工打卡成功后,都应该记录该员工的打卡时间,然后保存到文件中。
3.数据维护
数据维护总结起来就是增、删、改、查 4 种操作。简化版的打卡系统可以忽略“改”的操作,由先删除,再新增的方式代替。本系统除了提供录入新员工的功能之外,也提供删除已有员工的功能。删除员工之前应输入验证码进行验证,以防用户操作失误,误删重要数据。确认执行删除操作后,不仅要删除员工的信息,也要同时删除员工的打卡记录和照片文件。完成删除操作后,所有数据文件中不再存有被删员工的任何数据。
4.考勤报表
每个公司的考勤制度都不同,很多公司都主动设置“上班时间”和“下班时间”来做考勤的标准。员工要在“上班时间”之前打卡才算正常到岗,在“下班时间”之后打卡才算正常离岗。未在规定时间内打卡的情况属于“打卡异常”,“打卡异常”通常分为3种情况: 迟到、早退或缺席(或缺勤)。本系统分析每一位员工在某一天的打卡记录, 如果该员工在“上班时间”前和“下班时间”后都有打卡记录, 则认为该员工当天全勤, 该员工当天的其他打卡记录会被忽略。但如果该员工在“上班时间”前未能打卡, 而是在“上班时间”后到中午 12 点前打卡, 这种情况被视为迟到。如果该员工在“下班时间”后未能打卡,而是在中午12 点之后到“下班时间”前打卡, 这种情况被视为早退。当天没有打卡记录被视为缺席。
系统设计
WANT打卡系统
- 视频打卡
- 管理员登录
- 查看记录
- 查看员工记录
- 查看打卡记录
- 员工管理
- 录入新员工
- 删除员工
- 考勤报表
- 日报
- 月报
- 报表设置
- 退出系统
项目设计
1.文件系统
""" 作者:Want595 微信号:Want_595 公众号:Want595 """ import employees import os import cv2 import services path = 'data/' img_path = path + 'faces/' data_file = path + 'employees.txt' work_file = path + 'work_time.txt' user_file = path + 'user.txt' recode_file = path + 'record.txt' def checking_files(): if not os.path.exists(path): os.mkdir(path) print("数据文件丢失,已重新创建:" + path) if not os.path.exists(img_path): os.mkdir(img_path) print("照片文件丢失,已重新创建:" + img_path) if not os.path.exists(data_file): open(data_file, 'a+') print("员工信息文件丢失,已重新创建:" + data_file) if not os.path.exists(recode_file): open(recode_file, 'a+') print("打卡记录文件丢失,已重新创建:" + recode_file) if not os.path.exists(user_file): file = open(user_file, 'a+', encoding='utf-8') user = dict() user['want595'] = '123456' file.write(str(user)) file.close() print("管理员信息文件丢失,已重新创建:" + user_file) if not os.path.exists(work_file): file = open(work_file, 'a+', encoding='utf-8') file.write("09:00:00/17:00:00") file.close() print("时间配置文件丢失,已重新创建:", work_file) ……完整代码请下载后查看哦
这段代码是一个员工考勤系统的相关功能实现。它的主要功能包括员工信息的管理、打卡记录的管理、管理员账号的管理,以及相关文件的读取和保存。
首先,在代码开头定义了一些路径和文件的变量,用来存储员工信息、打卡记录、照片以及其他配置文件的路径。
接下来,通过checking_files函数来检查文件是否存在,如果某个文件不存在,则会重新创建。
然后,通过load_employees函数来读取员工信息文件,并将每条信息存储到employees模块中的EMPLOYEES列表中。同时,还会记录员工信息列表中最大的ID值。
接着,通过load_records函数来读取打卡记录文件,将记录存储到employees模块中的RECORDS字典中。
再然后,通过load_images函数来读取员工照片文件,并调用services模块的train函数来训练人脸识别模型。
接下来,通过load_works函数来读取工作时间配置文件,并将工作时间和下班时间分别保存到employees模块中的WORK_TIME和CLOSING_TIME变量中。
再然后,通过load_users函数来读取管理员账号文件,并将账号和密码保存到employees模块中的USERS字典中。
然后,通过save_employees、save_records、save_works函数来保存员工信息、打卡记录、工作时间配置到对应的文件中。
接着,通过remove_images函数来删除已经删除了的员工的照片文件。
最后,通过create_csv函数来生成CSV文件。
这段代码的核心逻辑是通过employees模块来管理员工信息、打卡记录等数据,并通过services模块来实现人脸识别的训练和识别功能。整体上,这段代码实现了一个基本的员工考勤系统的功能。
2.数据模块
""" 作者:Want595 微信号:Want_595 公众号:Want595 """ RECORDS = dict() EMPLOYEES = list() IMG_WIDTH = 960 IMG_HEIGHT = 540 MAX_ID = 0 CODE_LEN = 6 WORK_TIME = "" CLOSING_TIME = "" USERS = dict() class Employee: def __init__(self, id, name, code): self.name = name self.id = id self.code = code def add(e: Employee): EMPLOYEES.append(e) def remove(id): for i in EMPLOYEES: if str(id) == str(i.id): EMPLOYEES.remove(i) if i.name is RECORDS.keys(): del RECORDS[i.name] break def get_id(): global MAX_ID MAX_ID += 1 return MAX_ID
这部分代码定义了一些全局变量和类,用于存储员工信息和相关数据。
首先,定义了一个RECORDS字典,用于存储打卡记录。
然后,定义了一个EMPLOYEES列表,用于存储员工对象。
接着,定义了IMG_WIDTH和IMG_HEIGHT变量,用于设置图片的宽度和高度。
然后,定义了MAX_ID变量,用于记录员工信息中最大的ID值。
接下来,定义了CODE_LEN变量,表示员工的代码长度。
再然后,定义了WORK_TIME和CLOSING_TIME变量,用于存储每天的上班时间和下班时间。
最后,定义了一个USERS字典,用于存储管理员的账号和密码。
接下来,定义了一个Employee类,表示员工对象。它有三个属性,分别是id、name和code,分别表示员工的ID、姓名和代码。构造函数接收这三个参数来初始化员工对象。
接着,定义了add函数,用于将员工对象添加到EMPLOYEES列表中。
然后,定义了remove函数,用于根据员工ID从EMPLOYEES列表中移除对应的员工对象。同时,如果该员工的姓名存在于RECORDS字典中,也会将对应的记录删除。
最后,定义了get_id函数,用于获取一个新的员工ID。它先将MAX_ID增加1,然后返回新的ID值。
这部分代码主要是定义了一些全局变量和类,用于存储和操作员工信息和相关数据。
3.工具模块
""" 作者:Want595 微信号:Want_595 公众号:Want595 """ import random as rd import datetime as dt import employees def randomCode(): first = str(rd.randint(1, 9)) last = "".join(rd.sample("1234567890", employees.CODE_LEN - 1)) return first + last def valid_time(str): try: dt.datetime.strptime(str, "%H:%M:%S") return True except: return False def valid_year_month(str): try: dt.datetime.strptime(str, "%Y-%m") return True except: return False def valid_date(date): try: dt.datetime.strptime(date, "%Y-%m-%d") return True except: return False
这部分代码定义了一些辅助函数,用于生成随机代码、验证时间和日期的有效性。
首先,定义了一个randomCode函数,用于生成随机的员工代码。它首先生成一个1到9的随机数作为代码的第一位数字,然后使用rd.sample函数从数字"1234567890"中随机选择出长度为employees.CODE_LEN - 1的数字,将它们拼接在一起,得到最终的员工代码。
接下来,定义了一个valid_time函数,用于验证输入的时间字符串是否符合格式"%H:%M:%S"。它使用datetime.datetime.strptime函数将时间字符串转换为日期时间对象,如果转换成功,则说明时间字符串有效,返回True;否则,返回False。
然后,定义了一个valid_year_month函数,用于验证输入的年份和月份字符串是否符合格式"%Y-%m"。与valid_time函数类似,它使用datetime.datetime.strptime函数将字符串转换为日期时间对象,如果转换成功,则说明年份和月份字符串有效,返回True;否则,返回False。
最后,定义了一个valid_date函数,用于验证输入的日期字符串是否符合格式"%Y-%m-%d"。同样地,它使用datetime.datetime.strptime函数将日期字符串转换为日期时间对象,如果转换成功,则说明日期字符串有效,返回True;否则,返回False。
这些辅助函数可以在其他地方被调用,用于验证和处理时间和日期相关的输入。
4.服务模块
""" 作者:Want595 微信号:Want_595 公众号:Want595 """ import employees import public import inits import datetime import calendar import cv2 import numpy as np def init_data(): inits.checking_files() inits.load_users() inits.load_records() inits.load_employees() inits.load_images() def add_employee(name): code = public.randomCode() employee = employees.Employee(employees.get_id(), name, code) employees.add(employee) inits.save_employees() return code def remove_employee(id): inits.remove_images(id) employees.remove(id) inits.save_employees() inits.save_records() ……完整代码请下载后查看哦
5.人脸识别
""" 作者:Want595 微信号:Want_595 公众号:Want595 """ import cv2 import inits import employees import public import services ESC_KEY = 27 ENTER_KEY = 13 def register(code): capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) success, frame = capture.read() times = 0 while success: cv2.imshow("register", frame) success, frame = capture.read() key = cv2.waitKey(1) if key == ESC_KEY: break if key == ENTER_KEY: image = cv2.resize(frame, (employees.IMG_WIDTH, employees.IMG_HEIGHT)) img_name = str('data/faces/' + code + public.randomCode() + '.png') cv2.imwrite(img_name, image) print("保存成功:" + img_name) times += 1 if times == 3: break cv2.destroyAllWindows() capture.release() inits.load_images() ……完整代码请下载后查看哦
6.主函数
""" 作者:Want595 微信号:Want_595 公众号:Want595 """ import camera import public import services admin_login = False def login(): while True: username = input("请输入管理员账号:") if username == "0": return password = input("请输入管理员密码:") if services.valid_user(username.strip(), password.strip()): global admin_login admin_login = True print("登录成功!") break else: print("登录失败!请重新登录!!") ……完整代码请下载后查看哦
运行结果
写在后面
我是一只有趣的兔子,感谢你的喜欢!
猜你喜欢
- 4小时前自学(网络安全)黑客——高效学习2024
- 4小时前【深度学习目标检测】十六、基于深度学习的麦穗头系统-含GUI和源码(python,yolov8)
- 4小时前计算机视觉丨基于OpenCV的人脸识别打卡系统
- 4小时前Java接收前端请求体方式
- 4小时前[SWPUCTF 2022 新生赛]奇妙的MD5
- 4小时前iptables使用
- 4小时前【论文阅读】Deep Graph Contrastive Representation Learning
- 4小时前kafka服务器连接出现:[NetworkClient.java:935] [Producer clientId=producer-1] Node -1 disconnected原因分析
- 4小时前JavaMySql+hadoop高校固定资产管理系统 74965(免费领源码)计算机毕业设计选题推荐上万套实战教程JAVA、PHP,node.js,C++、python等
- 4小时前将网页数据读入数据库+将数据库数据读出到网页——基于python flask实现网页与数据库的交互连接【全网最全】
网友评论
- 搜索
- 最新文章
- 热门文章