毕业设计:基于python人脸识别考勤系统 签到系统 深度学习 Flask框架 Dlib库 MySQL数据库 大数据(源码+论文)✅

毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏)

毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅

1、项目介绍

技术栈:
Python语言、MySQL数据库、Flask框架、Echarts可视化、Dlib库、刷脸签到、多角色登录

课堂考勤签到是教育教学中的重要环节,可以实现学生出勤情况的管理,同时也是学生学习过程中的重要参考。传统的课堂签到方式存在着效率低、易产生作弊等问题。因此,基于人脸识别技术的课堂签到系统应运而生,其可以实现自动化签到,提高签到效率,同时也能减少作弊现象的发生。本文将介绍一种基于Flask框架开发的课堂人脸签到系统。
该系统主要分为前端和后端两个部分,前端负责人脸采集、人脸识别以及签到信息的展示,后

2、项目界面

(1)管理员端界面

在这里插入图片描述

(2)摄像头人脸识别考勤签到界面

在这里插入图片描述

(3)课程考勤情况

在这里插入图片描述

(4)学生考勤权限设置

在这里插入图片描述

(5)学生信息

在这里插入图片描述

(6)系统登录界面

在这里插入图片描述

(7)学生端界面

在这里插入图片描述

(8)教师端界面

在这里插入图片描述

3、项目说明

课堂考勤签到是教育教学中的重要环节,可以实现学生出勤情况的管理,同时也是学生学习过程中的重要参考。传统的课堂签到方式存在着效率低、易产生作弊等问题。因此,基于人脸识别技术的课堂签到系统应运而生,其可以实现自动化签到,提高签到效率,同时也能减少作弊现象的发生。本文将介绍一种基于Flask框架开发的课堂人脸签到系统。
该系统主要分为前端和后端两个部分,前端负责人脸采集、人脸识别以及签到信息的展示,后端则负责存储学生信息和签到记录,并进行相关的逻辑处理。
系统的前端采用HTML、CSS和JavaScript等技术进行开发,主要包括人脸采集页面、签到页面和签到记录页面。人脸采集页面提供了学生人脸的采集功能,签到页面则用于展示学生签到状态,签到记录页面用于展示历史签到记录。在人脸采集和签到页面中,系统使用了摄像头进行拍摄,并利用OpenCV库进行人脸识别。
系统的后端采用了Python语言和Flask框架进行开发。后端主要包括学生信息管理模块、签到记录管理模块和人脸识别模块。在学生信息管理模块中,系统管理员可以对学生信息进行增删改查操作。签到记录管理模块则用于存储学生签到记录,并提供了签到统计和查询功能。人脸识别模块则是整个系统的核心,其利用已经训练好的人脸识别模型进行签到信息的验证和识别。
总体来说,该系统可以提高课堂签到效率,降低作弊率,同时也能够减轻教师的工作负担。未来,可以考虑引入更多的功能和技术,如人脸特征提取、人脸活体检测等,进一步提升系统的精度和安全性。

关键字:人脸识别;人脸考勤;python;flask;opencv;Dlib;

4、核心代码


from flask import Blueprint, render_template, redirect, request, Response, session, flash, jsonify, url_for

import app
from app import db
from .models import Teacher, Faces, Course, SC, Attendance, Time_id, Student
from sqlalchemy.sql import exists
import base64
import os
from app import get_faces_from_camera as gf
from datetime import timedelta
import cv2
import pandas as pd
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import dlib
import time
import pandas as pd
import xlsxwriter
import xlwt
from io import BytesIO
from urllib.parse import quote
from flask import send_file
from sqlalchemy import create_engine

teacher = Blueprint('teacher', __name__, static_folder="static")
# 本次签到的所有人员信息
attend_records = []
# 本次签到的开启时间
the_now_time = ''


@teacher.route('/home')
def home():
    flag = session['id'][0]
    print(flag)
    courses = {}
    course = db.session.query(Course).filter(Course.t_id == session['id']).all()
    for c in course:
        num = db.session.query(SC).filter(SC.c_id == c.c_id).count()
        courses[c] = num
    return render_template('teacher/teacher_home.html', before=session['time'], flag=flag, name=session['name'],
                           courses=courses)


# Dlib 正向人脸检测器
detector = dlib.get_frontal_face_detector()
# Dlib 人脸 landmark 特征点检测器
predictor = dlib.shape_predictor('app/static/data_dlib/shape_predictor_68_face_landmarks.dat')

