☰
基于YOLOv8的教室人数统计系统:从训练到边缘部署实战
2026/10/18 22:39:22 网站建设 项目流程

简介:这是一套面向计算机专业学生及开发者的YOLOv8教室人数统计系统源码,采用Ultralytics YOLOv8目标检测模型,可对教室内摄像头视频流中的人体进行实时识别与计数,适用于课堂考勤、智慧教室、自习室管理等场景。资源包共63个文件,压缩后仅2.99MB,以Python代码和YAML配置为主:28个py脚本涵盖模型训练、检测推理、数据标注转换等环节,19个yaml文件用于配置模型结构与训练参数,还包含Shell自动脚本、Docker部署文件、requirements依赖清单及README说明文档,方便在本地或容器环境中快速复现。系统实现思路清晰:读取视频流、送入YOLOv8模型检测人物、统计边界框数量、并在画面上叠加实时人数。源码预留了自定义数据集接口,可直接替换自己的教室场景数据重新训练,也可使用预训练权重直接运行检测。该资源已有369人浏览学习,代码结构完整紧凑,适合作为目标检测课程设计、毕业设计或人数统计项目的起始参考,能帮助读者快速理解YOLOv8从训练到部署的全流程。

1. 项目核心思路与整体设计

讲实话,教室人数统计这个需求,在高校、培训机构甚至大型公开课场景里一直是个刚需。考勤、课堂活跃度分析、自习室座位管理,都需要知道教室里到底有多少人。传统方案要么靠人力点名,要么用红外对射或者压力传感器,前者效率低,后者只能判断有没有人坐,根本分不清人和书包。这几年摄像头普及率上来了,基于视觉的目标检测方案就成了主流选择,而YOLOv8在其中确实是一个非常合适的切入点。

选YOLOv8而不选老牌的YOLOv5或其他检测模型,核心原因有几个。第一,YOLOv8的C2f结构在特征提取上比YOLOv5的C3更强,尤其在密集小目标的场景下,c2f的多分支梯度流可以让浅层特征更丰富,这对教室后排那些小尺寸人头来说很关键。第二,YOLOv8把Anchor-Based换成了Anchor-Free,省去了手动聚类anchor的环节,训练部署都更省心。第三,Ultralytics官方仓库维护得极其勤快,文档完善,预训练权重齐全,从训练到导出ONNX再到TensorRT,链路非常成熟。

这套系统的整体架构其实不复杂:一台固定机位的摄像头采集画面,送入训练好的YOLOv8模型做推理,检测出画面中的每个人,然后通过计数逻辑统计人数,再把结果推送到本地看板或数据库。难点从来不在于推一个模型上去跑demo,而在于如何让模型在教室这个场景下保持稳定的高准确率,如何在边缘设备上跑得动、跑得快,以及如何处理好重复计数和遮挡漏检这些细节问题。

适合来参考这篇内容的朋友,我大概分三类:一是拿这个题目做毕业设计的在校学生,需要完整的方案和代码思路;二是高校或培训机构的信息化老师,想低成本落地一个人数统计工具;三是对YOLOv8感兴趣、想通过一个实际项目把训练到部署全流程走通的开发者。不管你是哪一类,这篇文章会按我从零搭建这套系统的顺序,把每个环节的选型原因、参数细节和踩坑记录都讲清楚。

2. 硬件选型与环境配置实测

2.1 没有高端GPU也能跑——GTX 1660 Ti够不够用

很多新手一上来就被动不动“双卡3090”的训练配置吓住了,其实完全不必。我在开发阶段用的就是一块GTX 1660 Ti,6GB显存,跑YOLOv8n和YOLOv8s完全没有问题。这里要给一个明确的结论:如果你只是做推理部署,CPU都能跑,只是帧率感人;如果你要训练自己的数据集,6GB显存足够跑YOLOv8n和YOLOv8s,YOLOv8m会非常吃力。

