当前位置: 首页 > article >正文

Python+OpenCV系列:【打卡系统-工具模块设计】工具模块深度揭秘,考勤智能化的核心秘籍!

在当今科技飞速发展的时代,Python+OpenCV 员工打卡系统正以其卓越的智能化考勤解决方案引领潮流。而其中的工具模块,无疑是构建这一强大系统的核心秘籍,它们如同精密齿轮,紧密咬合,驱动着打卡系统高效运转。今天,就让我们一同深入探索这些令人惊叹的工具模块设计!

一、公共工具模块:系统的万能工具箱

公共工具模块堪称整个打卡系统的万能工具箱,为各类功能的实现提供了基础支撑。首先,导入模块功能如同打开宝藏箱的钥匙,引入丰富的库资源,让系统能够调用各种强大的功能。生成随机数则像是魔法棒,在需要随机性的场景中,如密码生成、验证码设置等,发挥着关键作用,为系统增添了一份神秘与安全。而检验时间格式犹如精准的时间管家,严格把关每一个时间数据的准确性,确保考勤时间记录符合标准,避免因时间格式错误导致的混乱,为后续的考勤统计分析筑牢根基。

"""
公共工具模块
"""
import random
import datetime
from entity import organizations as o


# 随机生成长度为len的数字
def randomNumber(len):
    first = str(random.randint(1, 9))  # 第一位取非0数
    last = "".join(random.sample("1234567890", len - 1))  # 后几位随机拼接任意数字
    return first + last


# 随机生成与特征码长度相等的数字
def randomCode():
    return randomNumber(o.CODE_LEN)  # 特征码的长度


# 校验时间格式
def valid_time(str):
    try:
        datetime.datetime.strptime(str, "%H:%M:%S")
        return True
    except:
        return False


# 校验年月格式
def valid_year_month(str):
    try:
        datetime.datetime.strptime(str, "%Y-%m")
        return True
    except:
        return False


# 校验日期格式
def valid_date(date):
    try:
        datetime.datetime.strptime(date, "%Y-%m-%d")
        return True
    except:
        return False

二、IO 流模块:数据流转的超级管道

IO 流模块宛如一条超级管道,负责数据在系统中的顺畅流转。其全局变量如同管道的规格参数,定义了数据传输的基本规则。文件自检方法像是管道中的智能监测仪,时刻警惕着文件可能出现的问题,如文件损坏、数据丢失等,及时发出警报并尝试修复,保障数据的完整性。从文件中加载数据就像是从管道源头汲取信息源泉,为系统运行注入活力。将数据保存到文件则是把处理后的成果沿着管道输送回存储库,以便后续使用。删除照片功能如同清理管道中的杂物,释放存储空间,保持系统的清爽高效。生成 CSV 文件像是将管道中的数据转化为通用的“数据语言”,方便与其他软件进行交互和数据共享。

from service import hr_service as hr
from entity import organizations as o
from service import recognize_service as rs
import os
import cv2
import numpy as np

PATH = os.getcwd() + "\\data\\"  # 数据文件夹根目录
PIC_PATH = PATH + "faces\\"  # 照片文件夹
DATA_FILE = PATH + "employee_data.txt"  # 员工信息文件
WORK_TIME = PATH + "work_time.txt"  # 上下班时间配置文件
USER_PASSWORD = PATH + "user_password.txt"  # 管理员账号密码文件
RECORD_FILE = PATH + "lock_record.txt"  # 打卡记录文件

IMG_WIDTH = 640  # 图像的统一宽度
IMG_HEIGHT = 480  # 图像的统一高度


