300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 基于 OpenCV + Python 的人脸识别上课签到系统

基于 OpenCV + Python 的人脸识别上课签到系统

时间:2019-11-25 13:04:22

相关推荐

基于 OpenCV + Python 的人脸识别上课签到系统

目录

前言

安装第三方库

第一步:采集人脸图像

(1)修改姓名学号

(2)运行capture_face.py

(3)采集人脸图像

(4)查看采集到的人脸图像

第二步:训练模型

第三步:识别签到

(1)建立签到表

(2)运行sign_in.py,进行签到

(3)查看签到结果

第四步:设计GUI

完整项目的百度网盘链接:/s/1P1UzTyNdcHxfJyFxl-MV-Q?pwd=ni7A,提取码:ni7A

前言

当今社会,科学技术呈现着井喷式的发展情况,新理论的不断提出及新技术的实时应用,给人们的生活带来了日新月异的变化。在这些新技术新应用中,物联网、人工智能、大数据等名词被人们纷纷提起,产业领域的智能化产品层出不穷,其中人脸识别就是一个典型应用。

本项目构建一个基于OpenCV + Python的人脸识别上课签到系统。人脸识别是指将一个需要识别的人脸和人脸库中的某个人脸对应起来(类似于指纹识别),目的是完成识别功能。人脸检测是在一张图片中把人脸定位出来,完成的是搜寻的功能。

OpenCV提供了三种人脸识别方法,分别是LBPH方法、EigenFishfaces方法、Fisherfaces方法。本项目采用LBPH方法,分四步实现。

安装第三方库

首先安装项目用到的第三方库:opencv-python、opencv-contrib-python、pillow、tk、xlrd、xlwt、xlutils

安装方式:在当前python解释器下,pycharm终端运行:

pip install 库名称

第一步:采集人脸图像

capture_face.py

通过调用摄像头进行人脸图像采集,建立人脸图像库

# 第一步:采集人脸图像# 1.导入第三方库import cv2import osimport xlrd# 2.初始化变量font = cv2.FONT_HERSHEY_SIMPLEX # 定义字体,使用opencv中的FONT_HERSHEY_SIMPLEX字体classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 导入人脸检测级联文件。CascadeClassifier是opencv中做人脸检测时的一个级联分类器,对输入的图片进行分类,判断图像内是否有无人脸if not os.path.exists('dataset'): # 判断项目目录中是否存在dataset文件(dataset中存放采集到的人脸图像)os.mkdir('dataset') # 如果没有就新建立dataset文件夹count = 0 # 人脸图像的初始数量# 3.输入学号student_ID = 520542# 4.采集图像capture = cv2.VideoCapture(0) # 打开电脑的内置摄像头while capture.isOpened(): # 当摄像头打开的时候kk = cv2.waitKey(1) # 等待键盘的输入,1:表示延时1ms切换到下一帧图像_, frame = capture.read() # 读取摄像头内容,返回两个参数gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # 将读取到的RGB图像转换为灰度图像faces = classifier.detectMultiScale(gray, 1.3, 5) # 让classifier判断人脸,detectMultiScale函数可以检测出图像中的人脸,其中gray为要检测的灰度图像,1.3为每次图像尺寸减小的比例,5为minNeighborsif len(faces) != 0: # 如果找到人脸# 框选人脸for x, y, w, h in faces:cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 0), 2) # 用矩形框框出人脸,xy为左上角的坐标,w为宽,h为高cv2.putText(frame, 'please "s" to save a picture ', (200, 450), font, 0.8, (0, 255, 255), 2) # 在人脸图像上添加文字,参数依次表示:图像、要添加的文字、文字的位置、字体、字体大小、颜色、粗细if kk == ord('s'): # ord(' ')将字符转化为对应的整数(ASCII码)cv2.imwrite('dataset/caixukun.'+str(student_ID)+'.'+str(count)+'.jpg', gray[y:y+h, x:x+w]) # 保存图像count += 1 # 成功框选人脸后,则样本数增加print('共采集了'+str(count)+'张图片')cv2.putText(frame, 'please "esc" to quit ', (10, 20), font, 0.8, (0, 255, 255), 2) # 在窗口上添加文字,参数依次表示:图像、要添加的文字、文字的位置、字体、字体大小、颜色、粗细cv2.imshow("picture from a cammre", frame) # 打开窗口的名称if kk == 27:print('共采集了' + str(student_ID) + '同学' + str(count) + '张图片')break# 5.退出程序capture.release() # 释放变量cv2.destroyAllWindows() # 检查有无打开窗口,有的话关掉

(1)修改姓名学号

