【保姆级教程】基于OpenCV+Python的人脸识别上课签到系统

您所在的位置:网站首页 签到算法 【保姆级教程】基于OpenCV+Python的人脸识别上课签到系统

【保姆级教程】基于OpenCV+Python的人脸识别上课签到系统

2024-07-06 06:52| 来源: 网络整理| 查看: 265

【保姆级教程】基于OpenCV+Python的人脸识别上课签到系统 一、软件安装及环境配置1. 安装IDE:PyCharm2. 搭建Python的环境3. 新建项目、安装插件、库 二、源文件编写1. 采集人脸.py2. 训练模型.py3. 生成表格.py4. 识别签到.py5. 创建图形界面.py 三、相关函数分析1.采集人脸2.训练模型3.识别签到4.创建图形界面

一、软件安装及环境配置 1. 安装IDE:PyCharm

进入PyCharm官网:https://www.jetbrains.com/pycharm/ ,点击Download. 请添加图片描述

选择系统版本windows,选择Community版本(因为免费),点击Downlad。 在这里插入图片描述

下载完成后双击开始安装,点击Next. 在这里插入图片描述

选择合适路径(建议除了C以外的其他盘),点击Next。

勾选所有选项,点击Next. 在这里插入图片描述

点击Install,选择JetBrains. 在这里插入图片描述

等待安装结束,Rboot now或 I want manually reboot later随便选一个即可,点击finish. 在这里插入图片描述

双击打开Pycharm,首次打开会出现如下弹窗,勾选方框,点击Continue。勾选Don’t send 在这里插入图片描述 在这里插入图片描述 至此pyCharm软件安装完毕.

2. 搭建Python的环境

打开Python官方网站:https://www.Python.org,点击Downlads. 在这里插入图片描述

进入Python下载界面,选择Windows. 在这里插入图片描述

选择下面红框框住的版本:Download Windows x86-64 executable installer 在这里插入图片描述 这可能会下载的非常慢,推荐Internat Download Manager下载器(简称IDM),可以加速外网资源的下载,几个线程同时下载提高下载速度(官方说的最多五倍,个人觉得不止),官方地址https://www.internetdownloadmanager.com/download.html. 在这里插入图片描述 鼠标移到安装包上,按右键复制地址,打开IDM后,新建任务,把下载资源地址复制进去即可. 在这里插入图片描述

下载完成后,双击Python-3.6.5rc1-amd64文件进行安装,切记在选项Add Python 3.6 to PATH的框中打钩,然后点击Install Now进入下一步. 在这里插入图片描述 注:安装时一定要自定义安装解释器,因为后续库的安装地址同解释器的安装位置。项目小还好,项目大会把C盘“撑爆”.

耐心等待,安装完成后会弹出一个界面,点击close. 在这里插入图片描述

检查Python环境是否搭建成功,在Windows窗口中按 win+R,打开命令窗口,输入cmd,点击“确定”按钮,在新弹出的命令窗口中输入“Python” (或“py”)回车,显示如下界面说明安装成功。 在这里插入图片描述 在这里插入图片描述

3. 新建项目、安装插件、库 打开pyCharm,点击新建项目,为新项目命名并选择路径,点击Create. 在这里插入图片描述安装中文插件,在搜索框中输入Chinese,安装中文简体语言包. 在这里插入图片描述 在这里插入图片描述 安装成功后,点击Restart IDE重启软件,即可换为中文模式.安装项目所需要的库,本项目用到的第三方库:opencv-python、opencv-contrib-python、pillow、 numpy、tk、xlrd、xlwt、xlutils、DateTime。 由于外网网速原因,大概率会面临安装失败的问题,此时可以采用国内镜像源,利用pip加速安装. 在这里插入图片描述 以opencv-python库为例,打开终端,输入下述命令: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

在这里插入图片描述 终端pip安装完后,再打开python解释器安装软件包,速度快如飞雷神. 在这里插入图片描述 其余库安装流程类似,此处不做演示.

二、源文件编写

整体架构: 在这里插入图片描述

注意:把代码中涉及到的路径换为自己电脑下,否则编译器找不见报错

1. 采集人脸.py

演示:学号为:1111111111;姓名为:iu 在这里插入图片描述

首先,下载haarcascade_frontalface_default.xml,并把该xml文件移动到该项目下。下载地址https://gitcode.com/opencv/opencv/tree/master/data/haarcascades?utm_source=csdn_github_accelerator&isLogin=1

