基于深度学习的课堂专注度分析与作弊检测系统:Python实现与调优指南
简介这份资源是一套基于深度学习实现的课堂专注度分析与考试作弊检测系统包含完整Python源码与配套文档说明面向计算机相关专业正在做毕业设计的学生以及需要项目实战练习的学习者。项目经导师指导并通过评审难度适中源码均经本地编译与严格调试可正常运行。压缩包共626个文件约87.63MB以383个py源码文件为核心辅以41个md文档、32个yaml配置、25张jpg与21个gif图示以及cfg、cu、cpp、sh等模型与脚本文件覆盖数据配置、网络定义、训练推理与结果展示等环节。内容预览中可见yolov3、RetinaFace等模型配置与权重文件说明系统涉及目标检测与人脸分析等技术路线。目前已有163人学习下载适合希望快速搭建可运行系统、理解深度学习落地流程并完成毕设或课程实践的读者参考使用。1. 课堂专注度分析与作弊检测从一段监控视频到可用告警的完整链路一间装了摄像头的教室一节课四十五分钟视频里同时存在几十张脸。教务真正想要的不是把视频存下来而是想知道这节课有多少人走神了、哪个时间段集体低头、有没有人在考试时频繁转头或传递东西。基于深度学习开发的课堂专注度分析和考试作弊检测系统本质就是把这段原始视频拆成人脸检测 → 头部姿态与视线估计 → 时序行为判定 → 告警输出四段流水线用 Python 串起来跑。它适合两类人一类是手里有课堂或考场视频、想快速搭出可演示原型的在校开发者另一类是拿到一份 Python 源码加文档说明、却卡在环境配置和参数调不对的工程新手。这篇笔记按先讲清每个模块为什么这么选再给能直接抄的命令和参数来写重点放在能复现、能调参、能排错上而不是泛泛谈深度学习有多强。2. 系统拆成四段流水线为什么不能一个模型端到端硬扛很多人第一反应是找个行为识别模型把视频丢进去输出专注或作弊。真做起来会发现这条路在课堂场景里几乎走不通作弊动作样本极少、标注成本极高端到端模型没有足够数据去学而专注度本身是个连续量不是离散标签。所以常见做法是拆成可解释的四段每段用成熟模型中间结果可单独调试。2.1 人脸检测与跟踪先解决谁是谁第一段负责在每帧里框出人脸并给同一张脸分配稳定的 ID。检测用轻量模型保证帧率跟踪用简单的 IoU 匹配或卡尔曼滤波即可不必上重型 ReID。原因是课堂里人基本不动跟踪难度低把算力留给后面的姿态估计更划算。import cv2 import numpy as np # 用 OpenCV 自带的人脸检测器做最小可跑版本替换成 YOLO 系检测器时接口保持一致 detector cv2.CascadeClassifier( cv2.data.haarcascades haarcascade_frontalface_default.xml ) def detect_faces(frame, scale1.1, min_neighbors5, min_size(60, 60)): gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # scaleFactor 越小越慢但越不容易漏检课堂远景建议 1.05~1.1 # minNeighbors 越大误检越少但小脸容易被过滤5 是常用折中 faces detector.detectMultiScale( gray, scaleFactorscale, minNeighborsmin_neighbors, minSizemin_size ) return faces # 返回 (x, y, w, h) 列表这段代码里scaleFactor和minNeighbors是最常被调的两个参数。教室后排人脸只有几十像素min_size设太大直接漏检设太小又会把窗户、投影仪误判成人脸。我的经验是先用一段真实课堂视频跑一遍把min_size定在最远那排脸的实际像素高度再乘 0.8然后微调minNeighbors压误检。跟踪部分给每个框维护一个 ID 和丢失帧计数连续几帧匹配不上才注销避免人脸被遮挡时 ID 频繁跳变。2.2 头部姿态与视线估计专注度的核心信号专注度最可靠的信号是头部朝向和眼睛开合。头部姿态用 6D 或欧拉角表示常见做法是检测人脸关键点后做 PnP 解算或用直接回归姿态的轻量网络。视线估计则看瞳孔相对眼眶的位置。两者结合能区分低头看书和低头玩手机——前者头低但视线在桌面后者头低且视线频繁下移。# 用关键点做头部姿态解算的骨架landmarks 为 68 点或 5 点 import numpy as np # 3D 人脸模型参考点简化版单位任意比例正确即可 MODEL_POINTS np.array([ (0.0, 0.0, 0.0), # 鼻尖 (0.0, -63.6, -12.5), # 下巴 (-43.3, 32.7, -26.0), # 左眼左角 (43.3, 32.7, -26.0), # 右眼右角 (-28.9, -28.9, -24.1), # 左嘴角 (28.9, -28.9, -24.1), # 右嘴角 ], dtypenp.float64) def estimate_head_pose(landmarks_2d, frame_size): h, w frame_size[:2] focal w # 粗略焦距真实标定可换成相机内参 center (w / 2, h / 2) cam_matrix np.array([[focal, 0, center[0]], [0, focal, center[1]], [0, 0, 1]], dtypenp.float64) dist np.zeros((4, 1)) ok, rvec, tvec cv2.solvePnP( MODEL_POINTS, landmarks_2d, cam_matrix, dist, flagscv2.SOLVEPNP_ITERATIVE ) if not ok: return None rmat, _ cv2.Rodrigues(rvec) # 从旋转矩阵提取俯仰角负值通常代表低头 pitch np.degrees(np.arcsin(-rmat[2, 1])) return pitchfocal用图像宽度近似是常见偷懒做法误差在可接受范围但如果要精确到几度得用棋盘格标定相机内参。pitch的阈值不是固定的前排学生和后排学生因为俯仰视角不同同样的低头动作算出来的角度不一样。稳妥做法是按人脸框在画面中的纵向位置做一次线性补偿或者干脆对每个跟踪 ID 记录一段基线用相对变化判断。2.3 时序行为判定把逐帧信号变成事件单帧姿态没有意义专注度是时间维度上的统计量。常见做法是滑动窗口每 1 秒聚合一次统计窗口内低头帧占比、视线偏离占比、头部转动方差。作弊检测则关注短时间内的异常模式比如头部在 2 秒内左右摆动超过阈值、或手部区域频繁进入画面下方。from collections import deque class FocusTracker: def __init__(self, window_sec30, fps25): self.window deque(maxlenwindow_sec * fps) self.fps fps def update(self, pitch, gaze_off): # 低头超过 20 度或视线偏离记为不专注帧 unfocused 1 if (pitch -20 or gaze_off) else 0 self.window.append(unfocused) def focus_ratio(self): if not self.window: return 1.0 return 1.0 - sum(self.window) / len(self.window) def is_suspicious(self, turn_events): # 30 秒内头部大幅转动超过 5 次判为可疑 return turn_events 5window_sec决定告警灵敏度窗口太短一次正常低头就触发告警太长作弊动作被平均掉。课堂专注度统计我一般用 30 秒窗口作弊检测用 5 到 10 秒的短窗口。turn_events的计数要在跟踪 ID 维度上做不能全画面累加否则一个人频繁转头会污染所有人的统计。2.4 告警输出与可视化让结果能被人看懂最后一段把事件写成结构化记录并叠加到视频上。输出通常包括每个学生的专注度曲线、整节课的专注度均值、可疑时间段列表。可视化用 OpenCV 画框和文字即可不必上重型前端。def draw_overlay(frame, faces, tracker): for (x, y, w, h) in faces: ratio tracker.focus_ratio() color (0, 255, 0) if ratio 0.7 else (0, 165, 255) cv2.rectangle(frame, (x, y), (x w, y h), color, 2) cv2.putText(frame, f{ratio:.2f}, (x, y - 8), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) return frame颜色阈值 0.7 是经验值实际按班级基线调整。输出记录建议同时写 CSV 和 JSONCSV 给教务做统计JSON 给前端做回放定位。3. 环境配置与源码跑通Python 依赖、模型权重、目录结构拿到一份 Python 源码加文档说明第一步不是读代码而是把环境跑起来。这一步翻车的人最多血泪经验是先确认 Python 版本再装依赖最后放权重文件顺序错了会浪费大量时间排查。3.1 Python 环境与依赖安装推荐 Python 3.8 到 3.10太新的版本某些深度学习库轮子还没跟上。用虚拟环境隔离避免和系统包打架。# 创建并激活虚拟环境 python -m venv venv # Windows venv\Scripts\activate # Linux / macOS source venv/bin/activate # 安装核心依赖版本按源码文档说明为准 pip install opencv-python4.8.0.76 pip install numpy1.24.3 pip install torch2.0.1 torchvision0.15.2 pip install onnxruntime1.15.1opencv-python和numpy版本要匹配否则会出现numpy的 ABI 报错。torch装 CPU 版还是 GPU 版看机器有 NVIDIA 显卡且装了对应 CUDA 就装 GPU 版否则 CPU 版也能跑只是帧率低。onnxruntime用于加载导出的 ONNX 模型比直接跑 PyTorch 推理快适合部署。3.2 模型权重与目录结构源码通常不会带大权重文件需要按文档说明放到指定目录。常见结构如下目录用途注意事项weights/存放检测、姿态、视线模型权重文件名要和代码里加载路径一致data/测试视频和输出结果视频建议先转成 25fps 统一帧率configs/阈值、窗口大小等参数改参数优先改这里别硬编码logs/运行日志和告警记录定期清理避免占满磁盘权重文件缺失时程序一般会在加载处报FileNotFoundError按报错路径补文件即可。如果文档说明里给了下载方式按说明操作没有的话用代码里指定的模型名去对应框架的官方模型库找同结构权重。3.3 跑通最小示例先用一段短视频验证整条链路别一上来就处理整节课。python main.py --source data/test_5min.mp4 --output logs/result.csv --show--source指定输入视频--output指定结果 CSV--show打开实时预览窗口。第一次跑建议关掉--show用--save-video输出带标注的视频方便逐帧检查。如果报显存不足把批处理大小调到 1或改用 ONNX 推理。4. 参数调优与阈值设定专注度和作弊判定的边界在哪模型跑通只是开始真正决定系统好不好用的是阈值。阈值定错要么满屏误报要么什么都检测不到。4.1 专注度阈值的分层设定不要用一个全局阈值。按人脸在画面中的位置分层前排俯仰角天然偏下后排偏上。可以按人脸框中心 y 坐标分三段每段用不同的 pitch 阈值。分层人脸中心 y 范围低头阈值说明前排画面高度 0~33%-25 度视角偏下阈值放宽中排33%~66%-20 度标准阈值后排66%~100%-15 度视角偏上阈值收紧这张表是起点实际要用自己教室的视频标定。方法是让几个学生做标准低头动作记录每层的 pitch 值取平均值再减 5 度作为阈值。4.2 作弊检测的时序参数作弊检测靠的是短时间异常参数比专注度更敏感。核心三个参数转动角度阈值、时间窗口、触发次数。CHEAT_CONFIG { yaw_threshold: 35, # 头部左右转动超过 35 度记为一次转头 window_sec: 8, # 8 秒窗口 trigger_count: 4, # 窗口内转头 4 次触发告警 hand_region_ratio: 0.3, # 手部进入画面下方 30% 区域 }yaw_threshold设太小正常看黑板也会被算成转头设太大真作弊动作漏检。trigger_count和window_sec要一起调窗口短、次数少误报多窗口长、次数多漏报多。我的经验是先用 8 秒 4 次跑几段真实考场视频看误报率再微调。4.3 用验证集校准而不是拍脑袋有标注数据的话画一条 ROC 曲线选阈值。没有标注数据就人工看几段视频统计误报和漏报手动调。关键是记录每次调整后的误报数和漏报数别凭感觉。5. 避坑与排查那些让系统跑不起来的常见问题这一章全是踩过的坑按现象 → 原因 → 解决写遇到问题直接对号入座。5.1 检测框疯狂闪烁、ID 频繁跳变现象同一个人的人脸框忽大忽小跟踪 ID 每几帧换一次。原因检测器在相邻帧输出不稳定跟踪匹配阈值太严。解决给检测结果做一次指数平滑或把跟踪的 IoU 匹配阈值从 0.5 降到 0.3并允许丢失 5 帧内保持 ID。5.2 低头阈值在真实教室完全不准现象按文档默认阈值跑全班都被判成不专注。原因默认阈值是在正面平视的测试视频上调的真实教室摄像头有俯角。解决按 4.1 的分层方法重新标定或对每个跟踪 ID 记录前 10 秒的 pitch 均值作为个人基线用相对变化判断。5.3 显存不足或帧率低到无法实时现象跑几分钟后程序崩溃报 CUDA out of memory。原因批处理太大或模型没释放中间张量。解决把批大小降到 1推理时用torch.no_grad()或导出 ONNX 用 onnxruntime 跑。帧率低的话把检测间隔改成每 3 帧检测一次中间帧用跟踪结果。5.4 作弊告警全是误报现象一节课触发几十次作弊告警。原因转头阈值太低或没排除正常动作如捡笔、看时间。解决提高yaw_threshold到 40 度以上增加持续时间要求转动必须持续超过 0.5 秒并把手部区域检测加上只有头部异常加手部异常才告警。5.5 输出 CSV 中文乱码现象用 Excel 打开结果文件学生姓名或备注是乱码。原因CSV 默认编码不是 UTF-8 with BOM。解决写文件时用encodingutf-8-sigExcel 就能正确识别。6. 从能跑到好用把专注度曲线做成可回放的教学反馈系统能跑通、告警能出来只算完成一半。真正有价值的是把逐帧结果变成教师能看懂的反馈。我一般会做两件事一是把整节课的专注度按分钟聚合成曲线标出低谷时间段二是把告警时间点对应到视频时间戳支持点击跳转回放。import pandas as pd def build_minute_curve(csv_path): df pd.read_csv(csv_path) # 假设有 timestamp 和 focus_ratio 两列 df[minute] (df[timestamp] // 60).astype(int) curve df.groupby(minute)[focus_ratio].mean().reset_index() # 标出低于 0.5 的低谷分钟 curve[low] curve[focus_ratio] 0.5 return curve def export_report(curve, outlogs/report.csv): curve.to_csv(out, indexFalse, encodingutf-8-sig)groupby(minute)把秒级数据聚合成分钟级low列直接标出低谷教师一眼就能看到哪几分钟学生集体走神。回放功能用时间戳做锚点前端拿到告警列表后按timestamp定位视频即可。验证系统好不好用别只看准确率数字。找三位老师各看一段带标注的结果视频问两个问题告警时间点对不对、有没有明显漏掉的。如果老师觉得告警太频繁就调高触发次数如果觉得漏就降低阈值。这个反馈循环比任何离线指标都实在。最后说个我自己的习惯每次调完参数一定把配置和对应的误报漏报数记在一个表格里攒够十几组再回头看就能摸出这套参数在自己场景下的合理区间。别指望一次调对也别每次凭感觉改。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Excel文本清洗实战:巧用CODE函数实现中英文分离与姓名统计