(2)运行capture_face.py

(3)采集人脸图像

按住 "s" 键保存人脸图像,按 "esc" 键关闭摄像头,结束人脸采集

(4)查看采集到的人脸图像

采集到的人脸图像会自动保存在dataset文件夹中

第二步:训练模型

使用OpenCV中LBPH(Local Binary Patterns Histograms,局部二进制编码)算法建立人脸数据模型,对人脸图像库中的人脸图像提取特征信息(LBPH),并训练成模型,存储起来形成特征库。

# 第二步:训练模型# 1. 导入第三方库import cv2import osfrom PIL import Imageimport numpy as np# 2. 加载特征提取模型recognizer_create = cv2.face_LBPHFaceRecognizer.create()# 3. 数据处理def data_translate(path):face_data = []id_data = []file_list = [os.path.join(path, f) for f in os.listdir(path)]# print(file_list)for file in file_list:PIL_image = Image.open(file).convert("L")np_image = np.array(PIL_image, 'uint8')image_id = int(file.split('.')[1])# print(image_id)face_data.append(np_image)id_data.append(image_id)return face_data, id_data# 4. 训练模型Face, ID = data_translate('dataset')recognizer_create.train(Face, np.array(ID))print('训练完成')# 5. 保存模型recognizer_create.save('face_model.yml')print('模型已保存')

运行train.py,开始训练模型,训练完成后会生成face_model.yml 文件,face_model.yml 就是训练好的人脸模型

第三步:识别签到

开启摄像头实时跟踪人脸,获取人脸特征信息,然后将获取的人脸特征信息与第二步建立的特征库进行比对,将识别的信息在画面中呈现,并记录在Excel文档中。

(1)建立签到表

打开excel,新建文件,按如下的格式新建一个签到表

注意:

1. 建立签到表的时候,一定要将单元格格式设置成文本,这就是为什么大家老是签到不成功的原因

2. 保存签到表时,保存位置为当前项目的目录文件夹,文件命名为 “签到表” 保存类型一定要选择.xls格式

(2)运行sign_in.py,进行签到

# 第三步:识别签到# 1. 导入第三方库import xlrd, xlwtfrom xlutils.copy import copyfrom datetime import datetimeimport cv2import time# 2. 在考勤表签字def sign_name(idx, name):style0 = xlwt.easyxf('font:height 240,bOld on,color_index red', num_format_str='DD:MM HH:MM') # 样式0style1 = xlwt.easyxf('font:height 240,bOld on,color_index blue') # 样式1workbook = xlrd.open_workbook('签到表.xls') # 读取excel文件newbook = copy(workbook) # 复制文件newsheet = newbook.get_sheet(0) # 在源文件上追加newsheet.write(idx, 4, datetime.now(), style0) # 第idx行,第4列,写入签到时间,样式为style0(注:代码中的行列是从0开始的)newsheet.write(idx, 3, name, style1) # 第idx行,第3列,写入签到学生的名字,样式为style1((注:代码中的行列是从0开始的))# 设置列宽newsheet.col(0).width = 256 * 6 # 第0列的列宽为 256 * 6 (256为衡量单位,6表示6个字符宽度)newsheet.col(1).width = 256 * 12 # 第1列的列宽为 256 * 12 (256为衡量单位,12表示12个字符宽度)newsheet.col(2).width = 256 * 10 # 第2列的列宽为 256 * 10 (256为衡量单位,10表示10个字符宽度)newsheet.col(3).width = 256 * 12 # 第3列的列宽为 256 * 12 (256为衡量单位,12表示12个字符宽度)newsheet.col(4).width = 256 * 15 # 第4列的列宽为 256 * 15 (256为衡量单位,15表示15个字符宽度)newbook.save('签到表1.xls')# 3. 导入模块,初始化变量classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')recognizer_create = cv2.face.LBPHFaceRecognizer.create()recognizer_create.read('face_model.yml') # 读取训练好的模型flag = 0 # 标记次数start_time = time.time() # 系统时间提取duration = 25 # 持续时间ID = 'Unkonw'font = cv2.FONT_HERSHEY_SIMPLEX # 定义字体,使用opencv中的FONT_HERSHEY_SIMPLEX字体# 4. 导入应到学生名单workbook = xlrd.open_workbook('签到表.xls') # 导入考勤记录表worksheet = workbook.sheet_by_index(0) # 打开工作表stu_num = worksheet.col_values(1) # 提取工作表第1列,第1列为学生学号stu_name = worksheet.col_values(2) # 提取工作表第2列,第2列为学生名字# 5.识别签到capture = cv2.VideoCapture(0) # 打开摄像头while capture.isOpened(): # 当打开摄像头的时候kk = cv2.waitKey(1) # 等待键盘的输入_, frame = capture.read() # 读取摄像头内容gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # 将读取到的RGB图像转换为灰度图像faces = classifier.detectMultiScale(gray, 1.3, 5) # 让classifier判断人脸,detectMultiScale函数可以检测出图像中的人脸if len(faces) != 0: # 如果能找到人脸# 框选人脸for x, y, w, h in faces:cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2) # 用矩形框框出人脸,xy为左上角的坐标,w为宽,h为高roi_face = gray[y:y + h, x:x + w]label, conf = recognizer_create.predict(roi_face) # 预测出的学号和可信度# print(label,conf)if conf < 60:index = [list for list, i in enumerate(stu_num) if i == str(label)] # 得到预测学号在excel表格中所在的行数(注:index的值是从0开始的,index=3表示在excel表格中的第4行)# print(index)if index != []:name = stu_name[index[0]]ID = stu_name[index[0]]flag += 1else:ID = 'unknow'cv2.putText(frame, str(ID), (x, y-10), font, 0.8, (0, 0, 255), 2) # 添加字幕cv2.putText(frame, 'please "esc" to quit ', (10, 20), font, 0.8, (0, 255, 255), 2) # 在窗口上添加文字,参数依次表示:图像、要添加的文字、文字的位置、字体、字体大小、颜色、粗细cv2.imshow("picture from a cammre", frame) # 打开窗口的名称if flag > 5:sign_name(index[0], name)print('签到成功')breakif time.time()-start_time > duration: # 如果超时,则签到失败print('签到失败!')breakif kk == 27: # 如果退出print('程序被终止,请重新签到!')break# 6.退出程序capture.release() # 释放变量cv2.destroyAllWindows() # 检查有无打开窗口,有的话关掉