import cv2 import os # 定义变量 classifier = cv2.CascadeClassifier(r'D:\hello_world\pythonProject\haarcascade_frontalface_default.xml') font = cv2.FONT_HERSHEY_SIMPLEX stu_id = input('请输入你的学号: \n') stu_name = input('请输入你的姓名: \n') count = 0 # 建立人脸数据文件夹 if not os.path.exists('data'): os.mkdir('data') # 打开摄像头 capture = cv2.VideoCapture(0) while capture.isOpened(): kk = cv2.waitKey(1) _,farme = capture.read() gray = cv2.cvtColor(farme, cv2.COLOR_BGR2GRAY) faces = classifier.detectMultiScale(gray, 1.2, 5) if len(faces) != 0: for x, y, w, h in faces: cv2.rectangle(farme, (x, y), (x + w, y + h), (200, 0, 250), 2) # center = (x + w // 2, y + h // 2) # r = w // 2 # cv2.circle(farme, center, r, (0, 250, 0), 2) cv2.putText(farme, 'Press "s" to save' , (x + w, y + h), font, 1, (200, 0, 250), 2) if kk == ord('s'): cv2.imwrite('data/'+str(stu_name)+'.'+str(stu_id)+'.'+str(count)+'.jpg', gray[y:y+h,x:x+w]) count += 1 print('采集了'+str(count)+'张图片。') cv2.putText(farme, 'Press "q" to quit', (30, 60), font, 1, (200, 0, 250), 2) cv2.imshow('Picture from capture',farme) if kk == ord('q'): print('共采集了学号为'+str(stu_id)+'姓名为'+str(stu_name)+'的同学的'+str(count)+'张图片') break # 释放摄像头 capture.release() cv2.destroyAllWindows()

操作流程:右键运行’采集人脸’,输入自己的ID号(笔者是10位学号),输入姓名首字母(例:张三,输入zs),Enter。按s保存采集到的图像,一般采集20张,按q退出(注意:按s和q时必须切换至英文输入法模式)

2. 训练模型.py import cv2 import numpy as np from PIL import Image import os create = cv2.face.LBPHFaceRecognizer_create() def data_translate(path): face_data = [] id_data = [] file_list = [os.path.join(path, f) for f in os.listdir(path)] # print(file_list) # print(len(file_list)) for file in file_list: PIL_image = Image.open(file).convert('L') np_image = np.array(PIL_image, "uint8") # print(file) # print(file.split('.')) # print(file.split('.')[1]) id = int(file.split('.')[1]) # print(file.split('.')[0]) face_data.append(np_image) id_data.append(id) return face_data, id_data print('开始训练模型') # data_translate(r'data\data') Faces,Ids = data_translate(r'D:\hello_world\pythonProject\data') create.train(Faces,np.array((Ids))) create.save('trainer.yml') print('模型保存成功')

操作流程:右键运行’训练模型’,运行成功后,会生成一个trainer.yml文件.

3. 生成表格.py # 引入库 import xlrd import xlwt from xlutils.copy import copy # 创建工作簿 nwb = xlwt.Workbook() cjb = nwb.add_sheet('成绩表') cjb.write_merge(0, 0, 0, 3, '成绩表') a = ['序号', '学号', '姓名', '成绩', '签名', '签到时间'] for i in range(6): cjb.write(1, i, a[i]) name = ["iu", "张三", "李四", "王五"] id = ['1111111111', '2020001111', '2020002222', '2020003333'] b = 0 for a in range(2, 6): # 写入学号 cjb.write(a, 1, id[b]) # 写入姓名 cjb.write(a, 2, name[b]) cjb.write(a, 0, b+1) b = b+1 # 保存文件 nwb.save('人脸识别excel.xls')

操作流程:右键运行’生成表格’,可根据自己需求增加name和id个数.

4. 识别签到.py

在这里插入图片描述 在这里插入图片描述