Excel文本清洗实战:巧用CODE函数实现中英文分离与姓名统计

开头先说个现象。我在帮朋友处理一张几百人的报名名单时,发现问题远比想象中麻烦:同一列里既有“张三138****abcd”这种带备注的,又有“Johnson 王”这种中英混排的,还有全角空格、乱码、甚至日期被Excel自动转成了五位数序列号。…

2026/10/2 22:02:09 阅读更多 →
WSLg+Ubuntu 22.04图形化实战:Wayland原生GUI开发环境搭建

WSLg+Ubuntu 22.04图形化实战:Wayland原生GUI开发环境搭建

1. 这不是“装个图形界面”那么简单:Windows Terminal WSL Ubuntu 图形化的真实价值与常见误区 你搜“WSL 图形化”,十有八九会看到一堆标题党:“5分钟让Ubuntu在Windows上跑GUI!”、“媲美原生Linux桌面体验!”——…

2026/10/2 22:02:09 阅读更多 →
Python二手房数据可视化分析:从数据清洗到PPT实战

Python二手房数据可视化分析:从数据清洗到PPT实战

简介:这是一套面向Python数据分析初学者、毕业设计及期末大作业需求的南京二手房数据可视化完整项目资料,围绕链家网房源数据展开从采集到建模的全流程实践。资源包共157个文件,约40.04MB,包含18个py源码脚本、18个csv原始与清洗数…