具体来说,用COCO预训练权重做迁移学习的情况下,YOLOv8s、输入尺寸640x640、batch size设为8,显存占用大概在4.5GB到5.5GB之间,1660 Ti能扛住。如果你加了Mosaic增强和多尺度训练,显存会再涨一截,这时候需要把batch size降到4。我的建议是:训练阶段老老实实用YOLOv8n或YOLOv8s,把精力放在数据质量上,效果不会比强行上大模型差太多;推理阶段如果要做边缘部署,优先考虑模型剪枝和TensorRT量化。

2.2 环境配置踩坑记录

环境配置这块,网上教程五花八门,但其实核心就几步。我用的是Ubuntu 20.04 + CUDA 11.8 + PyTorch 2.0.1 + Ultralytics 8.0.x的组合,整体很稳。有个关键提示:一定不要直接pip install ultralytics就完事,建议先建虚拟环境,再按顺序装PyTorch、装依赖、装ultralytics。

我实际执行过的步骤供你参考:

# 创建虚拟环境 conda create -n yolov8 python=3.9 -y conda activate yolov8 # 安装PyTorch,注意对应CUDA版本 pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 安装ultralytics及依赖 pip install ultralytics==8.0.221 # 验证是否可用 python -c "from ultralytics import YOLO; print(YOLO('yolov8n.pt'))"

这里最容易出问题的坑是OpenCV和NumPy的版本冲突,症状是import ultralytics的时候直接报segmentation fault。后来我查了半天,发现是NumPy 1.24以上版本和旧版OpenCV的兼容性问题。解法也不难:把NumPy降到1.23.5。

还有一点容易被忽略的是,如果你用Windows而不是Linux,ultralytics在Windows上训练偶尔会报Dataloader的多进程相关错误,这时候把workers参数从默认的8改成2或者0就解决了。总之环境这块,只要版本不大乱来,基本半小时能搞定。

3. 数据集准备与模型训练实战

3.1 数据采集与标注要点

教室场景检测的标注目标,我强烈建议只标“人”,不要标“头”也不要去分“坐着/站着”。原因在于,YOLOv8检测的是目标的边界框,整人框在密集遮挡时框间重叠太严重,NMS一压就漏检;而只标头部的话,训练出来的模型在侧身、低头这些场景下又容易丢目标。整人框配合合理的标注策略,才是教室监控俯视或平视场景的最佳选择。

数据采集阶段,我的做法是:连续一周每天在固定机位录制不同时段的视频,提取关键帧做数据集。要覆盖这些情况:早课(学生刚入场,走动多)、上课中(基本静止)、下课(大规模移动)、阴天(光照低)、窗帘拉开(逆光)。最终累计了大概4000张有效图片,说实话这数量不算多,但胜在场景覆盖全。如果时间允许,凑到8000到10000张,模型的泛化能力会明显上一个台阶。

标注工具我用的LabelImg,标签类别就一个person。这里有个经验之谈:密集场景下标注的时候,能标多少标多少,千万别觉得后排小人看不清就跳过。漏标一个,训练的时候它就会成为误导样本,让模型学会忽略小人。我第一版模型漏检严重,就是吃了这个亏。

3.2 训练参数与数据增强配置

数据准备好后,关键的训练配置需要根据自己的硬件来定。我用YOLOv8s训练了200个epoch,输入尺寸640,batch size 8。优化器用SGD,初始学习率0.01,weight decay 0.0005,mosaic增强设置为1.0。

这里特别想聊一下数据增强。YOLOv8默认开Mosaic、MixUp、HSV扰动、随机翻转等,这些对教室场景非常友好。Mosaic把四张图拼在一起训练,小目标出现的频率变相增加,人头的检测能力会提升;HSV扰动让模型对教室不同时段的光照变化不那么敏感。但有个度的问题:如果数据集中小目标占比已经很高,Mosaic过度反而会让模型对正常尺寸的目标失衡。我实测在150个epoch之前把Mosaic关掉,只用flip和scale,能让模型收敛更稳定。

训练命令很简单:

yolo detect train data=classroom.yaml model=yolov8s.pt epochs=200 imgsz=640 batch=8 device=0

其中classroom.yaml里面指定训练集和验证集的路径,nc改为1(只有person一个类别)。跑起来之后,你会看到终端输出每个epoch的box_loss、cls_loss、dfl_loss,这些数值整体趋势应当是下降的。