# 导入库 import cv2 import time import xlrd import xlwt from xlutils.copy import copy from datetime import datetime # 创建签名子函数 def sign_in(idx, name): style0 =xlwt.easyxf('font:height 300,bold on,color_index black', num_format_str= 'MM:DD HH:MM') style1 = xlwt.easyxf('font:height 300,bold on,color_index blue', num_format_str ='MM:DD HH:MM') wb = xlrd.open_workbook('人脸识别excel.xls') nwb = copy(wb) nbs=nwb.get_sheet(0) # 签名 nbs.write(idx, 3, name, style1) # 签时间 nbs.write(idx, 4, datetime.now(), style0) nbs.col(4).width=256*20 nwb.save('人脸识别excel.xls') # 加载模型 classfier = cv2.CascadeClassifier('D:\hello_world\pythonProject\haarcascade_frontalface_default.xml') create = cv2.face_LBPHFaceRecognizer.create() create.read('trainer.yml') # 定义变量 font = cv2.FONT_ITALIC starttime = time.time() ID = ('UNKNOW') name = ('UNKNOW') count = 0 # 从表格中获取学号、姓名,与识别结果比对 workbook = xlrd.open_workbook('人脸识别excel.xls') worksheet = workbook.sheet_by_index(0) stu_id = worksheet.col_values(1) stu_name = worksheet.col_values(2) print(stu_id) print(stu_name) # 打开摄像头 capture = cv2.VideoCapture(0) while capture.isOpened(): kk = cv2.waitKey(1) _, farme = capture.read() gray = cv2.cvtColor(farme, cv2.COLOR_BGR2GRAY) faces = classfier.detectMultiScale(gray,1.2,5) if len(faces) != 0: for x, y, w, h in faces: cv2.rectangle(farme, (x,y), (x+w, y+h), (180, 120, 220), 2) gray1 = gray[y:y+h, x:x+w] label, conf = create.predict(gray1) print(label, conf) if conf 30: sign_in(index[0], name) print('学号为:'+str(label)+',姓名为:'+str(name)) break if time.time()-starttime>30: print('超时未识别') break # 关闭所有窗口,释放摄像头 capture.release() cv2.destroyAllWindows()

操作流程:右键运行’识别人脸’,运行成功后,打开人脸识别签到表.xls查看签到信息.

5. 创建图形界面.py

把上述功能做一个GUI界面,集成显示. 在这里插入图片描述