# 自检,检查默认文件缺失
def checking_data_files():
    if not os.path.exists(PATH):
        os.mkdir(PATH)
        print("数据文件夹丢失,已重新创建:" + PATH)
    if not os.path.exists(PIC_PATH):
        os.mkdir(PIC_PATH)
        print("照片文件夹丢失,已重新创建:" + PIC_PATH)
    sample1 = PIC_PATH + "1000000000.png"  # 样本1文件路径
    if not os.path.exists(sample1):
        sample_img_1 = np.zeros((IMG_HEIGHT, IMG_WIDTH, 3), np.uint8)  # 创建一个空内容图像
        sample_img_1[:, :, 0] = 255  # 改为纯蓝图像
        cv2.imwrite(sample1, sample_img_1)  # 保存此图像
        print("默认样本1已补充")
    sample2 = PIC_PATH + "2000000000.png"  # 样本2文件路径
    if not os.path.exists(sample2):
        sample_img_2 = np.zeros((IMG_HEIGHT, IMG_WIDTH, 3), np.uint8)  # 创建一个空内容图像
        sample_img_2[:, :, 1] = 255  # 改为纯蓝图像
        cv2.imwrite(sample2, sample_img_2)  # 保存此图像
        print("默认样本2已补充")
    if not os.path.exists(DATA_FILE):
        open(DATA_FILE, "a+")  # 附加读写方式打开文件,达到创建空文件目的
        print("员工信息文件丢失,已重新创建:" + DATA_FILE)
    if not os.path.exists(RECORD_FILE):
        open(RECORD_FILE, "a+")  # 附加读写方式打开文件,达到创建空文件目的
        print("打卡记录文件丢失,已重新创建:" + RECORD_FILE)
    if not os.path.exists(USER_PASSWORD):
        file = open(USER_PASSWORD, "a+", encoding="utf-8")  # 附加读写方式打开文件,达到创建空文件目的
        user = dict()
        user["mr"] = "mrsoft"
        file.write(str(user))  # 将默认管理员账号密码写入到文件中
        file.close()  # 关闭文件
        print("管理员账号密码文件丢失,已重新创建:" + RECORD_FILE)
    if not os.path.exists(WORK_TIME):
        file = open(WORK_TIME, "a+", encoding="utf-8")  # 附加读写方式打开文件,达到创建空文件目的
        file.write("09:00:00/17:00:00")  # 将默认时间写入到文件中
        file.close()  # 关闭文件
        print("上下班时间配置文件丢失,已重新创建:" + RECORD_FILE)


# 加载全部员工信息
def load_employee_info():
    max_id = 1  # 最大员工ID
    file = open(DATA_FILE, "r", encoding="utf-8")  # 打开文件,只读
    for line in file.readlines():  # 遍历文件中的行内容
        id, name, code = line.rstrip().split(",")  # 去除换行符,并分割字符串信息
        o.add(o.Employee(id, name, code))  # 组织结构中添加员工信息
        if int(id) > max_id:  # 如果发现某员工的id更大
            max_id = int(id)  # 修改最大ID
    o.MAX_ID = max_id  # 记录最大ID
    file.close()  # 关闭文件


# 加载员工图像
def load_employee_pic():
    photos = list()  # 样本图像列表
    lables = list()  # 标签列表
    pics = os.listdir(PIC_PATH)  # 读取所有照片
    if len(pics) != 0:  # 如果照片文件不是空的
        for file_name in pics:  # 遍历所有图像文件
            code = file_name[0:o.CODE_LEN]  # 截取文件名开头的特征码
            photos.append(cv2.imread(PIC_PATH + file_name, 0))  # 以灰度图像的方式读取样本
            lables.append(int(code))  # 样本的特征码作为训练标签
        rs.train(photos, lables)  # 识别器训练样本
    else:  # 不存在任何照片
        print("Error >> 员工照片文件丢失,请重新启动程序并录入员工信息!")


# 将员工信息持久化
def save_employee_all():
    file = open(DATA_FILE, "w", encoding="utf-8")  # 打开员工信息文件,只写,覆盖
    info = ""  # 待写入的字符串
    for emp in o.EMPLOYEES:  # 遍历所有员工信息
        # 拼接员工信息
        info += str(emp.id) + "," + str(emp.name) + "," + str(emp.code) + "\n"
    file.write(info)  # 将这些员工信息写入到文件中
    file.close()  # 关闭文件