3.3 损失函数曲线的判读技巧

很多新手训练完只看一个mAP,这其实是不够的。我建议拉开训练目录下的results.csv,用matplotlib把box_loss、cls_loss、dfl_loss三条曲线画出来,分别观察。box_loss下降说明边框回归在收敛;cls_loss下降说明分类在变准;如果cls_loss降到0.02左右就下不去了,那通常是数据标注的边界噪声导致,不用太焦虑。

有一个判断过拟合的实用技巧:当训练集的loss持续下降,但验证集的loss在第150个epoch附近开始回升,说明模型开始死记训练集了。这时候要么提前终止训练,要么回调early stopping,要么增加数据增强的强度。Ultralytics默认有早停机制,patience设为50,实测下来还是比较合理的。

另一个我踩过的坑是关于学习率和batch size的配合。同样的数据,batch size从8升到16的时候,学习率也应该适当调大,否则收敛速度明显变慢。如果你用Ultralytics默认的lr0=0.01,batch size翻倍的时候可以试着提到0.02。当然这只是经验值,具体还要看loss曲线的反馈。

4. 教室场景检测难点与针对性改进

4.1 密集遮挡与透视形变的破局思路

教室人数统计真正难的不是“看清人”,而是“看清后排的人”。一个常见的中型教室,后排的人头在画面里往往只有二三十个像素,这对检测器来说就是典型的小目标问题。很多初学者用YOLOv8s跑COCO预训练模型,结果后排漏检率30%以上,就开始怀疑模型不行。

其实问题出在特征层上。YOLOv8默认有P3、P4、P5三个检测层,分别负责小、中、大目标,小目标由P3层输出。如果你的场景里小目标特别多,可以考虑加一个P2检测头,专门负责更浅层的特征。具体做法是修改ultralytics的yaml结构,在backbone的P2位置引出一条分支。这个改动对密集小目标场景的提升非常明显,我的实测中,加上P2头后后排漏检率从35%降到了18%左右,代价是推理速度掉了约20%。如果部署的是RK3588这类边缘设备,这个代价需要认真权衡。

提到YOLOv8 head改进,网上讨论比较多的还有把Detect头里共享卷积换成解耦更彻底的结构,或者引入G-FPN的思想做跨层特征融合。这些改动对精度确实有正收益,但会显著增加代码改动量和调试成本。我的建议是:除非你的项目就是研究改进算法,否则不要在毕业设计或工程落地里过于激进地改网络结构,很多时候调好数据和增强策略,收益比改结构更大。

4.2 光照变化与摄像头视角的应对策略

教室另一个麻烦是光照。上午东侧的窗户阳光直射,画面里靠窗区域的对比度极高,逆光时人脸和衣服全部过曝;到了阴雨天,整个教室亮度又非常低。如果摄像头是固定的,这个问题会好很多,因为模型可以学到这个视角下不同光照的不同纹理,但前提是你的数据集里要有这些光照变化。

如果实测下来光照鲁棒性还是差,我建议在预处理环节加一步:推理时对输入帧做自适应直方图均衡化(CLAHE),限制对比度,让过曝区域的细节稍微拉回来一点。这步用OpenCV一行代码就能实现,对检测精度的影响在密集场景下通常是正向的。另外,摄像头安装位置对检测效果的影响极其关键。我这套系统最开始装在教室正前方黑板上方,结果后排全被前排同学挡住,漏检惨不忍睹;后来把机位调整到教室前侧天花板斜向下45度俯视,遮挡问题立刻缓解了大半。

5. 边缘部署:从RK3588到Jetson Orin Nano

5.1 模型导出与量化注意事项

模型训练好了,接下来要考虑部署。如果你只是在自己的电脑上跑个demo,YOLOv8的PyTorch模型直接推理就行,但想上RK3588或Jetson Orin Nano这类边缘设备,就不能直接用了。

