摘要课堂学生行为识别是计算机视觉项目里非常适合做“项目实战交付”的方向。相比普通的目标检测项目它不仅要检测到人还要进一步理解人的姿态和动作例如学生是否抬头听课、是否举手互动、是否低头书写、是否疑似趴桌。传统目标检测只能给出“人”的检测框很难表达手腕、肩膀、头部之间的位置关系而 YOLO-Pose 这类姿态估计模型可以直接输出人体关键点天然适合做课堂姿态分析、课堂互动统计、教学状态观察和课程设计展示。本文围绕一个完整可运行项目展开项目名称为“基于 YOLO-Pose 的课堂学生行为识别与专注度统计系统”。系统使用 COCO-17 人体关键点作为姿态表达方式上层通过透明几何规则判断课堂行为再根据行为类别计算学生级专注度得分和班级级统计结果。项目同时考虑到实际运行门槛如果本地存在yolov8n-pose.pt权重可以使用 Ultralytics YOLO-Pose 对真实图片或视频进行姿态推理如果运行机器没有权重、不能联网或没有 GPU系统会自动切换到内置匿名关键点样例保证直接运行主程序也能看到完整输出结果。本文适合用于 CSDN 技术博客、课程设计、项目实战展示、AI 项目交付、视觉检测项目二次开发。文章会从项目背景、技术路线、系统架构、核心代码、运行方式、结果分析、隐私边界和扩展方向几个方面展开最后给出完整项目目录、运行截图和输出文件说明。关键词YOLO-Pose、YOLO11、姿态估计、课堂行为识别、学生专注度统计、人体关键点、COCO-17、计算机视觉项目、Python 项目实战、CSDN 源码项目一、为什么选择课堂学生行为识别这个项目很多视觉检测项目只停留在“检测一个物体”的阶段例如检测安全帽、车辆、垃圾、裂缝、零件缺陷等。这类项目适合入门但如果想把项目写成更有展示感的技术博客就需要进一步做“检测结果之后的业务分析”。课堂学生行为识别正好符合这个特点。它的输入可以是一张课堂图片、一段课堂视频或者摄像头画面中间层是人体姿态关键点输出层不是简单画框而是学生级行为标签、班级级专注度、行为分布图和分析报告。这个项目的价值主要体现在三个方面。第一它把深度学习模型和规则分析结合起来。YOLO-Pose 负责从图像中提取人体关键点规则模块负责把关键点转化为行为标签。这样既能体现深度学习推理也能体现业务逻辑设计不会让项目只停留在调用模型 API。第二它适合做完整工程交付。项目可以包含命令行程序、可选 Web 页面、配置文件、权重说明、示例数据、可视化图片、CSV 报表、Markdown 分析报告和博客文章。对于课程设计或项目实践来说这种结构比单个脚本更完整。第三它有明确的扩展空间。基础版本可以用单帧规则判断进阶版本可以加入视频跟踪、多帧行为平滑、学生轨迹统计、课堂时间轴分析、教师互动事件识别甚至可以接入 FastAPI 或 Streamlit 做成后台系统。当然这个项目也有明显边界。姿态识别只能根据身体关键点推断“可观察行为”不能直接判断学生真实心理状态。学生低头可能是在做笔记也可能是在走神学生抬头也不一定代表完全专注。因此本项目更适合作为课堂观察辅助工具和 AI 项目演示不应该被用于隐蔽监控、个体惩罚或替代教师判断。真实课堂画面中学生姿态、遮挡、桌椅位置和拍摄角度都会影响关键点质量。项目的重点不是简单识别一个动作而是把可观察姿态转成可解释、可复核的统计结果。二、技术调研与方案选择本项目参考了 Ultralytics YOLO-Pose 的技术路线。Ultralytics 的 Pose Estimation 文档说明姿态估计任务会输出目标关键点的坐标和置信度这些关键点通常代表人体关节或其他具有区分度的位置。官方文档也提到YOLO 的姿态模型使用-pose后缀默认模型使用 COCO keypoints 数据集训练能够输出 17 个人体关键点。对于课堂行为识别来说这 17 个关键点已经足以覆盖头部、肩部、肘部、手腕、髋部、膝盖和脚踝等主要部位。COCO-Pose 数据集说明中也明确提到COCO-Pose 扩展了 COCO Keypoints 2017 标注包含人体 17 个关键点可用于人体姿态估计任务。项目中采用 COCO-17 的原因很直接它是主流姿态估计项目中最常见的格式之一Ultralytics YOLO-Pose 输出也与这个格式兼容后续如果要接训练集、标注工具或模型微调会比较方便。项目没有一开始就强制用户必须下载权重和安装 GPU 环境而是设计了两条路线第一条是完整 YOLO-Pose 路线。用户准备yolov8n-pose.pt权重后系统加载本地权重对真实图片或视频做姿态推理再进入行为分析模块。这个路线适合展示真实课堂图片、监控截帧或视频片段。第二条是离线 demo 路线。项目内置一个demo_data/classroom_pose_sample.json文件里面保存了匿名模拟的 COCO-17 关键点。用户没有模型权重时主程序仍然能运行仍然会生成姿态图、行为分布图、专注度柱状图和分析报告。这个设计非常重要因为很多项目交付环境无法联网也不一定有 GPU。如果一个项目必须先下载大模型才能运行用户体验会明显下降。从工程角度看真实项目通常不应该把模型推理和业务判断写死在一个脚本里。本项目把 YOLO-Pose 推理、姿态规则判断、结果可视化、报告导出拆成独立模块方便后续二次开发。三、系统整体架构系统整体架构如下图所示。输入端可以是真实图片、视频或内置关键点样例中间层由姿态推理模块输出 COCO-17 关键点规则层根据头部、肩部、手腕和躯干之间的几何关系判断课堂行为输出层生成可视化图片、统计图、CSV、JSON 和 Markdown 报告。这个项目的核心不是“模型越大越好”而是把模型输出变成可解释的业务结果。YOLO-Pose 检测到一个人以后会给出 17 个关键点。仅凭这些关键点人类观察者其实已经可以看出很多姿态信息手腕在肩膀上方多数情况下表示举手头部明显靠近桌面可能是趴桌头部略低于正常位置可能是低头书写或阅读头部稳定在肩膀上方可能是正常听课。项目把这些观察转成规则就能形成一个可运行、可解释、可修改的课堂行为识别系统。流程可以概括为七步加载输入源、进行姿态检测或读取关键点样例、规范化关键点格式、计算姿态几何指标、判断学生行为、聚合班级统计结果、导出可视化和报告。这样设计的好处是每一步都可以独立替换。例如后续想把规则判断换成机器学习分类器只需要修改behavior_analyzer.py想把输出接入 Web 页面只需要读取outputs/attention_summary.json和outputs/classroom_behavior_results.csv想把 YOLOv8n-pose 换成 YOLO11n-pose 或其他姿态模型只要保证输出仍然能转成 COCO-17 格式即可。四、项目目录结构说明项目文件结构如下。核心目录说明如下classroom_yolo_pose_attention_system/ ├── blog.md ├── README.md ├── requirements.txt ├── requirements_yolo.txt ├── main.py ├── run_demo.py ├── app.py ├── run.bat ├── run.sh ├── src/ │ ├── data_loader.py │ ├── keypoints.py │ ├── pose_engine.py │ ├── behavior_analyzer.py │ ├── visualizer.py │ └── report_writer.py ├── configs/ │ └── config.json ├── demo_data/ │ └── classroom_pose_sample.json ├── weights/ │ └── README_WEIGHTS.md ├── images/ │ ├── figures/ │ └── results/ ├── outputs/ └── docs/main.py是主入口负责串联配置加载、姿态推理、行为分析、可视化和报告导出。用户只要运行python main.py --mode demo就可以看到结果。src/pose_engine.py是姿态推理模块。它优先尝试加载本地 YOLO-Pose 权重如果没有权重或用户指定 demo 模式就读取内置匿名关键点。这样既保留真实推理能力又保证项目交付时能直接运行。src/behavior_analyzer.py是行为规则模块。它接收每个学生的 17 个关键点计算头肩距离比例、手腕相对肩膀高度、关键点平均置信度等指标再输出行为标签和专注度分数。src/visualizer.py负责绘图包括课堂姿态标注图、行为分布图、学生专注度柱状图和命令行运行截图。对于技术博客来说结果图非常重要因为读者需要直观看到项目不是停留在代码层面而是真的跑出了结果。weights/README_WEIGHTS.md是权重说明文件写清楚模型名称、下载地址、保存路径和运行前检查方式。项目已使用轻量yolov8n-pose.pt完成真实图片推理验证如果分享平台限制大文件也可以只保留说明文件并让读者按文档重新下载权重。五、COCO-17 关键点与课堂行为规则COCO-17 人体关键点包含以下部位0 nose 1 left_eye 2 right_eye 3 left_ear 4 right_ear 5 left_shoulder 6 right_shoulder 7 left_elbow 8 right_elbow 9 left_wrist 10 right_wrist 11 left_hip 12 right_hip 13 left_knee 14 right_knee 15 left_ankle 16 right_ankle对于课堂行为识别来说最关键的是头部、肩部、手腕和髋部。项目没有直接使用所有关键点进行复杂建模而是先提取几个容易解释的几何指标。第一个指标是头肩比例。图像坐标中y 轴向下增长。正常坐姿下鼻尖应该明显位于肩膀上方所以“鼻尖 y 坐标减去肩部中点 y 坐标”通常是负数。为了让不同身高、不同画面尺度下的结果具有可比性项目用肩部中点到髋部中点的距离作为躯干长度对这个差值做归一化。这个指标在代码中叫head_ratio。当head_ratio非常小例如 -0.6 左右说明头部明显在肩膀上方通常是正常听课当它接近 0说明头部已经靠近肩部高度可能是趴桌或睡觉当它介于两者之间则可能是低头书写或阅读。第二个指标是手腕相对肩膀高度。如果左手腕或右手腕的 y 坐标明显小于肩膀 y 坐标说明手腕在画面中更靠上这通常对应举手动作。项目没有要求手腕一定要达到头顶以上因为课堂画面中经常有遮挡、角度变化和坐姿差异只要手腕高于肩部一定比例就可以判断为举手互动。第三个指标是姿态质量。每个关键点都有置信度如果平均置信度太低或者关键部位缺失系统不会强行给出明确行为而是标记为“姿态不确定”。这比强行分类更稳妥也更符合实际项目要求。当前项目支持五类行为attentive_listening 正常听课 active_raising_hand 举手互动 head_down_writing 低头书写/阅读 desk_sleeping 疑似趴桌/睡觉 uncertain 姿态不确定每类行为对应一个专注度得分。正常听课设置为 88 分举手互动设置为 95 分低头书写/阅读设置为 70 分疑似趴桌/睡觉设置为 25 分姿态不确定设置为 50 分。这里的分数不是教育评价标准而是为了项目演示和统计可视化而设计的指标。实际应用时建议根据课堂场景、年级、课程类型和教师需求重新调整。六、核心代码讲解姿态推理模块姿态推理模块在src/pose_engine.py中。它的设计重点是“双模式运行”有权重时走 YOLO没有权重时走 demo。这样项目不会因为缺少.pt文件而无法启动。核心逻辑如下class PoseEngine: def __init__(self, weight_pathweights/yolov8n-pose.pt, confidence_threshold0.35, force_demoFalse): self.weight_path Path(weight_path) self.confidence_threshold confidence_threshold self.force_demo force_demo def _try_load_yolo(self): if self.force_demo: return False if not self.weight_path.exists(): return False from ultralytics import YOLO self._model YOLO(str(self.weight_path)) return True这段代码先判断是否强制 demo再判断权重文件是否存在。只有本地确实存在权重文件时才尝试导入 Ultralytics 并加载模型。这样可以避免用户在没有安装ultralytics的环境下运行 demo 时报错。如果加载 YOLO 成功系统调用模型进行推理并把 Ultralytics 返回的 keypoints 转成统一格式kpts_np keypoints.data.cpu().numpy() boxes_np boxes.xyxy.cpu().numpy() for idx, kpts in enumerate(kpts_np): detections.append({ student_id: fS{idx 1:02d}, bbox: boxes_np[idx].tolist(), keypoints: [[float(v) for v in row] for row in kpts.tolist()], confidence: float(conf_np[idx]), })如果加载 YOLO 失败系统读取demo_data/classroom_pose_sample.json并返回同样结构的数据。这样后续模块不需要关心数据来自真实 YOLO 还是内置关键点样例统一按detections处理即可。七、核心代码讲解行为分析模块行为分析模块在src/behavior_analyzer.py中。核心函数是classify_one它输入一个学生的关键点输出行为类别和中间指标。首先计算肩部中点、髋部中点和躯干长度shoulder_mid midpoint(left_shoulder, right_shoulder) hip_mid midpoint(left_hip, right_hip) torso_len max(distance(shoulder_mid, hip_mid), 1.0) head_ratio (float(nose[1]) - shoulder_mid[1]) / torso_len这里使用torso_len做归一化非常关键。如果只看像素差不同远近位置的学生会产生明显偏差。坐在后排的学生身体尺寸小头肩像素差也小坐在前排的学生身体尺寸大头肩像素差也大。归一化后项目判断的是相对姿态而不是绝对像素。然后判断是否举手left_hand_raised ( left_wrist[2] low_conf and left_wrist[1] left_shoulder[1] - torso_len * wrist_raise_ratio ) right_hand_raised ( right_wrist[2] low_conf and right_wrist[1] right_shoulder[1] - torso_len * wrist_raise_ratio )由于图像坐标 y 轴向下手腕 y 坐标越小表示越靠上。只要手腕明显高于肩膀就判断为举手互动。最后根据规则输出行为if left_hand_raised or right_hand_raised: return active_raising_hand, metrics if head_ratio desk_sleep_ratio: return desk_sleeping, metrics if head_ratio head_down_ratio: return head_down_writing, metrics return attentive_listening, metrics这套规则有两个优点。第一容易理解。读者可以直接看懂为什么系统判断某个学生是低头或举手。第二容易修改。比如某个课堂角度下低头阈值太敏感只需要调整configs/config.json中的阈值不需要重新训练模型。八、运行项目项目默认可以离线运行。进入项目目录后安装基础依赖pip install -r requirements.txt运行 demopython main.py --mode demo如果在 Windows 上也可以直接双击或运行run.batLinux 或 macOS 可以运行bash run.sh如果想使用真实 YOLO-Pose请先安装完整依赖pip install -r requirements_yolo.txt然后准备权重yolov8n-pose.pt放到weights/yolov8n-pose.pt真实图片推理命令如下python main.py --mode auto --source path/to/classroom.jpg --weights weights/yolov8n-pose.pt如果需要一个简单展示页面可以运行streamlit run app.py九、运行效果展示本项目已经使用真实课堂图片运行主程序并在images/results/中保存了结果图片。输入图片来自 Wikimedia Commons 的课堂场景推理权重为本地yolov8n-pose.pt。从运行结果可以看到系统识别了 6 个学生姿态平均专注度为 76.0活跃率为 0.333。行为分布中包含正常听课和低头书写/阅读两类说明规则层已经基于真实 YOLO-Pose 关键点完成了学生级行为判断和班级级统计。课堂姿态标注结果如下。图中每个学生都用骨架线和关键点进行标注同时显示学生编号、行为类别和得分。这里的关键点并不包含人脸身份信息只包含匿名坐标因此更适合作为项目演示数据。真实使用时仍然要注意图像采集授权和隐私保护。行为分布图如下。行为分布图可以帮助教师或项目评审快速理解整堂课的状态。例如举手人数较多说明课堂互动较积极低头人数较多不一定代表不专注也可能是书写任务较多趴桌人数较多则可能需要关注课堂节奏或学生状态。学生级专注度得分图如下。柱状图展示了每个学生的得分。这里的分数不是绝对评价而是用于项目展示和辅助观察。实际落地时可以把单帧得分扩展为多帧平均分或者按时间窗口统计比如每 5 分钟输出一次课堂活跃度曲线这样会比单帧判断更稳健。十、输出文件说明运行后系统会在outputs/目录生成三个主要文件。第一个是学生级 CSVoutputs/classroom_behavior_results.csv它包含学生编号、行为类别、中文行为名称、专注度分数、姿态质量、头肩比例、是否举手和风险等级等字段。这个文件可以直接导入 Excel也可以作为后续 Web 系统的数据源。第二个是班级级汇总 JSONoutputs/attention_summary.json它包含学生数量、平均专注度、活跃率、各行为数量和课堂提醒信息。Web 前端或后台接口可以直接读取这个 JSON。第三个是 Markdown 报告outputs/attention_report.md它把统计结果整理成可读文本适合用于项目报告、课程设计材料和博客补充说明。十一、为什么使用规则层而不是直接训练行为分类模型很多人看到课堂行为识别这个题目会直接想到训练一个分类模型。但对于一个可交付的课程项目来说直接训练行为模型有几个问题。首先课堂行为数据集并不容易获得。真实课堂图像涉及学生隐私采集、标注、发布都需要严格授权。即便拿到数据也要标注“举手、低头、趴桌、听课”等类别成本较高。其次行为标签本身存在歧义。低头可能是写字、看书、看手机也可能是短暂走神抬头也不一定代表认真听讲。因此如果没有多帧上下文、桌面物品信息和课堂任务信息单靠一张图训练出来的模型很容易误判。再次课程设计或 CSDN 实战项目更需要可解释性。规则层虽然简单但读者可以明确知道每个判断来自哪一个关键点关系。项目评审也更容易理解技术路线。所以本项目采用“YOLO-Pose 提取关键点 规则层判断行为”的方案。这个方案不是最终形态但非常适合作为可运行项目的第一版。后续如果有真实数据可以在此基础上扩展为机器学习分类器例如用关键点坐标、角度、距离比例作为特征训练 RandomForest、XGBoost 或轻量 MLP如果输入是视频还可以使用 LSTM、TCN 或 Transformer 建模时间序列。十二、隐私与应用边界课堂行为识别属于敏感应用方向因为它涉及学生图像和学习状态判断。项目在设计时做了几个边界控制。第一项目不做人脸识别。系统不保存人脸特征不建立身份库也不进行学生身份匹配。内置样例只包含匿名姿态关键点。第二项目输出的是“姿态行为标签”不是“学习态度结论”。例如低头书写和低头走神在单帧姿态上可能非常相似系统不能直接判断学生是否认真。博客和 README 中都明确强调结果只能作为辅助观察。第三真实环境使用必须获得授权。课堂视频、摄像头和学生图像都应遵守学校、家长和学生的知情同意要求不建议用于隐蔽监控。第四不建议把单帧结果用于惩罚性评价。更合理的方式是做班级级趋势分析比如课堂互动是否增加、长时间趴桌人数是否异常、教师调整节奏后活跃度是否变化等。这些边界并不会削弱项目价值反而能让项目更专业。一个负责任的 AI 项目不应该只关注模型准确率也要关注使用场景和社会影响。十三、如何二次开发如果要把这个项目继续扩展可以从几个方向入手。第一个方向是接入真实视频。当前项目以单帧为主真实课堂视频可以按固定帧率抽帧例如每秒分析 1 帧或每 5 秒分析 1 帧。对每一帧生成学生级结果后再按时间窗口做平滑统计。这样可以减少单帧误判。第二个方向是加入跟踪算法。YOLO-Pose 可以检测每一帧的人体但不同帧中的学生编号可能不稳定。如果接入 ByteTrack、BoT-SORT 或其他跟踪方法可以让同一个学生在视频中保持相对稳定的 ID从而统计个人姿态变化轨迹。真实教育场景要慎重处理个人 ID建议默认使用匿名临时编号。第三个方向是训练行为分类器。可以把关键点归一化后提取特征例如头肩比例、手腕高度、肘部角度、躯干倾斜角、关键点置信度等再训练一个分类模型。相比直接用原图训练关键点特征更轻量也更保护隐私。第四个方向是做成 Web 后台。当前项目已经提供了可选app.pyStreamlit 页面。如果要做成更完整的系统可以用 FastAPI 提供推理接口用 Vue 或 React 做前端管理页面用 SQLite 或 MySQL 保存分析记录。这样就可以形成“课堂视频上传、自动分析、报告下载、历史记录查询”的完整系统。第五个方向是接入项目报告和软著材料。由于项目结构清晰包含配置文件、主程序、模块代码、报告输出和截图很适合进一步整理成课程设计报告、项目展示 PPT 或软件著作权说明书。十四、常见问题1. 没有 GPU 能运行吗可以。离线 demo 模式只需要基础 Python 依赖不需要 GPU。真实 YOLO-Pose 推理也可以在 CPU 上运行只是速度会慢一些。2. 没有权重能运行吗可以。直接运行python main.py --mode demo即可。项目会读取内置匿名关键点样例生成完整结果。3. 为什么项目不直接打包权重YOLO-Pose 权重文件通常比较大不适合放进轻量项目压缩包。项目已经在weights/README_WEIGHTS.md中写明下载地址、保存路径和检查方式。4. 可以换成 YOLO26-Pose 吗可以。只要 Ultralytics 输出的关键点格式仍能转成[x, y, confidence]的 COCO-17 结构项目上层分析模块基本不需要改动。5. 可以识别玩手机吗只靠人体关键点很难稳定判断玩手机因为手机是小目标需要目标检测模型配合。后续可以增加一个手机检测模型如果手腕接近头部或桌面同时检测到手机再判断为疑似看手机。6. 可以直接判断课堂纪律吗不建议。课堂纪律和学习状态不是单帧姿态能完全决定的。本项目输出的是姿态行为统计适合辅助观察和项目演示不应作为唯一评价依据。十五、总结本文完成了一个“基于 YOLO-Pose 的课堂学生行为识别与专注度统计系统”。项目不是简单调用模型画框而是围绕课堂场景做了完整工程设计姿态推理、关键点格式统一、行为规则判断、专注度统计、可视化展示、CSV/JSON/Markdown 报告导出、权重说明和可选 Web 页面。项目默认可以离线运行即使没有模型权重也能生成完整结果图适合 CSDN 技术博客、课程设计、AI 项目实战和项目实践交付。从技术角度看这个项目展示了姿态估计模型在教育场景中的一种典型用法。YOLO-Pose 提供人体关键点规则层负责把关键点转成行为标签可视化模块负责把结果变成可展示的项目成果。后续可以继续扩展视频跟踪、多帧平滑、真实数据微调和 Web 后台系统。从应用角度看课堂行为识别必须注意隐私与边界。系统不做人脸识别不建立身份库不把单帧姿态等同于学习态度只把它作为课堂观察辅助和算法演示。这样的定位更适合教学项目也更符合负责任 AI 的基本要求。参考资料Ultralytics Pose Estimation 文档https://docs.ultralytics.com/tasks/pose/Ultralytics YOLO11 文档https://docs.ultralytics.com/models/yolo11/Ultralytics COCO-Pose 数据集说明https://docs.ultralytics.com/datasets/pose/coco/Ultralytics assetshttps://github.com/ultralytics/assetsCOCO 数据集官网https://cocodataset.org/Wikimedia Commons 课堂场景图https://commons.wikimedia.org/wiki/File:A_classroom_of_students_(7138907393).jpg
基于 YOLO-Pose 的课堂学生行为识别与专注度统计系统实战
摘要课堂学生行为识别是计算机视觉项目里非常适合做“项目实战交付”的方向。相比普通的目标检测项目它不仅要检测到人还要进一步理解人的姿态和动作例如学生是否抬头听课、是否举手互动、是否低头书写、是否疑似趴桌。传统目标检测只能给出“人”的检测框很难表达手腕、肩膀、头部之间的位置关系而 YOLO-Pose 这类姿态估计模型可以直接输出人体关键点天然适合做课堂姿态分析、课堂互动统计、教学状态观察和课程设计展示。本文围绕一个完整可运行项目展开项目名称为“基于 YOLO-Pose 的课堂学生行为识别与专注度统计系统”。系统使用 COCO-17 人体关键点作为姿态表达方式上层通过透明几何规则判断课堂行为再根据行为类别计算学生级专注度得分和班级级统计结果。项目同时考虑到实际运行门槛如果本地存在yolov8n-pose.pt权重可以使用 Ultralytics YOLO-Pose 对真实图片或视频进行姿态推理如果运行机器没有权重、不能联网或没有 GPU系统会自动切换到内置匿名关键点样例保证直接运行主程序也能看到完整输出结果。本文适合用于 CSDN 技术博客、课程设计、项目实战展示、AI 项目交付、视觉检测项目二次开发。文章会从项目背景、技术路线、系统架构、核心代码、运行方式、结果分析、隐私边界和扩展方向几个方面展开最后给出完整项目目录、运行截图和输出文件说明。关键词YOLO-Pose、YOLO11、姿态估计、课堂行为识别、学生专注度统计、人体关键点、COCO-17、计算机视觉项目、Python 项目实战、CSDN 源码项目一、为什么选择课堂学生行为识别这个项目很多视觉检测项目只停留在“检测一个物体”的阶段例如检测安全帽、车辆、垃圾、裂缝、零件缺陷等。这类项目适合入门但如果想把项目写成更有展示感的技术博客就需要进一步做“检测结果之后的业务分析”。课堂学生行为识别正好符合这个特点。它的输入可以是一张课堂图片、一段课堂视频或者摄像头画面中间层是人体姿态关键点输出层不是简单画框而是学生级行为标签、班级级专注度、行为分布图和分析报告。这个项目的价值主要体现在三个方面。第一它把深度学习模型和规则分析结合起来。YOLO-Pose 负责从图像中提取人体关键点规则模块负责把关键点转化为行为标签。这样既能体现深度学习推理也能体现业务逻辑设计不会让项目只停留在调用模型 API。第二它适合做完整工程交付。项目可以包含命令行程序、可选 Web 页面、配置文件、权重说明、示例数据、可视化图片、CSV 报表、Markdown 分析报告和博客文章。对于课程设计或项目实践来说这种结构比单个脚本更完整。第三它有明确的扩展空间。基础版本可以用单帧规则判断进阶版本可以加入视频跟踪、多帧行为平滑、学生轨迹统计、课堂时间轴分析、教师互动事件识别甚至可以接入 FastAPI 或 Streamlit 做成后台系统。当然这个项目也有明显边界。姿态识别只能根据身体关键点推断“可观察行为”不能直接判断学生真实心理状态。学生低头可能是在做笔记也可能是在走神学生抬头也不一定代表完全专注。因此本项目更适合作为课堂观察辅助工具和 AI 项目演示不应该被用于隐蔽监控、个体惩罚或替代教师判断。真实课堂画面中学生姿态、遮挡、桌椅位置和拍摄角度都会影响关键点质量。项目的重点不是简单识别一个动作而是把可观察姿态转成可解释、可复核的统计结果。二、技术调研与方案选择本项目参考了 Ultralytics YOLO-Pose 的技术路线。Ultralytics 的 Pose Estimation 文档说明姿态估计任务会输出目标关键点的坐标和置信度这些关键点通常代表人体关节或其他具有区分度的位置。官方文档也提到YOLO 的姿态模型使用-pose后缀默认模型使用 COCO keypoints 数据集训练能够输出 17 个人体关键点。对于课堂行为识别来说这 17 个关键点已经足以覆盖头部、肩部、肘部、手腕、髋部、膝盖和脚踝等主要部位。COCO-Pose 数据集说明中也明确提到COCO-Pose 扩展了 COCO Keypoints 2017 标注包含人体 17 个关键点可用于人体姿态估计任务。项目中采用 COCO-17 的原因很直接它是主流姿态估计项目中最常见的格式之一Ultralytics YOLO-Pose 输出也与这个格式兼容后续如果要接训练集、标注工具或模型微调会比较方便。项目没有一开始就强制用户必须下载权重和安装 GPU 环境而是设计了两条路线第一条是完整 YOLO-Pose 路线。用户准备yolov8n-pose.pt权重后系统加载本地权重对真实图片或视频做姿态推理再进入行为分析模块。这个路线适合展示真实课堂图片、监控截帧或视频片段。第二条是离线 demo 路线。项目内置一个demo_data/classroom_pose_sample.json文件里面保存了匿名模拟的 COCO-17 关键点。用户没有模型权重时主程序仍然能运行仍然会生成姿态图、行为分布图、专注度柱状图和分析报告。这个设计非常重要因为很多项目交付环境无法联网也不一定有 GPU。如果一个项目必须先下载大模型才能运行用户体验会明显下降。从工程角度看真实项目通常不应该把模型推理和业务判断写死在一个脚本里。本项目把 YOLO-Pose 推理、姿态规则判断、结果可视化、报告导出拆成独立模块方便后续二次开发。三、系统整体架构系统整体架构如下图所示。输入端可以是真实图片、视频或内置关键点样例中间层由姿态推理模块输出 COCO-17 关键点规则层根据头部、肩部、手腕和躯干之间的几何关系判断课堂行为输出层生成可视化图片、统计图、CSV、JSON 和 Markdown 报告。这个项目的核心不是“模型越大越好”而是把模型输出变成可解释的业务结果。YOLO-Pose 检测到一个人以后会给出 17 个关键点。仅凭这些关键点人类观察者其实已经可以看出很多姿态信息手腕在肩膀上方多数情况下表示举手头部明显靠近桌面可能是趴桌头部略低于正常位置可能是低头书写或阅读头部稳定在肩膀上方可能是正常听课。项目把这些观察转成规则就能形成一个可运行、可解释、可修改的课堂行为识别系统。流程可以概括为七步加载输入源、进行姿态检测或读取关键点样例、规范化关键点格式、计算姿态几何指标、判断学生行为、聚合班级统计结果、导出可视化和报告。这样设计的好处是每一步都可以独立替换。例如后续想把规则判断换成机器学习分类器只需要修改behavior_analyzer.py想把输出接入 Web 页面只需要读取outputs/attention_summary.json和outputs/classroom_behavior_results.csv想把 YOLOv8n-pose 换成 YOLO11n-pose 或其他姿态模型只要保证输出仍然能转成 COCO-17 格式即可。四、项目目录结构说明项目文件结构如下。核心目录说明如下classroom_yolo_pose_attention_system/ ├── blog.md ├── README.md ├── requirements.txt ├── requirements_yolo.txt ├── main.py ├── run_demo.py ├── app.py ├── run.bat ├── run.sh ├── src/ │ ├── data_loader.py │ ├── keypoints.py │ ├── pose_engine.py │ ├── behavior_analyzer.py │ ├── visualizer.py │ └── report_writer.py ├── configs/ │ └── config.json ├── demo_data/ │ └── classroom_pose_sample.json ├── weights/ │ └── README_WEIGHTS.md ├── images/ │ ├── figures/ │ └── results/ ├── outputs/ └── docs/main.py是主入口负责串联配置加载、姿态推理、行为分析、可视化和报告导出。用户只要运行python main.py --mode demo就可以看到结果。src/pose_engine.py是姿态推理模块。它优先尝试加载本地 YOLO-Pose 权重如果没有权重或用户指定 demo 模式就读取内置匿名关键点。这样既保留真实推理能力又保证项目交付时能直接运行。src/behavior_analyzer.py是行为规则模块。它接收每个学生的 17 个关键点计算头肩距离比例、手腕相对肩膀高度、关键点平均置信度等指标再输出行为标签和专注度分数。src/visualizer.py负责绘图包括课堂姿态标注图、行为分布图、学生专注度柱状图和命令行运行截图。对于技术博客来说结果图非常重要因为读者需要直观看到项目不是停留在代码层面而是真的跑出了结果。weights/README_WEIGHTS.md是权重说明文件写清楚模型名称、下载地址、保存路径和运行前检查方式。项目已使用轻量yolov8n-pose.pt完成真实图片推理验证如果分享平台限制大文件也可以只保留说明文件并让读者按文档重新下载权重。五、COCO-17 关键点与课堂行为规则COCO-17 人体关键点包含以下部位0 nose 1 left_eye 2 right_eye 3 left_ear 4 right_ear 5 left_shoulder 6 right_shoulder 7 left_elbow 8 right_elbow 9 left_wrist 10 right_wrist 11 left_hip 12 right_hip 13 left_knee 14 right_knee 15 left_ankle 16 right_ankle对于课堂行为识别来说最关键的是头部、肩部、手腕和髋部。项目没有直接使用所有关键点进行复杂建模而是先提取几个容易解释的几何指标。第一个指标是头肩比例。图像坐标中y 轴向下增长。正常坐姿下鼻尖应该明显位于肩膀上方所以“鼻尖 y 坐标减去肩部中点 y 坐标”通常是负数。为了让不同身高、不同画面尺度下的结果具有可比性项目用肩部中点到髋部中点的距离作为躯干长度对这个差值做归一化。这个指标在代码中叫head_ratio。当head_ratio非常小例如 -0.6 左右说明头部明显在肩膀上方通常是正常听课当它接近 0说明头部已经靠近肩部高度可能是趴桌或睡觉当它介于两者之间则可能是低头书写或阅读。第二个指标是手腕相对肩膀高度。如果左手腕或右手腕的 y 坐标明显小于肩膀 y 坐标说明手腕在画面中更靠上这通常对应举手动作。项目没有要求手腕一定要达到头顶以上因为课堂画面中经常有遮挡、角度变化和坐姿差异只要手腕高于肩部一定比例就可以判断为举手互动。第三个指标是姿态质量。每个关键点都有置信度如果平均置信度太低或者关键部位缺失系统不会强行给出明确行为而是标记为“姿态不确定”。这比强行分类更稳妥也更符合实际项目要求。当前项目支持五类行为attentive_listening 正常听课 active_raising_hand 举手互动 head_down_writing 低头书写/阅读 desk_sleeping 疑似趴桌/睡觉 uncertain 姿态不确定每类行为对应一个专注度得分。正常听课设置为 88 分举手互动设置为 95 分低头书写/阅读设置为 70 分疑似趴桌/睡觉设置为 25 分姿态不确定设置为 50 分。这里的分数不是教育评价标准而是为了项目演示和统计可视化而设计的指标。实际应用时建议根据课堂场景、年级、课程类型和教师需求重新调整。六、核心代码讲解姿态推理模块姿态推理模块在src/pose_engine.py中。它的设计重点是“双模式运行”有权重时走 YOLO没有权重时走 demo。这样项目不会因为缺少.pt文件而无法启动。核心逻辑如下class PoseEngine: def __init__(self, weight_pathweights/yolov8n-pose.pt, confidence_threshold0.35, force_demoFalse): self.weight_path Path(weight_path) self.confidence_threshold confidence_threshold self.force_demo force_demo def _try_load_yolo(self): if self.force_demo: return False if not self.weight_path.exists(): return False from ultralytics import YOLO self._model YOLO(str(self.weight_path)) return True这段代码先判断是否强制 demo再判断权重文件是否存在。只有本地确实存在权重文件时才尝试导入 Ultralytics 并加载模型。这样可以避免用户在没有安装ultralytics的环境下运行 demo 时报错。如果加载 YOLO 成功系统调用模型进行推理并把 Ultralytics 返回的 keypoints 转成统一格式kpts_np keypoints.data.cpu().numpy() boxes_np boxes.xyxy.cpu().numpy() for idx, kpts in enumerate(kpts_np): detections.append({ student_id: fS{idx 1:02d}, bbox: boxes_np[idx].tolist(), keypoints: [[float(v) for v in row] for row in kpts.tolist()], confidence: float(conf_np[idx]), })如果加载 YOLO 失败系统读取demo_data/classroom_pose_sample.json并返回同样结构的数据。这样后续模块不需要关心数据来自真实 YOLO 还是内置关键点样例统一按detections处理即可。七、核心代码讲解行为分析模块行为分析模块在src/behavior_analyzer.py中。核心函数是classify_one它输入一个学生的关键点输出行为类别和中间指标。首先计算肩部中点、髋部中点和躯干长度shoulder_mid midpoint(left_shoulder, right_shoulder) hip_mid midpoint(left_hip, right_hip) torso_len max(distance(shoulder_mid, hip_mid), 1.0) head_ratio (float(nose[1]) - shoulder_mid[1]) / torso_len这里使用torso_len做归一化非常关键。如果只看像素差不同远近位置的学生会产生明显偏差。坐在后排的学生身体尺寸小头肩像素差也小坐在前排的学生身体尺寸大头肩像素差也大。归一化后项目判断的是相对姿态而不是绝对像素。然后判断是否举手left_hand_raised ( left_wrist[2] low_conf and left_wrist[1] left_shoulder[1] - torso_len * wrist_raise_ratio ) right_hand_raised ( right_wrist[2] low_conf and right_wrist[1] right_shoulder[1] - torso_len * wrist_raise_ratio )由于图像坐标 y 轴向下手腕 y 坐标越小表示越靠上。只要手腕明显高于肩膀就判断为举手互动。最后根据规则输出行为if left_hand_raised or right_hand_raised: return active_raising_hand, metrics if head_ratio desk_sleep_ratio: return desk_sleeping, metrics if head_ratio head_down_ratio: return head_down_writing, metrics return attentive_listening, metrics这套规则有两个优点。第一容易理解。读者可以直接看懂为什么系统判断某个学生是低头或举手。第二容易修改。比如某个课堂角度下低头阈值太敏感只需要调整configs/config.json中的阈值不需要重新训练模型。八、运行项目项目默认可以离线运行。进入项目目录后安装基础依赖pip install -r requirements.txt运行 demopython main.py --mode demo如果在 Windows 上也可以直接双击或运行run.batLinux 或 macOS 可以运行bash run.sh如果想使用真实 YOLO-Pose请先安装完整依赖pip install -r requirements_yolo.txt然后准备权重yolov8n-pose.pt放到weights/yolov8n-pose.pt真实图片推理命令如下python main.py --mode auto --source path/to/classroom.jpg --weights weights/yolov8n-pose.pt如果需要一个简单展示页面可以运行streamlit run app.py九、运行效果展示本项目已经使用真实课堂图片运行主程序并在images/results/中保存了结果图片。输入图片来自 Wikimedia Commons 的课堂场景推理权重为本地yolov8n-pose.pt。从运行结果可以看到系统识别了 6 个学生姿态平均专注度为 76.0活跃率为 0.333。行为分布中包含正常听课和低头书写/阅读两类说明规则层已经基于真实 YOLO-Pose 关键点完成了学生级行为判断和班级级统计。课堂姿态标注结果如下。图中每个学生都用骨架线和关键点进行标注同时显示学生编号、行为类别和得分。这里的关键点并不包含人脸身份信息只包含匿名坐标因此更适合作为项目演示数据。真实使用时仍然要注意图像采集授权和隐私保护。行为分布图如下。行为分布图可以帮助教师或项目评审快速理解整堂课的状态。例如举手人数较多说明课堂互动较积极低头人数较多不一定代表不专注也可能是书写任务较多趴桌人数较多则可能需要关注课堂节奏或学生状态。学生级专注度得分图如下。柱状图展示了每个学生的得分。这里的分数不是绝对评价而是用于项目展示和辅助观察。实际落地时可以把单帧得分扩展为多帧平均分或者按时间窗口统计比如每 5 分钟输出一次课堂活跃度曲线这样会比单帧判断更稳健。十、输出文件说明运行后系统会在outputs/目录生成三个主要文件。第一个是学生级 CSVoutputs/classroom_behavior_results.csv它包含学生编号、行为类别、中文行为名称、专注度分数、姿态质量、头肩比例、是否举手和风险等级等字段。这个文件可以直接导入 Excel也可以作为后续 Web 系统的数据源。第二个是班级级汇总 JSONoutputs/attention_summary.json它包含学生数量、平均专注度、活跃率、各行为数量和课堂提醒信息。Web 前端或后台接口可以直接读取这个 JSON。第三个是 Markdown 报告outputs/attention_report.md它把统计结果整理成可读文本适合用于项目报告、课程设计材料和博客补充说明。十一、为什么使用规则层而不是直接训练行为分类模型很多人看到课堂行为识别这个题目会直接想到训练一个分类模型。但对于一个可交付的课程项目来说直接训练行为模型有几个问题。首先课堂行为数据集并不容易获得。真实课堂图像涉及学生隐私采集、标注、发布都需要严格授权。即便拿到数据也要标注“举手、低头、趴桌、听课”等类别成本较高。其次行为标签本身存在歧义。低头可能是写字、看书、看手机也可能是短暂走神抬头也不一定代表认真听讲。因此如果没有多帧上下文、桌面物品信息和课堂任务信息单靠一张图训练出来的模型很容易误判。再次课程设计或 CSDN 实战项目更需要可解释性。规则层虽然简单但读者可以明确知道每个判断来自哪一个关键点关系。项目评审也更容易理解技术路线。所以本项目采用“YOLO-Pose 提取关键点 规则层判断行为”的方案。这个方案不是最终形态但非常适合作为可运行项目的第一版。后续如果有真实数据可以在此基础上扩展为机器学习分类器例如用关键点坐标、角度、距离比例作为特征训练 RandomForest、XGBoost 或轻量 MLP如果输入是视频还可以使用 LSTM、TCN 或 Transformer 建模时间序列。十二、隐私与应用边界课堂行为识别属于敏感应用方向因为它涉及学生图像和学习状态判断。项目在设计时做了几个边界控制。第一项目不做人脸识别。系统不保存人脸特征不建立身份库也不进行学生身份匹配。内置样例只包含匿名姿态关键点。第二项目输出的是“姿态行为标签”不是“学习态度结论”。例如低头书写和低头走神在单帧姿态上可能非常相似系统不能直接判断学生是否认真。博客和 README 中都明确强调结果只能作为辅助观察。第三真实环境使用必须获得授权。课堂视频、摄像头和学生图像都应遵守学校、家长和学生的知情同意要求不建议用于隐蔽监控。第四不建议把单帧结果用于惩罚性评价。更合理的方式是做班级级趋势分析比如课堂互动是否增加、长时间趴桌人数是否异常、教师调整节奏后活跃度是否变化等。这些边界并不会削弱项目价值反而能让项目更专业。一个负责任的 AI 项目不应该只关注模型准确率也要关注使用场景和社会影响。十三、如何二次开发如果要把这个项目继续扩展可以从几个方向入手。第一个方向是接入真实视频。当前项目以单帧为主真实课堂视频可以按固定帧率抽帧例如每秒分析 1 帧或每 5 秒分析 1 帧。对每一帧生成学生级结果后再按时间窗口做平滑统计。这样可以减少单帧误判。第二个方向是加入跟踪算法。YOLO-Pose 可以检测每一帧的人体但不同帧中的学生编号可能不稳定。如果接入 ByteTrack、BoT-SORT 或其他跟踪方法可以让同一个学生在视频中保持相对稳定的 ID从而统计个人姿态变化轨迹。真实教育场景要慎重处理个人 ID建议默认使用匿名临时编号。第三个方向是训练行为分类器。可以把关键点归一化后提取特征例如头肩比例、手腕高度、肘部角度、躯干倾斜角、关键点置信度等再训练一个分类模型。相比直接用原图训练关键点特征更轻量也更保护隐私。第四个方向是做成 Web 后台。当前项目已经提供了可选app.pyStreamlit 页面。如果要做成更完整的系统可以用 FastAPI 提供推理接口用 Vue 或 React 做前端管理页面用 SQLite 或 MySQL 保存分析记录。这样就可以形成“课堂视频上传、自动分析、报告下载、历史记录查询”的完整系统。第五个方向是接入项目报告和软著材料。由于项目结构清晰包含配置文件、主程序、模块代码、报告输出和截图很适合进一步整理成课程设计报告、项目展示 PPT 或软件著作权说明书。十四、常见问题1. 没有 GPU 能运行吗可以。离线 demo 模式只需要基础 Python 依赖不需要 GPU。真实 YOLO-Pose 推理也可以在 CPU 上运行只是速度会慢一些。2. 没有权重能运行吗可以。直接运行python main.py --mode demo即可。项目会读取内置匿名关键点样例生成完整结果。3. 为什么项目不直接打包权重YOLO-Pose 权重文件通常比较大不适合放进轻量项目压缩包。项目已经在weights/README_WEIGHTS.md中写明下载地址、保存路径和检查方式。4. 可以换成 YOLO26-Pose 吗可以。只要 Ultralytics 输出的关键点格式仍能转成[x, y, confidence]的 COCO-17 结构项目上层分析模块基本不需要改动。5. 可以识别玩手机吗只靠人体关键点很难稳定判断玩手机因为手机是小目标需要目标检测模型配合。后续可以增加一个手机检测模型如果手腕接近头部或桌面同时检测到手机再判断为疑似看手机。6. 可以直接判断课堂纪律吗不建议。课堂纪律和学习状态不是单帧姿态能完全决定的。本项目输出的是姿态行为统计适合辅助观察和项目演示不应作为唯一评价依据。十五、总结本文完成了一个“基于 YOLO-Pose 的课堂学生行为识别与专注度统计系统”。项目不是简单调用模型画框而是围绕课堂场景做了完整工程设计姿态推理、关键点格式统一、行为规则判断、专注度统计、可视化展示、CSV/JSON/Markdown 报告导出、权重说明和可选 Web 页面。项目默认可以离线运行即使没有模型权重也能生成完整结果图适合 CSDN 技术博客、课程设计、AI 项目实战和项目实践交付。从技术角度看这个项目展示了姿态估计模型在教育场景中的一种典型用法。YOLO-Pose 提供人体关键点规则层负责把关键点转成行为标签可视化模块负责把结果变成可展示的项目成果。后续可以继续扩展视频跟踪、多帧平滑、真实数据微调和 Web 后台系统。从应用角度看课堂行为识别必须注意隐私与边界。系统不做人脸识别不建立身份库不把单帧姿态等同于学习态度只把它作为课堂观察辅助和算法演示。这样的定位更适合教学项目也更符合负责任 AI 的基本要求。参考资料Ultralytics Pose Estimation 文档https://docs.ultralytics.com/tasks/pose/Ultralytics YOLO11 文档https://docs.ultralytics.com/models/yolo11/Ultralytics COCO-Pose 数据集说明https://docs.ultralytics.com/datasets/pose/coco/Ultralytics assetshttps://github.com/ultralytics/assetsCOCO 数据集官网https://cocodataset.org/Wikimedia Commons 课堂场景图https://commons.wikimedia.org/wiki/File:A_classroom_of_students_(7138907393).jpg