挑战杯 基于深度学习的人脸专注度检测计算系统 - opencv python cnn

news2024/10/5 17:27:41

文章目录

  • 1 前言
  • 2 相关技术
    • 2.1CNN简介
    • 2.2 人脸识别算法
    • 2.3专注检测原理
    • 2.4 OpenCV
  • 3 功能介绍
    • 3.1人脸录入功能
    • 3.2 人脸识别
    • 3.3 人脸专注度检测
    • 3.4 识别记录
  • 4 最后

1 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 基于深度学习的人脸专注度检测计算算法

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:5分

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

2 相关技术

2.1CNN简介

卷积神经网络(CNN),是由多层卷积结构组成的一种神经网络。卷积结构可以减少网络的内存占用、参数和模型的过拟合。卷积神经网络是一种典型的深度学习算法。广泛应用于视觉处理和人工智能领域,特别是在图像识别和人脸识别领域。与完全连接的神经网络相比,CNN输入是通过交换参数和局部感知来提取图像特征的图像。卷积神经网络是由输入层、卷积层、池化层、全连接层和输出层五层结构组成。其具体模型如下图所示。
在这里插入图片描述

(1)输入层(Input
layer):输入层就是神经网络的输入端口,就是把输入传入的入口。通常传入的图像的R,G,B三个通道的数据。数据的输入一般是多维的矩阵向量,其中矩阵中的数值代表的是图像对应位置的像素点的值。

(2)卷积层(Convolution layer):卷积层在CNN中主要具有学习功能,它主要提取输入的数据的特征值。

(3)池化层(Pooling
layer):池化层通过对卷积层的特征值进行压缩来获得自己的特征值,减小特征值的矩阵的维度,减小网络计算量,加速收敛速度可以有效避免过拟合问题。

(4)全连接层(Full connected
layer):全连接层主要实现是把经过卷积层和池化层处理的数据进行集合在一起,形成一个或者多个的全连接层,该层在CNN的功能主要是实现高阶推理计算。

(5)输出层(Output layer):输出层在全连接层之后,是整个神经网络的输出端口即把处理分析后的数据进行输出。

2.2 人脸识别算法

利用dlib实现人脸68个关键点检测并标注,关键代码



    import cv2
    
    # 加载人脸识别模型
    face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat'
    facerec = dlib.face_recognition_model_v1(face_rec_model_path)
    # 加载特征点识别模型
    predictor_path = "shape_predictor_5_face_landmarks.dat"
    predictor = dlib.shape_predictor(predictor_path)
    
    # 读取图片
    img_path = "step1/image/face.jpg"
    img = cv2.imread(img_path)
    # 转换为灰阶图片
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 正向人脸检测器将图像
    detector = dlib.get_frontal_face_detector()


    # 使用人脸识别模型来检测图像中的人脸
    faces = detector(gray, 1)
    # 使用特征点识别模型来检测人脸中的特征
    for i, face in enumerate(faces):
        # 获取人脸特征点
        shape = predictor(img, face)

2.3专注检测原理

总体流程

主要通过电脑摄像头去实时的抓拍学生当前的状态和行为,不间断的采集学生上课时的面部表情和眼睛注视的方向,利用CNN提取相应的特征数据并进行分析处理,若对应输出的判断值大于设置的阈值时,则认为学生在走神没有认真学习。并且对拍摄时间进行计时,在界面上实时输出该学生在课堂上的有效学习时间和学生在课堂上专注时间的比例并进行存入表格中。

在这里插入图片描述

眼睛检测算法

基于dlib人脸识别68特征点检测、分别获取左右眼面部标志的索引,通过opencv对视频流进行灰度化处理,检测出人眼的位置信息。人脸特征点检测用到了dlib,dlib有两个关键函数:dlib.get_frontal_face_detector()和dlib.shape_predictor(predictor_path)。

前者是内置的人脸检测算法,使用HOG pyramid,检测人脸区域的界限(bounds)。
后者是用来检测一个区域内的特征点,并输出这些特征点的坐标,它需要一个预先训练好的模型(通过文件路径的方法传入),才能正常工作。
使用开源模型shape_predictor_68_face_landmarks.dat,可以得到68个特征点位置的坐标,连起来后,可以有如图所示的效果(红色是HOG
pyramid检测的结果,绿色是shape_predictor的结果,仅把同一个器官的特征点连线)。

在这里插入图片描述

通过计算眼睛的宽高比来确定专注状态