# 删除指定员工的所有照片
def remove_pics(id):
    pics = os.listdir(PIC_PATH)  # 读取所有照片文件
    code = str(hr.get_code_with_id(id))  # 获取该员工的特征码
    for file_name in pics:  # 遍历文件
        if file_name.startswith(code):  # 如果文件名以特征码开头
            os.remove(PIC_PATH + file_name)  # 删除此文件
            print("删除照片:" + file_name)


# 加载所有打卡记录
def load_lock_record():
    file = open(RECORD_FILE, "r", encoding="utf-8")  # 打开打卡记录文件,只读
    text = file.read()  # 读取所有文本
    if len(text) > 0:  # 如果存在文本
        o.LOCK_RECORD = eval(text)  # 将文本转换成打卡记录字典
    file.close()  # 关闭文件


# 将打卡记录持久化
def save_lock_record():
    file = open(RECORD_FILE, "w", encoding="utf-8")  # 打开打卡记录文件,只写,覆盖
    info = str(o.LOCK_RECORD)  # 将打卡记录字典转换成字符串
    file.write(info)  # 将字符串内容写入到文件中
    file.close()  # 关闭文件


# 将上下班时间写到文件中
def save_work_time_config():
    file = open(WORK_TIME, "w", encoding="utf-8")  # 打开打卡记录文件,只写,覆盖
    times = str(o.WORK_TIME) + "/" + str(o.CLOSING_TIME)
    file.write(times)  # 将字符串内容写入到文件中
    file.close()  # 关闭文件


# 加载上下班时间数据
def load_work_time_config():
    file = open(WORK_TIME, "r", encoding="utf-8")  # 打开打卡记录文件,只读
    text = file.read().rstrip()  # 读取所有文本
    times = text.split("/")  # 分割字符串
    o.WORK_TIME = times[0]  # 第一个值是上班时间
    o.CLOSING_TIME = times[1]  # 第二个值是下班时间
    file.close()  # 关闭文件


# 加载管理员账号密码
def load_users():
    file = open(USER_PASSWORD, "r", encoding="utf-8")  # 打开打卡记录文件,只读
    text = file.read()  # 读取所有文本
    if len(text) > 0:  # 如果存在文本
        o.USERS = eval(text)  # 将文本转换成打卡记录字典
    file.close()  # 关闭文件


# 生成csv文件,采用Windows默认的gbk编码
def create_CSV(file_name, text):
    file = open(PATH + file_name + ".csv", "w", encoding="gbk")  # 打开文件,只写,覆盖
    file.write(text)  # 将文本写入文件中
    file.close()  # 关闭文件
    print("已生成文件,请注意查看:" + PATH + file_name + ".csv")

三、摄像头工具模块:视觉交互的前沿哨所

摄像头工具模块无疑是打卡系统视觉交互的前沿哨所。在导入模块后,全局变量设定好了摄像头的视野范围、分辨率等关键参数,使其能够精准捕捉画面。为新员工拍照功能恰似一位专业的人像摄影师,精心定格员工的面容特征,为系统录入独一无二的人脸数据,这是后续人脸识别考勤的重要基础。开启摄像头打卡则像是打开了通往便捷考勤世界的大门,员工只需轻松站在摄像头前,系统便能迅速捕捉图像并进行处理,实现无感打卡,极大地提升了考勤效率,让员工告别繁琐的传统打卡方式。

"""
摄像头工具
"""

import cv2
from util import public_tools as tool
from util import io_tools as io
from service import recognize_service as rs
from service import hr_service as hr

ESC_KEY = 27  # Esc键的ASCII码
ENTER_KEY = 13  # Enter键的ASCII码