# Dlib Resnet 人脸识别模型,提取 128D 的特征矢量
face_reco_model = dlib.face_recognition_model_v1("app/static/data_dlib/dlib_face_recognition_resnet_model_v1.dat")

#人脸识别类
class VideoCamera(object):
    def __init__(self):
        self.font = cv2.FONT_ITALIC
        # 通过opencv获取实时视频流
        self.video = cv2.VideoCapture(0)

        # 统计 FPS
        self.frame_time = 0
        self.frame_start_time = 0
        self.fps = 0

        # 统计帧数
        self.frame_cnt = 0

        # 用来存储所有录入人脸特征的数组
        self.features_known_list = []
        # 用来存储录入人脸名字
        self.name_known_list = []

        # 用来存储上一帧和当前帧 ROI 的质心坐标
        self.last_frame_centroid_list = []
        self.current_frame_centroid_list = []

        # 用来存储当前帧检测出目标的名字
        self.current_frame_name_list = []

        # 上一帧和当前帧中人脸数的计数器
        self.last_frame_faces_cnt = 0
        self.current_frame_face_cnt = 0

        # 用来存放进行识别时候对比的欧氏距离
        self.current_frame_face_X_e_distance_list = []

        # 存储当前摄像头中捕获到的所有人脸的坐标名字
        self.current_frame_face_position_list = []
        # 存储当前摄像头中捕获到的人脸特征
        self.current_frame_face_feature_list = []

        # 控制再识别的后续帧数
        # 如果识别出 "unknown" 的脸, 将在 reclassify_interval_cnt 计数到 reclassify_interval 后, 对于人脸进行重新识别
        self.reclassify_interval_cnt = 0
        self.reclassify_interval = 10

    def __del__(self):
        self.video.release()

        # 从 "features_all.csv" 读取录入人脸特征 / Get known faces from "features_all.csv"

    def get_face_database(self, cid):
        # print(cid)
        # course_sid = SC.query.filter(SC.c_id==cid).all()
        # all_sid = []
        # for sc in course_sid:
        #     all_sid.append(sc.s_id)
        # from_db_all_features = Faces.query.filter(Faces.s_id.in_(all_sid)).all()
        from_db_all_features = Faces.query.all()
        if from_db_all_features:
            for from_db_one_features in from_db_all_features:
                someone_feature_str = str(from_db_one_features.feature).split(',')
                self.name_known_list.append(from_db_one_features.s_id)
                features_someone_arr = []
                for one_feature in someone_feature_str:
                    if one_feature == '':
                        features_someone_arr.append('0')
                    else:
                        features_someone_arr.append(float(one_feature))
                self.features_known_list.append(features_someone_arr)
            # print("Faces in Database:", len(self.features_known_list))
            return 1
        else:
            # print('##### Warning #####', '\n')
            # print("'features' is empty")
            # print('##### End Warning #####')
            return 0

        # 更新 FPS / Update FPS of video stream

    def update_fps(self):
        now = time.time()
        self.frame_time = now - self.frame_start_time
        self.fps = 1.0 / self.frame_time
        self.frame_start_time = now

    # 计算两个128D向量间的欧式距离
    @staticmethod
    def return_euclidean_distance(feature_1, feature_2):
        feature_1 = np.array(feature_1)
        feature_2 = np.array(feature_2)
        dist = np.sqrt(np.sum(np.square(feature_1 - feature_2)))
        return dist

    # 生成的 cv2 window 上面添加说明文字 / putText on cv2 window
    def draw_note(self, img_rd):
        # 添加说明 (Add some statements
        cv2.putText(img_rd, "One person at a time:  ", (20, 40), self.font, 1, (255, 255, 255), 1,
                    cv2.LINE_AA)
        cv2.putText(img_rd, "FPS:   " + str(self.fps.__round__(2)), (20, 100), self.font, 0.8, (0, 255, 0), 1,
                    cv2.LINE_AA)
        # cv2.putText(img_rd, "Q: Quit", (20, 450), self.font, 0.8, (255, 255, 255), 1, cv2.LINE_AA)

    def draw_name(self, img_rd):
        # 在人脸框下面写人脸名字
        # print(self.current_frame_name_list)
        font = ImageFont.truetype("simsun.ttc", 30)
        img = Image.fromarray(cv2.cvtColor(img_rd, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img)
        draw.text(xy=self.current_frame_face_position_list[0], text=self.current_frame_name_list[0], font=font)
        img_rd = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
        return img_rd

        # 处理获取的视频流,进行人脸识别
        #进行人脸识别的方法
    def get_frame(self, cid):
        stream = self.video
        # 1. 读取存放所有人脸特征的 csv / Get faces known from "features.all.csv"

        #从数据库中获取Cid(studentid) 拿到人脸特征
        if self.get_face_database(cid):
            while stream.isOpened():
                self.frame_cnt += 1
                # print(">>> Frame " + str(self.frame_cnt) + " starts")
                flag, img_rd = stream.read()

                # 2. 检测人脸 / Detect faces for frame X
                faces = detector(img_rd, 0) #人脸特征数组

                # 3. 更新帧中的人脸数 / Update cnt for faces in frames
                self.last_frame_faces_cnt = self.current_frame_face_cnt
                self.current_frame_face_cnt = len(faces)
                filename = 'attendacnce.txt'
                with open(filename, 'a') as file:
                    # 4.1 当前帧和上一帧相比没有发生人脸数变化 / If cnt not changes, 1->1 or 0->0
                    if self.current_frame_face_cnt == self.last_frame_faces_cnt:
                        # print("   >>> scene 1: 当前帧和上一帧相比没有发生人脸数变化 / No face cnt changes in this frame!!!")
                        if "unknown" in self.current_frame_name_list:
                            # print("   >>> 有未知人脸, 开始进行 reclassify_interval_cnt 计数")
                            self.reclassify_interval_cnt += 1

                        # 4.1.1 当前帧一张人脸 / One face in this frame
                        if self.current_frame_face_cnt == 1:
                            if self.reclassify_interval_cnt == self.reclassify_interval:
                                # print("   >>> scene 1.1 需要对于当前帧重新进行人脸识别 / Re-classify for current frame")

                                self.reclassify_interval_cnt = 0
                                self.current_frame_face_feature_list = []
                                self.current_frame_face_X_e_distance_list = []
                                self.current_frame_name_list = []

                                for i in range(len(faces)):
                                    shape = predictor(img_rd, faces[i])
                                    self.current_frame_face_feature_list.append(
                                        face_reco_model.compute_face_descriptor(img_rd, shape))

                                # a. 遍历捕获到的图像中所有的人脸 / Traversal all the faces in the database
                                for k in range(len(faces)):
                                    self.current_frame_name_list.append("unknown")

                                    # b. 每个捕获人脸的名字坐标 / Positions of faces captured
                                    self.current_frame_face_position_list.append(tuple(
                                        [faces[k].left(),
                                         int(faces[k].bottom() + (faces[k].bottom() - faces[k].top()) / 4)]))

                                    # c. 对于某张人脸,遍历所有存储的人脸特征 / For every face detected, compare it with all the faces in the database
                                    for i in range(len(self.features_known_list)):
                                        # 如果 person_X 数据不为空 / If the data of person_X is not empty
                                        if str(self.features_known_list[i][0]) != '0.0':
                                            # print("            >>> with person", str(i + 1), "the e distance: ", end='')
                                            e_distance_tmp = self.return_euclidean_distance(
                                                self.current_frame_face_feature_list[k],
                                                self.features_known_list[i])
                                            # print(e_distance_tmp)
                                            self.current_frame_face_X_e_distance_list.append(e_distance_tmp)
                                        else:
                                            # 空数据 person_X / For empty data
                                            self.current_frame_face_X_e_distance_list.append(999999999)
                                    # print("            >>> current_frame_face_X_e_distance_list:",
                                    #       self.current_frame_face_X_e_distance_list)

                                    # d. 寻找出最小的欧式距离匹配 / Find the one with minimum e distance
                                    similar_person_num = self.current_frame_face_X_e_distance_list.index(
                                        min(self.current_frame_face_X_e_distance_list))
                                    # print("   >>> Minimum e distance with ", self.name_known_list[similar_person_num],
                                    #      ": ",
                                    #      min(self.current_frame_face_X_e_distance_list))


                                    if min(self.current_frame_face_X_e_distance_list) < 0.4:
                                        # 在这里更改显示的人名
                                        # self.show_chinese_name()
                                        self.current_frame_name_list[k] = self.name_known_list[similar_person_num]
                                        # print("            >>> recognition result for face " + str(k + 1) + ": " +
                                        #       self.name_known_list[similar_person_num])
                                        now = time.strftime("%Y-%m-%d %H:%M", time.localtime())
                                        mm = self.name_known_list[similar_person_num] + '  ' + now + '  已签到\n'
                                        file.write(self.name_known_list[similar_person_num] + '  ' + now + '     已签到\n')
                                        attend_records.append(mm)
                                        # session['attend'].append(mm)
                                    else:
                                        pass
                                    # print(
                                    #    "            >>> recognition result for face " + str(
                                    #        k + 1) + ": " + "unknown")
                            else:
                                # print("   >>> scene 1.2 不需要对于当前帧重新进行人脸识别 / No re-classification for current frame")
                                # 获取特征框坐标 / Get ROI positions
                                for k, d in enumerate(faces):
                                    # 计算矩形框大小 / Compute the shape of ROI
                                    height = (d.bottom() - d.top())
                                    width = (d.right() - d.left())
                                    hh = int(height / 2)
                                    ww = int(width / 2)

                                    cv2.rectangle(img_rd,
                                                  tuple([d.left() - ww, d.top() - hh]),
                                                  tuple([d.right() + ww, d.bottom() + hh]),
                                                  (255, 255, 255), 2)

                                    self.current_frame_face_position_list[k] = tuple(
                                        [faces[k].left(),
                                         int(faces[k].bottom() + (faces[k].bottom() - faces[k].top()) / 4)])

                                    # print("   >>> self.current_frame_name_list:              ",
                                    #       self.current_frame_name_list[k])
                                    # print("   >>> self.current_frame_face_position_list:     ",
                                    #       self.current_frame_face_position_list[k])

                                    img_rd = self.draw_name(img_rd)

                    # 4.2 当前帧和上一帧相比发生人脸数变化
                    else:
                        # print("   >>> scene 2: 当前帧和上一帧相比人脸数发生变化 / Faces cnt changes in this frame")
                        self.current_frame_face_position_list = []
                        self.current_frame_face_X_e_distance_list = []
                        self.current_frame_face_feature_list = []

                        # 4.2.1 人脸数从 0->1 / Face cnt 0->1
                        if self.current_frame_face_cnt == 1:
                            # print("   >>> scene 2.1 出现人脸,进行人脸识别
                            self.current_frame_name_list = []

                            for i in range(len(faces)):
                                shape = predictor(img_rd, faces[i])
                                self.current_frame_face_feature_list.append(
                                    face_reco_model.compute_face_descriptor(img_rd, shape))

                            # a. 遍历捕获到的图像中所有的人脸
                            for k in range(len(faces)):
                                self.current_frame_name_list.append("unknown")

                                # b. 每个捕获人脸的名字坐标
                                self.current_frame_face_position_list.append(tuple(
                                    [faces[k].left(),
                                     int(faces[k].bottom() + (faces[k].bottom() - faces[k].top()) / 4)]))

                                # c. 对于某张人脸,遍历所有存储的人脸特征
                                # print(len(self.features_known_list))
                                for i in range(len(self.features_known_list)):
                                    # 如果 person_X 数据不为空 / If data of person_X is not empty
                                    if str(self.features_known_list[i][0]) != '0.0':
                                        #  print("            >>> with person", str(i + 1), "the e distance: ", end='')
                                        e_distance_tmp = self.return_euclidean_distance(
                                            self.current_frame_face_feature_list[k],
                                            self.features_known_list[i])
                                        # print(e_distance_tmp)
                                        self.current_frame_face_X_e_distance_list.append(e_distance_tmp)
                                    else:
                                        # 空数据 person_X
                                        self.current_frame_face_X_e_distance_list.append(999999999)

                                # d. 寻找出最小的欧式距离匹配
                                similar_person_num = self.current_frame_face_X_e_distance_list.index(
                                    min(self.current_frame_face_X_e_distance_list))

                                if min(self.current_frame_face_X_e_distance_list) < 0.4:
                                    # 在这里更改显示的人名
                                    # self.show_chinese_name()
                                    self.current_frame_name_list[k] = self.name_known_list[similar_person_num]
                                    # print("            >>> recognition result for face " + str(k + 1) + ": " +
                                    #     self.name_known_list[similar_person_num])
                                    now = time.strftime("%Y-%m-%d %H:%M", time.localtime())
                                    mm = self.name_known_list[similar_person_num] + '  ' + now + '  已签到\n'
                                    file.write(self.name_known_list[similar_person_num] + '  ' + now + '  已签到\n')
                                    # session['attend'].append(mm)
                                    attend_records.append(mm)
                                else:
                                    pass
                                # print(
                                #    "            >>> recognition result for face " + str(k + 1) + ": " + "unknown")

                            if "unknown" in self.current_frame_name_list:
                                self.reclassify_interval_cnt += 1

                        # 4.2.1 人脸数从 1->0 / Face cnt 1->0
                        elif self.current_frame_face_cnt == 0:
                            # print("   >>> scene 2.2 人脸消失, 当前帧中没有人脸 / No face in this frame!!!")

                            self.reclassify_interval_cnt = 0
                            self.current_frame_name_list = []
                            self.current_frame_face_feature_list = []

                # 5. 生成的窗口添加说明文字 / Add note on cv2 window
                self.draw_note(img_rd)

                self.update_fps()

                # cv2.namedWindow("camera", 1)
                # cv2.imshow("camera", img_rd)
                # print(">>> Frame ends\n\n")
                ret, jpeg = cv2.imencode('.jpg', img_rd)
                return jpeg.tobytes()



5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅

感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻

  • 31
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 本系统的目标是实现基于人脸识别考勤打卡。为了实现这个目标,我们使用了Python语言下的OpenCV、FlaskMySQL这些工具。 首先,我们选择使用OpenCV作为人脸识别。OpenCV是一个开的计算机视觉,提供了丰富的图像处理和模式识别功能。通过OpenCV,我们可以进行人脸检测、人脸识别以及人脸特征提取等操作,从而实现对员工进行考勤的功能。 其次,为了实现系统的服务器端功能和Web接口,我们选择使用了Flask框架Flask是一个轻量级的Python Web框架,提供了简单而灵活的工具和,用于构建Web应用程序。通过Flask,我们可以实现用户注册、登录、人脸数据的录入和识别等功能,同时提供友好的Web界面给用户使用。 此外,为了存储员工的信息和考勤记录,我们选择使用了MySQL数据库MySQL是一个关系型数据库管理系统,通过使用SQL语言,我们可以轻松地维护员工信息和考勤记录的存储、查询和更新。 综上所述,我们利用Python下的OpenCV进行人脸识别,使用Flask框架构建服务器端和Web接口,以及借助MySQL数据库存储员工信息和考勤记录。通过这些工具的协作,我们可以实现基于人脸识别考勤打卡系统,提高考勤管理的效率和准确性。 ### 回答2: 本系统使用Python下的OpenCV、FlaskMySQL来实现基于人脸识别考勤打卡功能。 首先,我们使用OpenCV人脸进行识别和检测。通过调用OpenCV的人脸检测算法,我们可以从图像或视频中确定人脸的位置。然后,我们可以从检测到的人脸中提取关键特征,如眼睛、鼻子和嘴巴的位置。 接下来,我们使用Flask框架来构建一个Web应用程序。Flask可以帮助我们创建一个基于Python的轻量级Web服务器,并提供路由、处理前端请求和返回响应的功能。我们可以创建一个打卡页面,让用户上传自己的照片进行人脸识别Flask还可以与前端页面进行交互,将识别结果返回给用户。 为了存储打卡记录以及用户信息,我们使用MySQL数据库。我们可以创建一个数据库表来存储用户的信息,例如姓名、照片和打卡时间。当用户上传照片进行打卡时,我们可以将其与数据库中的人脸数据进行匹配,并将打卡记录存入数据库中。 总结来说,通过使用Python下的OpenCV、FlaskMySQL,我们可以构建一个基于人脸识别考勤打卡系统。用户可以通过上传照片,系统识别人脸并与数据库中的人脸数据进行匹配,最后将考勤记录存档。这样的系统可以提高考勤的准确性和效率,并且可以方便地存储和管理考勤数据。 ### 回答3: 本系统要实现基于人脸识别考勤打卡,所以我们选择使用Python下的OpenCV、Flask以及MySQL数据库来完成。 首先,我们使用OpenCV进行人脸识别。OpenCV是一个强大的计算机视觉,它提供了大量的图像处理和人脸识别的功能。通过使用OpenCV,我们可以对员工的人脸进行识别和比对,以确保打卡的准确性和可靠性。 其次,我们使用Flask框架来搭建系统的后端。Flask是一个轻量级的Python Web框架,它可以帮助我们快速搭建起一个可扩展的Web应用程序。我们可以使用Flask来处理前端页面的请求、以及与数据库的交互等。 最后,为了保存员工的考勤信息以及人脸数据,我们选择使用MySQL数据库MySQL是一个常用的关系型数据库管理系统,它可以帮助我们有效地存储和管理大量的数据。通过使用MySQL,我们可以将员工的考勤记录、人脸特征等信息进行存储和管理,以便后续的查询和分析。 综上所述,通过使用Python下的OpenCV、Flask以及MySQL数据库,我们可以很好地实现基于人脸识别考勤打卡系统。这个系统可以准确地识别员工的人脸,记录员工的考勤信息,并提供可靠的存储和查询功能,帮助企业实现便捷高效的考勤管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值