RK3588用的NPU需要把模型转成RKNN格式。流程是:先导出ONNX,再用RKNN-Toolkit2把ONNX转成RKNN。我用的rknn-toolkit2版本是1.6.0,对应的NPU驱动版本要匹配,这一步坑很多。强烈建议先跑通自带的yolov8 demo,确认环境没问题,再转自己的模型。量化精度上,RK3588的NPU支持INT8量化,但YOLOv8对量化比较敏感,我的实测是:不量化FP16推理精度基本无损,INT8量化后mAP掉了大概2到3个点,但速度翻倍。教室里人数统计对帧率要求不高,我最终选择了FP16,稳定优先。

Jetson Orin Nano那边就友好很多。直接用TensorRT,Ultralytics官方提供了导出脚本,一条命令就能转成engine文件。命令大概是:

yolo export model=best.pt format=engine device=0

TensorRT会自动做层融合和精度校准,int8需要准备校准数据集,fp16则不需要。

5.2 计数逻辑:不要只数这一帧的人

部署模型之后,计数逻辑反而是我花时间最多的地方。如果每一帧都直接数检测框数量,会出现两个问题:一是误检带来的数量抖动,比如某个角落的阴影突然被识别成人,计数立刻多一个;二是同一时刻不同帧的检测结果不稳定,导致结果跳动,不适合直接展示给别人看。

我的方案是引入一个带有滞后性的“确认计数”机制。具体做法是:维护一个长度为30帧的滑动窗口,对于画面中的每个检测框,只有当它连续出现超过15帧才把对应位置标记为“有人”。检测框消失后,也要求连续消失超过10帧才把位置清空。这样一个人进出画面时会有一个平滑的过渡过程,不会出现数字疯狂跳动的情况。实际体验下来,这套逻辑在50人的教室里,计数误差能控制在2到3人以内。

如果你还需要统计“进入”和“离开”的人数,那就要引入跟踪算法了。YOLOv8官方集成了ByteTrack,可以在检测的基础上给每个目标一个稳定的ID,然后在画面中设定一条虚拟警戒线,判断目标ID的轨迹是从线上方跨到下方还是反向,分别累加进和出的数量。这一套逻辑做好,就从一个单纯的人数统计工具升级成了教室进出管理看板。

6. 常见问题速查与排错实录

下面整理了一份我在开发和调试过程中遇到的典型问题,按问题现象、可能原因和解决方案列出,方便你对照排查。

问题现象可能原因解决方案
训练到一半显存溢出(OOM)batch size过大,或输入尺寸过高把batch size从8降到4,或imgsz从640降到512
训练时loss不下降学习率过高或数据集标注错乱降低学习率到0.001,检查标签文件是否有空框、错误类别
模型对小尺寸人漏检严重小目标样本不足,或P3层特征不够增加后排小目标的标注、开启Mosaic增强、考虑加P2检测头
推理速度很慢模型过大,或未启用GPU推理换YOLOv8n、导出为TensorRT/ONNX,确认device参数正确配置
RKNN转换时报错RKNN-Toolkit2与NPU驱动版本不匹配严格按照官方文档组合版本,先跑通自带demo
计数结果反复跳动直接使用单帧检测结果按本文5.2节的滑动窗口确认机制处理
逆光场景漏检多训练数据光照变化不足增加逆光时段数据,推理前加CLAHE预处理

还有一个容易踩的坑,是数据集划分的比例。我在第一版训练时用了随机划分,结果某些时段的数据全部进了训练集,验证集和测试集都是另一个时段的,导致验证指标虚高,一上真实场景就露馅。正确的做法是按时间段划分:前四天数据做训练,第五天数据做验证。这样才能真实反映模型的泛化能力。

另外建议在训练结束后,用Ultralytics的val模式输出混淆矩阵和PR曲线,重点关注person这个类别在低置信度区间是否还有明显的召回上升空间。如果PR曲线尾部掉得厉害,可以考虑把推理时的conf阈值从默认0.25调低到0.15,代价是误检会多一些,需要和计数逻辑配合来过滤。

最后分享一个实操中的小技巧:在部署机上,把模型推理和计数展示拆成两个进程,用队列传数据。模型推理进程用多线程处理视频流,保证帧率稳定;展示进程只负责把计数结果绘制到画面并推送看板。这样即使展示端网络卡顿也不会拖垮推理进程。这套系统在RK3588上稳定跑了两周,CPU占用率不到30%,整体体验完全可用。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询