# 打开摄像头进行登记
def register(code):
    cameraCapture = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # 获得默认摄像头
    success, frame = cameraCapture.read()  # 读取一帧
    shooting_time = 0  # 拍摄次数
    while success:  # 如果读到有效帧数
        cv2.imshow("register", frame)  # 展示当前画面
        success, frame = cameraCapture.read()  # 再读一帧
        key = cv2.waitKey(1)  # 记录当前用户敲下的按键
        if key == ESC_KEY:  # 如果直接按ESC键
            break  # 停止循环
        if key == ENTER_KEY:  # 如果按Enter键
            # 将当前帧缩放成统一大小
            photo = cv2.resize(frame, (io.IMG_WIDTH, io.IMG_HEIGHT))
            # 拼接照片名:照片文件夹+特征码+随机数字+图片后缀
            img_name = io.PIC_PATH + str(code) + str(tool.randomNumber(8)) + ".png"
            cv2.imwrite(img_name, photo)  # 保存将图像
            shooting_time += 1  # 拍摄次数递增
            if shooting_time == 3:  # 如果拍完三张照片
                break  # 停止循环
    cv2.destroyAllWindows()  # 释放所有窗体
    cameraCapture.release()  # 释放摄像头
    io.load_employee_pic()  # 让人脸识别服务重新载入员工照片


# 打开摄像头打卡
def clock_in():
    cameraCapture = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # 获得默认摄像头
    success, frame = cameraCapture.read()  # 读取一帧
    while success and cv2.waitKey(1) == -1:  # 如果读到有效帧数
        cv2.imshow("check in", frame)  # 展示当前画面
        gary = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 将彩色图片转为灰度图片
        if rs.found_face(gary):  # 如果屏幕中出现正面人脸
            gary = cv2.resize(gary, (io.IMG_WIDTH, io.IMG_HEIGHT))  # 将当前帧缩放成统一大小
            code = rs.recognise_face(gary)  # 识别图像
            if code != -1:  # 如果识别成功
                name = hr.get_name_with_code(code)  # 获取此特征码对应的员工
                if name != None:  # 如果返回的结果不是空的
                    cv2.destroyAllWindows()  # 释放所有窗体
                    cameraCapture.release()  # 释放摄像头
                    return name  # 返回打卡成功者的姓名
        success, frame = cameraCapture.read()  # 再读一帧
    cv2.destroyAllWindows()  # 释放所有窗体
    cameraCapture.release()  # 释放摄像头

这些精心设计的工具模块相互配合、协同作战,共同铸就了 Python+OpenCV 员工打卡系统的强大功能与卓越性能。关注我们的博客,后续将继续为您揭开更多关于打卡系统的神秘面纱,带您领略智能考勤技术的无限魅力!


http://www.kler.cn/a/453272.html

相关文章:

  • Kubernetes 常用的网络插件
  • 嘉立创创建工程
  • Java 中 getClass() 方法的使用与原理分析:深入理解对象类型信息
  • Python爬虫(入门+进阶)
  • lv_ffmpeg学习及播放rtsp
  • 黑盒测试/白盒测试知识总结
  • 无影云电脑的高性能与便捷性
  • 评估大语言模型在药物基因组学问答任务中的表现:PGxQA
  • 菜鸟带新鸟——基于EPlan2022的部件库制作(3D)
  • ubuntu 网络管理--NetworkManager
  • 硬件设计:LVDS电平标准
  • 抖音小程序登录(前端通过tt.login获取code换取openId)
  • 生成10级子目录,每个子目录下有100个不同大小的文件
  • 将现有环境192.168.1.100中的svn迁移至新服务器192.168.1.4;
  • 项目管理咨询公司专注于为各类项目提供全方位的管理咨询服务
  • K8S--“ Failed to create pod sandbox: nameserver list is empty“
  • Jmeter下载安装配置教程(多版本)
  • 【目标跟踪+人流计数+人流热图(Web界面)】基于YOLOV11+Vue+SpringBoot+Flask+MySQL
  • Java 23和JDK 23详细安装方法,常用命令使用等
  • 安卓端侧大模型MLC-LLM部署全攻略:以InternLM2.5-1.8B为例
  • 任务8 数据库服务配置与管理
  • 力扣面试题 39 - 三步问题 C语言解法
  • 遗传萤火虫算法的原理
  • 【Git】—— 代码版本控制工具git的安装及基本使用
  • 【C++动态规划】1458. 两个子序列的最大点积|1823
  • 深度解析DAPP开发 | 智能合约与业务应用