草庐IT

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

呆梨小蔡姬 2023-04-08 原文

目录

前言

安装第三方库

第一步:采集人脸图像

(1)修改姓名学号

(2)运行capture_face.py 

(3)采集人脸图像 

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

第二步:训练模型

第三步:识别签到

(1)建立签到表

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

(3)查看签到结果

第四步:设计GUI

完整项目的百度网盘链接:https://pan.baidu.com/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 cv2
import os
import 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 = 2021520542

# 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为minNeighbors
    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为高
            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 cv2
import os
from PIL import Image
import 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, xlwt
from xlutils.copy import copy
from datetime import datetime
import cv2
import 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')  # 样式0
    style1 = xlwt.easyxf('font:height 240,bOld on,color_index blue')  # 样式1
    workbook = 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 += 1
                else:
                    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('签到成功')
        break
    if time.time()-start_time > duration:  # 如果超时,则签到失败
        print('签到失败!')
        break
    if kk == 27:  # 如果退出
        print('程序被终止,请重新签到!')
        break

# 6.退出程序
capture.release()  # 释放变量
cv2.destroyAllWindows()  # 检查有无打开窗口,有的话关掉

(3)查看签到结果

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

 

第四步:设计GUI

 

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

# 第四步:设计GUI

# 1. 导入第三方库
import os
import 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='学号:2021520542   姓名:蔡徐坤', font=('仿宋', 20, 'bold'), fg='black',
         bg='white').grid(padx=20, pady=50, sticky=tk.W+tk.E)

# 5. 运行
windows.mainloop()

 

有关基于 OpenCV + Python 的人脸识别上课签到系统的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  3. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  4. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  5. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  6. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  7. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  10. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

随机推荐