Python OpenCV开发MR智能人脸识别打卡系统(三工具模块设计)
Posted showswoller
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python OpenCV开发MR智能人脸识别打卡系统(三工具模块设计)相关的知识,希望对你有一定的参考价值。
需要源码请点赞关注收藏后评论区留言私信~~~
整体系统讲解如下
Python OpenCV开发MR智能人脸识别打卡系统(一、需求分析与系统设计)
Python OpenCV开发MR智能人脸识别打卡系统(二、文件系统、数据实体模块设计)
Python OpenCV开发MR智能人脸识别打卡系统(四、服务模块设计)
Python OpenCV开发MR智能人脸识别打卡系统(五、程序入口设计与测试)
本系统的工具模块包含三个文件:public_tools.py,io_tools.py,camera.py下面将详细介绍三个文件中的代码内容及功能
一、公共工具模块
public_tools.py模块提供了以下功能:
生成随机数和随机特征码
校验时间字符串格式
下面介绍里面的代码
1:导入模块
公共工具设计随机数和日期格式,所以导入random和datetime模块,生成随机特征码要通过organizations获取特征码长度,所以也要导入数据实体模块
import random
import datetime
from entity import organizations as o
2:生成随机数
特征码、照片文件名和验证码都用到了随机数,公共工具模块提供了一个生成指定位数数字的randomNumber方法,其参数就是数字的位数,且不会以0开头,该方法最后返回的是字符串类
# 随机生成长度为len的数字
def randomNumber(len):
first = str(random.randint(1, 9)) # 第一位取非0数
last = "".join(random.sample("1234567890", len - 1)) # 后几位随机拼接任意数字
return first + last
特征码实际上是长度固定的随机码,特征码的程度保存在数据实体模块的code_len变量中,可以直接调用方法创建特征码,最好保持六位以上,这样才能降低特征码重复概率
3:校验时间格式
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_tools.py是本程序的IO流工具模块,该模块提供了以下功能:
封装所有对文件的读写操作,包括加载员工信息,加载打卡记录,加载照片文件等等
文件自检功能
创建CSV文件
1:导入模块
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
2:全局变量
全局变量中保存了各个数据文件配置,包含文件路径,文件名和照片的宽和高
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 # 图像的统一高度
3:文件自检方法
为了防止用户误删数据文件而导致程序无法正常运行,该方法在程序启动时执行,然后自动检查所有数据文件的状态,如果发现丢失文件,就会自动创建新的空数据文件。
# 自检,检查默认文件缺失
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)
4:从文件中加载数据
本系统中的所有数据都保存在文本文件中,当程序启动时需要加载所有数据,包括员工信息,员工打卡记录和员工照片
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 >> 员工照片文件丢失,请重新启动程序并录入员工信息!")
5:将数据保存到文件中
既然有加载数据的方法,也就应该有保存数据的方法,当数据发生变化时,程序应该立刻将变化后的数据保存到本地硬盘上
# 将员工信息持久化
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() # 关闭文件
6:删除照片
该方法首先通过员工编号获取该员工的特征码,然后到照片文件夹中遍历所有文件,只要文件名以此员工的特征码开头,就将文件删除,删除后在控制台打印删除日志以提醒用户
# 删除指定员工的所有照片
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)
7:生成CSV文件
考勤月报是一个内容非常多的报表,不适合在控制台中展示,但很适合生成Excel报表来展示,我们使用更简单的CSV文件来展示报表,Excel可以直接打开CSV文件
CSV文件实际上是一个文本文件,每一行文字都对应Excel中的一行内容,CSV文件将每一行文字内容用英文逗号分分隔,Excel根据这些英文逗号自动将文字内容分配到每一列中
# 生成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")
三、摄像头工具模块
该模块提供以下功能:
开启摄像头打卡
开启摄像头为员工拍照
1:导入模块
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
2:全局变量
ESC_KEY = 27 # Esc键的ASCII码
ENTER_KEY = 13 # Enter键的ASCII码
3:为新员工拍照
# 打开摄像头进行登记
def register(code):
cameraCapture = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 获得默认摄像头
suc
cess, 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() # 让人脸识别服务重新载入员工照片
4:开启摄像头打卡
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() # 释放摄像头
/data/face/文件夹中员工照片文件
创作不易 觉得有帮助请点赞关注收藏~~~
以上是关于Python OpenCV开发MR智能人脸识别打卡系统(三工具模块设计)的主要内容,如果未能解决你的问题,请参考以下文章
Python OpenCV开发MR智能人脸识别打卡系统(五程序入口设计与测试)
Python人脸识别智能考勤系统 (供源码,附报告)(可答疑,可调试)