2026/10/2 22:02:09 阅读更多 →

最新新闻

AI编程测试验证Skills套件:从代码生成到质量闭环的实践指南

AI编程测试验证Skills套件:从代码生成到质量闭环的实践指南

1. 一句话能写代码,但你真的敢直接上线吗AI写代码这件事,这两年已经从“玩具”变成了“主力”。命令行里敲一句“帮我写一个用户注册接口,用Python实现,带JWT签名验证”,十几秒后一段完整代码就躺在编辑器里了。速度确…

2026/10/2 22:43:00 阅读更多 →
游戏引擎开发实战:团队分工与底层架构的关键认知

游戏引擎开发实战:团队分工与底层架构的关键认知

先说明一下我对这篇文章的定位:它不是一篇教科书式的百科讲解,也不是某家引擎的官方文档翻译。我写的是自己做引擎开发这几年,从团队协作到底层代码之间反复踩出来的认知。标题里带着"001",说明这是个系列,第…

2026/10/2 22:43:00 阅读更多 →
前后端分离跨域问题全解析:从同源策略到Nginx实战

前后端分离跨域问题全解析:从同源策略到Nginx实战

做前后端分离开发,谁还没被跨域问题坑过几次。本地npm run dev跑得好好的,一接后端接口就报CORS错误,或者开发环境一切正常,部署到服务器上又冒出跨域问题。这个从前后端分离架构诞生起就伴随左右的经典难题,坑了无数开…