(3)查看签到结果

签到成功后项目目录生成 “签到表1.xls” 文件,双击打开即可查看签到结果

第四步:设计GUI

运行GUI.py,查看用户界面

# 第四步:设计GUI# 1. 导入第三方库import osimport tkinter as tk# 2. 创建屏幕窗口windows = tk.Tk() # 创建windows的窗口windows.title('<计算机视觉>课程案例') # 窗口名称windows.geometry('310x500+1000+100') # 窗口大小(注:x是小写字母x,不能写乘号)# 3. 定义功能函数def function1():os.system('python capture_face.py') # 执行python capture_face.py命令def function2():os.system('python train.py') # 执行python train.py命令def function3():os.system('python sign_in.py') # 执行python sign_in.py命令def function4():os.startfile(os.getcwd()+'/签到表1.xls') # 打开'签到表1.xls'文件def function5():os.startfile(os.getcwd()+'/基于OpenCV的人脸识别说明文档.docx') # 打开说明文档def function6():windows.destroy()# 4. 创建标签及按钮tk.Label(windows, text='人脸识别上课签到系统', font=('黑体', 20, 'bold'), fg='white',bg='maroon', height=2).grid(padx=7, pady=5)tk.Button(windows,text='采 集 人 脸 图 像', font=('黑体', 20, 'bold'), fg='white',bg='#0D47A1', command=function1).grid(padx=7, pady=5, sticky=tk.W+tk.E)tk.Button(windows,text='训 练 模 型', font=('黑体', 20, 'bold'), fg='white',bg='#0D47A1', command=function2).grid(padx=7, pady=5, sticky=tk.W+tk.E)tk.Button(windows,text='识 别 签 到', font=('黑体', 20, 'bold'), fg='white',bg='#0D47A1', command=function3).grid(padx=7, pady=5, sticky=tk.W+tk.E)tk.Button(windows,text='查 看 签 到 表', font=('黑体', 20, 'bold'), fg='white',bg='#0D47A1', command=function4).grid(padx=7, pady=5, sticky=tk.W+tk.E)tk.Button(windows,text='查看项目说明文档', font=('黑体', 20, 'bold'), fg='white',bg='#0D47A1', command=function5).grid(padx=7, pady=5, sticky=tk.W+tk.E)tk.Button(windows,text=' 退出 ', font=('黑体', 20, 'bold'), fg='white',bg='#0D47A1', command=function6).grid(padx=7, pady=5, sticky=tk.W+tk.E)tk.Button(windows,text='学号:520542 姓名:蔡徐坤', font=('仿宋', 20, 'bold'), fg='black',bg='white').grid(padx=20, pady=50, sticky=tk.W+tk.E)# 5. 运行windows.mainloop()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。