基本原理:计算 眼睛长宽比 Eye Aspect Ratio,EAR.当人眼睁开时,EAR在某个值上下波动,当人眼闭合时
在这里插入图片描述

关键代码

 # -*- coding: utf-8 -*-
    # import the necessary packages
    from scipy.spatial import distance as dist
    from imutils.video import FileVideoStream
    from imutils.video import VideoStream
    from imutils import face_utils
    import numpy as np # 数据处理的库 numpy
    import argparse
    import imutils
    import time
    import dlib
    import cv2


    def eye_aspect_ratio(eye):
        # 垂直眼标志(X,Y)坐标
        A = dist.euclidean(eye[1], eye[5])# 计算两个集合之间的欧式距离
        B = dist.euclidean(eye[2], eye[4])
        # 计算水平之间的欧几里得距离
        # 水平眼标志(X,Y)坐标
        C = dist.euclidean(eye[0], eye[3])
        # 眼睛长宽比的计算
        ear = (A + B) / (2.0 * C)
        # 返回眼睛的长宽比
        return ear


    # 定义两个常数
    # 眼睛长宽比
    # 闪烁阈值
    EYE_AR_THRESH = 0.2
    EYE_AR_CONSEC_FRAMES = 3
    # 初始化帧计数器和眨眼总数
    COUNTER = 0
    TOTAL = 0
     
    # 初始化DLIB的人脸检测器(HOG),然后创建面部标志物预测
    print("[INFO] loading facial landmark predictor...")
    # 第一步:使用dlib.get_frontal_face_detector() 获得脸部位置检测器
    detector = dlib.get_frontal_face_detector()
    # 第二步:使用dlib.shape_predictor获得脸部特征位置检测器
    predictor = dlib.shape_predictor('D:/myworkspace/JupyterNotebook/fatigue_detecting/model/shape_predictor_68_face_landmarks.dat')
     
    # 第三步:分别获取左右眼面部标志的索引
    (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
    (rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
    
    # 第四步:打开cv2 本地摄像头
    cap = cv2.VideoCapture(0)
     
    # 从视频流循环帧
    while True:
        # 第五步:进行循环,读取图片,并对图片做维度扩大,并进灰度化
        ret, frame = cap.read()
        frame = imutils.resize(frame, width=720)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        # 第六步:使用detector(gray, 0) 进行脸部位置检测
        rects = detector(gray, 0)
        
        # 第七步:循环脸部位置信息,使用predictor(gray, rect)获得脸部特征位置的信息
        for rect in rects:
            shape = predictor(gray, rect)
            
            # 第八步:将脸部特征信息转换为数组array的格式
            shape = face_utils.shape_to_np(shape)
            
            # 第九步:提取左眼和右眼坐标
            leftEye = shape[lStart:lEnd]
            rightEye = shape[rStart:rEnd]
            
            # 第十步:构造函数计算左右眼的EAR值,使用平均值作为最终的EAR
            leftEAR = eye_aspect_ratio(leftEye)
            rightEAR = eye_aspect_ratio(rightEye)
            ear = (leftEAR + rightEAR) / 2.0
     
            # 第十一步:使用cv2.convexHull获得凸包位置,使用drawContours画出轮廓位置进行画图操作
            leftEyeHull = cv2.convexHull(leftEye)
            rightEyeHull = cv2.convexHull(rightEye)
            cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
            cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)
     
            # 第十二步:进行画图操作,用矩形框标注人脸
            left = rect.left()
            top = rect.top()
            right = rect.right()
            bottom = rect.bottom()
            cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 3)    
     
            '''
                分别计算左眼和右眼的评分求平均作为最终的评分,如果小于阈值,则加1,如果连续3次都小于阈值,则表示进行了一次眨眼活动
            '''
            # 第十三步:循环,满足条件的,眨眼次数+1
            if ear < EYE_AR_THRESH:# 眼睛长宽比:0.2
                COUNTER += 1
               
            else:
                # 如果连续3次都小于阈值,则表示进行了一次眨眼活动
                if COUNTER >= EYE_AR_CONSEC_FRAMES:# 阈值:3
                    TOTAL += 1
                # 重置眼帧计数器
                COUNTER = 0
                
            # 第十四步:进行画图操作,68个特征点标识
            for (x, y) in shape:
                cv2.circle(frame, (x, y), 1, (0, 0, 255), -1)
                
            # 第十五步:进行画图操作,同时使用cv2.putText将眨眼次数进行显示
            cv2.putText(frame, "Faces: {}".format(len(rects)), (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
            cv2.putText(frame, "Blinks: {}".format(TOTAL), (150, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
            cv2.putText(frame, "COUNTER: {}".format(COUNTER), (300, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) 
            cv2.putText(frame, "EAR: {:.2f}".format(ear), (450, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)


        print('眼睛实时长宽比:{:.2f} '.format(ear))
        if TOTAL >= 50:
            cv2.putText(frame, "SLEEP!!!", (200, 200),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
        cv2.putText(frame, "Press 'q': Quit", (20, 500),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (84, 255, 159), 2)
        # 窗口显示 show with opencv
        cv2.imshow("Frame", frame)
        
        # if the `q` key was pressed, break from the loop
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            
    # 释放摄像头 release camera
    cap.release()
    # do a bit of cleanup
    cv2.destroyAllWindows()


2.4 OpenCV

OpenCV是计算机视觉中一个经典的数据库。支持多语言、跨平台、功能强大。其提供了一个Python接口,用户可以在保证可读性和操作效率的前提下,用Python调用C/C++实现所需的功能。OpenCV是一个基于BSD许可证的跨平台计算机视觉库,可以在Linux、windows和Mac
OS操作系统上运行。它由一系列C函数和少量C++类组成。同时,它还提供了与Python、ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉中的许多通用算法。

本项目中OpenCV主要是在图片的采集的图片的预处理方面使用,通过操作界面中的按钮选项选择是否打开摄像头,使用OpenCV来调用电脑摄像头来检测录像过程中的聚焦和人脸镜头的矫正等状态,然后在摄像头的录像的视频流中抓取对应的人脸照片,然后调用内部的函数对照片的尺寸和光线等进行矫正处理后,传给神经网络进行特征值提取。

3 功能介绍

3.1人脸录入功能

数据库数据录入

将采集到的人脸信息和姓名、学号录入到数据库中,数据库表如下图所示:

在这里插入图片描述

在这里插入图片描述

过程演示

在这里插入图片描述

3.2 人脸识别

在这里插入图片描述

3.3 人脸专注度检测

拍摄时间进行计时,在界面上实时输出该学生在课堂上的有效学习时间和学生在课堂上专注时间的比例
在这里插入图片描述

3.4 识别记录

在这里插入图片描述

4 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1488006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Eclipse也可以轻松创建JSP动态Web项目 绿色、免费、神器、就是好用一大截!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

本地安装部署Flask并结合内网穿透实现远程访问本地web界面

文章目录 1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 本篇文章主要讲解如何在本地安装Flask&#xff0c;以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架&#xff0c;采用Python编程语…

树莓集团董事长王凯带队拜访国家超级计算成都中心,探索数字经济高质量发展新路径

随着数字经济时代全面开启&#xff0c;算力作为新型生产力&#xff0c;已成为支撑数字经济发展的“新底座”、驱动经济社会数字化转型的“新引擎”。 2024年3月1日&#xff0c;树莓科技&#xff08;成都&#xff09;集团有限公司董事长王凯、副总裁吴晓平、天府产城投资部部长…

Centos7.9双网卡绑定操作

同事整理的安装文档参考&#xff1a; 首先要有两块物理网卡 我用的虚机模拟两块物理网卡 先查看一下bonging模块有没有启动 lsmod | grep bonding 如没启动 modprobe bonding 查看两块网卡名字 创建物理网卡网口配置文件 vi /etc/sysconfig/network-scripts/if…

力扣 第 387 场周赛 解题报告 | 珂学家 | 离散化树状数组 + 模拟场

前言 整体评价 手速场模拟场&#xff0c;思路和解法都蛮直接的。 所以搞点活 如果T2&#xff0c;如果不固定左上角&#xff0c;批量查询某个点为左上角&#xff0c;求满足总和 ≤ k \le k ≤k的子矩阵个数 如果T2&#xff0c;如果不固定左上角&#xff0c;求总和 ≤ k \le k…

手写分布式配置中心(二)实现分布式配置中心的简单版本

这一篇文章比较简单&#xff0c;就是一个增删改查的服务端和一个获取配置的客户端&#xff0c;旨在搭建一个简单的配置中心架构&#xff0c;代码在 https://gitee.com/summer-cat001/config-center 服务端 服务端选择用springboot 2.7.14搭建&#xff0c;设计了4个接口/confi…

每天一道leetcode:20.有效的括号(简单;栈的经典题目)

⭐今日份题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对…

【数据结构与算法设计】上机课习题一

基础知识 勾画 1.存储结构是逻辑结构的&#xff08;&#xff09;实现 2.一个算法的时空性能是指该算法的&#xff08;&#xff09;和&#xff08;&#xff09; 3.在一般算法下一个算法的事件复杂性是&#xff08;&#xff09;的函数 4.用python设计一个算法&#xff0c;计算 …

输入文章id,爬取小红书某文章下所有评论

import requests import time import csvf open(小红书评论.csv,mode a,encodingutf-8,newline) csv_writer csv.DictWriter(f,fieldnames[内容,点赞数量,发布时间,昵称,头像链接,用户id]) csv_writer.writeheader()def spider(url):headers {"Cookie":"abR…

程序员竟然还有职业规划手册?

《程序员职业规划手册》不是一本具体的书&#xff0c;而是由前阿里技术总监雪梅老师讲授的一个专栏课程&#xff0c;总共有20讲&#xff0c;内容基本都是图片和文字形式&#xff0c;也有对应的语音讲述。 回顾了下毕业工作的这几年&#xff0c;我买过很多学习课程&#xff0c;…

【Python】进阶学习:pandas--read_csv()用法详解

&#x1f680;【Python】进阶学习&#xff1a;pandas–read_csv()用法详解&#x1f680; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教…

Windows服务器:通过nginx反向代理配置HTTPS、安装SSL证书

先看下效果&#xff1a; 原来的是 http&#xff0c;配置好后 https 也能用了&#xff0c;并且显示为安全链接。 首先需要 SSL证书 。 SSL 证书是跟域名绑定的&#xff0c;还有有效期。 windows 下双击可以查看相关信息。 下载的证书是分 Apache、IIS、Tomcat 和 Nginx 的。 我…

redis批量删除指定前缀key四种方法(收藏)

这篇文章主要介绍了redis批量删除指定前缀key四种方法。 目录 redis批量删除指定前缀key四种方法 第一种&#xff1a;第二种&#xff1a;第三种&#xff1a;第四种&#xff1a;Redis 如何批量删除指定前缀的Key 编码方式 redis批量删除指定前缀key四种方法 第一种&#xff…

【题解】—— LeetCode一周小结9

【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结8 26.二叉搜索树的范围和 题目链接&#xff1a;938. 二叉搜索树的范围和 给定二叉搜索树的根结点 root&#xff0c;返回值位于范围 [low, high] 之间的所有结点的值的和。 示例 1&#xff1a; 输…

SpringBoot-yaml语法

1.概念 在Springboot的项目中&#xff0c;配置文件有以下几种格式&#xff1a; Application.propertiesApplication.yamlApplication.yml 其中官方推荐我们使用yaml的格式(因为能表示的数据类型很多样) 2.基本语法 # yaml形式的配置文件# 普通的key-value&#xff08;分号之后…

windows环境下Grafana+loki+promtail入门级部署日志系统,收集Springboot(Slf4j+logback)项目日志

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

MyBatis操作数据库(XML方式)

MyBatis是一个持久层框架&#xff0c;和Spring没有任何关系&#xff0c;可以用来简化数据库的操作&#xff01; 创建工作&#xff1a; 创建Spring Boot工程&#xff0c;并导入MyBatis的起步依赖&#xff0c;Mysql的依赖等 配置数据 #配置数据库的连接字符串 spring:datasour…

ruoyi 图片等文件资源读取

老是忘&#xff0c;记录一下 ResourcesConfig 文件下 /** 本地文件上传路径 */ registry.addResourceHandler(Constants.RESOURCE_PREFIX "/**").addResourceLocations("file:" RuoYiConfig.getProfile() "/"); /*** 资源映射路径 前缀*/ …

C++使用工具进阶(LOG输出、堆栈跟踪、代码结构、code review)

0. 简介 对于C&#xff0c;无论是大学生还是算法工程师都是非常需要学习并使用的一门语言&#xff0c;而C不像python、rust一样简单好用。不单单是在嵌套复杂代码后的逻辑还是各种类和堆栈的管理&#xff0c;都是非常头疼的问题。一般来说对于LOG类很多都是使用GLOG、而堆栈跟…

STM32 (1)

1.基本信息 stm32是由ST公司生产的一种32位微控制器&#xff08;单片机&#xff09;。 1.1 各种型号 stm32是32位单片机的总称&#xff0c;有多种不同的系列。 32即用32个比特位表示一个地址&#xff0c;寻址范围&#xff1a;0x00000000 --0xffffffff (4GB) 1.2 存储密度 …