2026/10/2 22:43:00 阅读更多 →
iOS相册多选删除实战:Photos框架批量删除与UI同步

iOS相册多选删除实战:Photos框架批量删除与UI同步

简介:这份PDF文档面向iOS开发初学者与中级开发者,聚焦相册图片多选、删除及拍照上传这一常见业务场景,帮助解决社交、图片编辑类应用中与系统相册交互、数据同步和图片压缩上传等实际问题。资源包共1个PDF文件,大小约77KB&#xf…

2026/10/2 22:43:00 阅读更多 →
cron表达式详解:从秒级到小时级,定时任务写法一次搞懂

cron表达式详解:从秒级到小时级,定时任务写法一次搞懂

cron表达式真是个神奇的东西,看起来就几个星号加斜杠,真要写对却没几个同事能一次搞定。尤其是“每N秒”“每N分钟”“每N小时”这种高频需求,网上答案五花八门,抄错了也不知道问题出在哪。我翻了翻手头的项目,发现大部…

2026/10/2 22:43:00 阅读更多 →
RESTful API设计实战:从资源建模到可靠服务构建

RESTful API设计实战:从资源建模到可靠服务构建

1. 先把 RESTful 说清楚:它定义的边界与常见认知偏差把接口地址写得像英语句子,就敢叫 RESTful,这是我在团队评审里最常碰到的情况。比如把GET /getUserInfo?id1改成GET /users/id/1,然后宣布“我们做了一轮 RESTful 改造”。如果…

2026/10/2 22:41:59 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 6:09:11 阅读更多 →