本科毕设——基于人脸识别的签到系统的研究

        本人普通四非本科,毕设选了这个比较大众且成熟的选题,四处借鉴后完成了论文,现在写写一些我完成毕设期间的历程。

        在完成论文开题报告后我开始寻求代码以期完成一个简易人脸识别签到系统的设计,开始我用了舍友选修课人工智能的大作业,他所采用的是传统的haar算法,但发现其代码只能用于检测以及识别人脸,不能做到调用摄像头实时识别。于是我又去网上荡了几份代码下来跑(代码已放代码包里——基于haar算法的人脸识别)。

        本人采用的是vscode来实现代码的运行,考虑到vscode的多样性,以后也许其他语言的汇编也可以通用,所以我没有下pycharm。直接在官网下最新的vscode以及搭配最新的anaconda环境,由于都是新版本,所以后续有些报错会与我查阅的文章解决方法不同或不适用了,这给我带来不小的麻烦,具体是哪些我隔了半年我也忘了哈哈哈哈哈,连历史记录都找不到了,只能照着记忆粗略描述,第一次写不够严谨,出现很多问题还请各位大佬多多指正。

        初进vscode各种配置我就不一一介绍了,大体扩展处下个python的扩展包就可以了,然后在第一次运行.py文件时会要你选择编译环境,这个要选好,或者后续摁F1弹出搜索框搜Python:Select Interpreter选择也可。我的理解是相当于一个虚拟编译环境,你不同的项目所用到的模块导入下载后都在各自的环境里,并不通用,打比方你在这个项目刚导入了cv2模块,重开一个项目在另外的编译环境里又得重下,如图。我都选在了在anaconda下集成模块编译,因为同个环境换项目的时候模块导入也不用重新下载。

        要是缺少某个模块报错,如图,根据报错信息到百度搜一下也基本都有解决方案,例如第3行的就是缺少了opencv,可以在base环境下使用pip install opencv-python,本人由于在anaconda的编译环境,所以都是使用conda install安装各种模块,包括下文用到dlib的模型,也是采用conda install -c conda-forge dlib或直接conda install dlib。

         haar作为一款非常经典的算法而言,其优点是可以检测不同尺度的人脸,而且得益于其简单的架构,使其可以在CPU上近乎实时工作。haar算法主要是建立haar级联器,对输入的图像进行灰度化处理,然后调用函数接口来进行人脸识别。上文提到本文一开始的人脸识别是计划基于haar算法实现的,通过实验发现其对于完整的脸部检测效果不错,但其不适用于非正面图像,脸部受到轻微遮挡的情况下近乎起不到作用,同时识别率不高,经常给出许多错误预测,在近亲人脸识别中几乎识别不出两人的区别,经常混淆。如图.yml是是将训练对象的数据保存下来,然后照片则是点击拍照时截取并保存在本地文件夹的。

      

         于是又一次去借鉴了网上各路大佬,物色到了一个基于dlib改进的人脸识别签到系统。dlib曾于2017年2月刷新了LFW人脸数据库的识别榜单,准确率高达0.9938 ± 0.0027。该模型是本系统所用的人脸编码方法,具有27 层的 ResNet网络。它的实质是ResNet-34网络,但却是在这基础上进行了简化,删除了一部分网络层并减少了一半使用的滤波器,使其可以更加高效快速的完成任务。代码如下:

# 主程序
import sys
import cv2
import os
import numpy as np
import uuid  # 生成随机文件名
import dlib
from PIL import Image, ImageDraw, ImageFont
import datetime
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, QLabel

a = 0
b = 0


def name(face_id):  # 创建班级表
    with open('info.csv', 'r+') as f:
        # 使用 with as 操作已经打开的文件对象(本身就是上下文管理器),无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件。
        # r+是open的参数,代表可读可写,若文件不存在就报错
        myInfo = f.readlines()
        namelist = []
        for line in myInfo:
            enty = line.split(',')
# 数据中遇到','就隔开
            namelist.append(enty[0])
        if face_id not in namelist:
            state = "已录入"
            f.writelines(f'\n{face_id},{state}')
        # 如果是新的面孔id,即不在现有面容列表里的(namelist)则显示已录入


def getMax_faces(face_rects):
    if len(face_rects) == 0:
        return 0, 0
    face_areas = []
    for rect in face_rects:
        # 计算每个人脸的面积(高x宽)只录入最大的那个人脸
        area = (rect.bottom() - rect.top()) * (rect.right() - rect.left())
        face_areas.append(area)
    index = np.argmax(face_areas)
    return face_areas[index], face_rects[index]


def gen_face_name(str_face_id):
    # 生成图片文件
    return str_face_id + '_' + str(uuid.uuid4()) + '.jpg'


def ChineseText(img, text, position, textColor=(255, 0, 0), textsize=30):
    if (isinstance(img, np.ndarray)):
        # isinstance(object, classinfo)如果参数object是classinfo的实例,或者object是classinfo类的子类的一个实例, 返回True。如果object不是一个给定类型的的对象, 则返回结果总是False。所以此句判断是否OpenCV图片类型
        # np.array 只是一个便捷的函数,用来创建一个ndarray,它本身不是一个类。ndarray数组,是用 np.ndarray类的对象 表示n维数组对象,所以ndarray是一个类对象,而array是一个方法。
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img)
    # 创建一个可以在给定图像上绘图的对象
    fontSytle = ImageFont.truetype("simsun.ttc", textsize, encoding='utf-8')
    # 字体的格式
    draw.text(position, text, textColor, font=fontSytle)
    # 绘制文本
    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
# 转换回OpenCV格式


# 创建已打卡表
def saveInfo(face_id):  # 创建已打卡表
    with open('sign.csv', 'r+') as f:
        myInfo = f.readlines()
        namelist = []
        for line in myInfo:
            enty = line.split(',')
            namelist.append(enty[0])
        if face_id not in namelist:
            now = datetime.datetime.now()  # 获取当前时间
            dtString = now.strftime("%H:%M:%S")  # 设置时间格式hour,minutes,second
            state = "已签到"
            f.writelines(f'\n{face_id},{dtString},{state}')


def absenteeism():  # 建立缺勤名单
    with open('sign.csv', 'r+') as f:
        myInfo = f.readlines()
        namelist = []
        for line in myInfo:
            enty = line.split(',')
            na
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值