# 导入库 import tkinter as tk import os from PIL import Image, ImageTk #创建采集人脸子函数 def CJRL(): os.system('python 采集人脸.py') #创建训练模型子函数 def XL(): os.system('python 训练模型.py') #创建识别签到子函数 def SBQD(): os.system('python 识别签到.py') #创建签到表 def QDB(): os.startfile('人脸识别excel.xls') #关闭窗口 def GB(): win.destroy() # 创建窗口 win = tk.Tk() win.title('人脸识别签到系统') win.geometry('310x500+800+50') win.configure(bg='#FF8247') # tk.Label(win, text="自动化人脸识别", font=('黑体', 20, 'bold'), bg='#00BFFF', fg='white').place(x=10,y=10) # 设置图片以便使用 img = Image.open('D:\hello_world\pythonProject\cat.jpg') photo = ImageTk.PhotoImage(img) # 大标题 lab1 = tk.Label(win, text="自动化人脸识别", font=('黑体', 20, 'bold'), bg='#00BFFF', fg='white').grid(padx=20, pady=10, sticky=tk.W+tk.E) # 显示图片 # lab2 = tk.Label(win, image=photo).grid(padx=20, pady=10, sticky=tk.W+tk.E) # 按钮 but1 = tk.Button(win, text='采 集 人 脸 图 片', activebackground='yellow',command=CJRL, font=('黑体', 10, 'bold'), bg='#00BFFF', fg='white').grid(padx=20, pady=10, sticky=tk.W+tk.E) but2 = tk.Button(win, text='训 练 模 型',activebackground='yellow', command=XL, font=('黑体', 10, 'bold'), bg='#00BFFF', fg='white').grid(padx=20, pady=10, sticky=tk.W+tk.E) but3 = tk.Button(win, text='识 别 签 到',activebackground='yellow', command=SBQD, font=('黑体', 10, 'bold'), bg='#00BFFF', fg='white').grid(padx=20, pady=10, sticky=tk.W+tk.E) but4 = tk.Button(win, text='签 到 表', activebackground='yellow',command=QDB, font=('黑体', 10, 'bold'), bg='#00BFFF', fg='white').grid(padx=20, pady=10, sticky=tk.W+tk.E) but5 = tk.Button(win, text='关 闭 窗 口',activebackground='yellow', command=GB, font=('黑体', 10, 'bold'), bg='#00BFFF', fg='white').grid(padx=20, pady=10, sticky=tk.W+tk.E) tk.Label(win, text='学号:1111111111 姓名:iu', bg='white', fg='black',font=('楷体',12)).grid(padx=20, pady=10, sticky=tk.W+tk.E) # tk.Label(win, text='字图一体', image=photo ,compound='bottom', bg='white', fg='black',font=('楷体',12)).grid(padx=20, pady=10, sticky=tk.W+tk.E) win.mainloop() 三、相关函数分析 1.采集人脸 classifier = cv2.CascadeClassifier(r'D:\py-project\pythonProject1\haarcascade_frontalface_default.xml') CascadeClassifier:是OpenCV中的一个类,用于创建和管理级联分类器对象,允许加载一个预先训练好的分类器模型.r’D:\pyproject\pythonProject1\haarcascade_frontalface_default.xml’:绝对路径。haarcascade_frontalface_default.xml:该XML文件包含了用于Haar级联分类器的预训练模型,它是基于Haar特征和AdaBoost算法训练得到的,用于检测人脸 faces = classifier.detectMultiScale(gray, 1.2, 5) detectMultiScale() :用于在给定的灰度图像 gray 中检测对象。它会返回一个包含检测到的对象边界框的列表。每个边界框由 (x, y, width, height) 组成,其中 (x, y) 是矩形左上角的坐标,width 和 height 分别是矩形的宽度和高度.gray:这是输入的灰度图像。级联分类器通常在灰度图像上工作,因为颜色信息对于基于Haar特征的分类器不是必需的.1.2:scaleFactor 参数,用于构建图像金字塔。图像金字塔是一系列逐渐缩小的图像,用于在不同的尺度上检测对象。scaleFactor 指定了相邻图像之间的缩放比例。较小的 scaleFactor 值意味着金字塔中的图像尺寸减小得更慢,这有助于在不同尺度上更细致地检测对象。5:这是 minNeighbors 参数,它 指定了在声明找到对象之前,必须在同一个位置重叠检测到的对象的最小数量。较大的 minNeighbors 值可以减少误检,但可能会降低检测的灵敏度。 2.训练模型 create = cv2.face.LBPHFaceRecognizer_create() LBPHFaceRecognizer_create() :OpenCV face 模块中的一个函数,它初始化一个LBPH人脸识别器对象。LBPH是一种基于图像纹理的识别方法,它通过计算局部二值模式的直方图来提取特征,这些特征随后用于人脸的识别.函数返回一个 LBPHFaceRecognizer 对象,这个对象包含了LBPH算法所需的所有参数和模型。与 create.train(faces, labels) 结合使用,其中, faces 和 labels 是已经准备好的训练数据和对应的标签 def data_translate(path): # 初始化用于存储面部图像数据的列表 face_data = [] # 初始化用于存储与面部图像对应的ID的列表(学号) id_data = [] # 使用os.path.join(path, f)将路径和文件名组合成完整的文件路径 # 列表推导式用于创建包含所有文件完整路径的列表 file_list = [os.path.join(path, f) for f in os.listdir(path)] # 遍历file_list中的每个文件路径 for file in file_list: # 打开图像文件,并将其转换为灰度图像'L'模式 PIL_image = Image.open(file).convert('L') # 转换为NumPy数组,数据类型为"uint8" np_image = np.array(PIL_image, "uint8") # 提取文件名中的ID部分,文件名中第一个'.'之后,第二个'.'之前的部分 id = int(file.split('.')[1]) # 将转换后的图像数组添加到face_data列表 face_data.append(np_image) # 将提取的ID添加到id_data列表 id_data.append(id) # 返回包含面部图像数据和对应ID的两个列表 return face_data, id_data 3.识别签到 style0 =xlwt.easyxf('font:height 300,bold on,color_index black', num_format_str= 'MM:DD HH:MM') xlwt.easyxf():函数用于创建一个Excel单元格样式对象,这个对象包含了一系列的格式化设置,可以应用于一个或多个单元格.font:height 300 :设置字体大小为300,这通常对应于Excel中的11号字体.bold on: 表示文本加粗.color_index black :设置文本颜色为黑色。color_index是一个索引,用于指定Excel调色板中的颜色num_format_str= ‘MM:DD HH:MM’:指定日期和时间应该以月-日 时:分的格式显示. for x, y, w, h in faces: # 在图像farme上绘制矩形框,框住检测到的人脸区域 # 参数(x, y)是矩形左上角的坐标,(x+w, y+h)是矩形右下角的坐标(注:坐标系在左上角) # (180, 120, 220)是矩形的颜色(BGR格式),2是线条的粗细 cv2.rectangle(farme, (x, y), (x+w, y+h), (180, 120, 220), 2) # 从灰度图像gray中截取人脸区域,坐标(x, y)是人脸左上角,宽高为w和h gray1 = gray[y:y+h, x:x+w] # 使用人脸识别器create预测截取的人脸区域gray1的身份和置信度,前面create已经read过训练好的yml文件 label, conf = create.predict(gray1) # 打印预测的标签(身份ID)和置信度 print(label, conf) # 如果置信度小于50,认为识别结果比较可信 if conf


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3