
简介基于YOLOv8的智慧教室人数统计应用完整项目包面向计算机视觉、深度学习方向的毕业设计与课程设计场景适合计算机、人工智能、通信、自动化等专业学生快速部署使用。项目代码全部测试通过运行即可输出结果能够生成核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果和标签分布图足以支撑毕业设计答辩中的效果展示与方案讲解。压缩包内共8个文件包含3个Python源码文件模型训练、视频检测、可视化界面、3个模型权重文件预训练权重与训练结果权重以及2个TXT说明文档整体大小约15.91MB目录结构清晰依据README即可快速启动训练或推理流程。目前已有59人学习下载适合需要直接复用完整项目来构建智慧教室演示系统、完成课程项目或进行二次开发的学习者。1. YOLOv8智慧教室人数统计拿到压缩包不代表跑得动先看它到底做了什么教室人数统计这个题目在毕设和课程设计里几乎是常青树但你如果真的下载过带“源码可视化界面完整数据集运行教程”的压缩包会发现真正的门槛根本不在YOLOv8训练而在环境配置那一刻。很多同学卡在第一步Python版本装错PyTorch和CUDA对不上解压完连demo.py都跑不起来还有一批人跑起来了却在答辩时说不清置信度阈值和mAP是怎么来的。标题里的这套方案之所以适合毕设不是因为它训练效果好而是它把检测、计数、界面和结果可视化串成了一条完整链路评审老师看重的不是你会调参而是你有没有把整条链路跑通并且能解释每个环节。适合谁呢适合那些想用最短时间交付一个能演示、能截图、能写论文的人。这篇文章就把这条链路从头拆到尾包括环境搭建、数据集处理、训练参数和那些只有踩过才会知道的坑。2. 先看懂YOLOv8的检测逻辑人数统计为什么很少用人脸检测2.1 教室人数统计的选型行人检测、头肩检测、人脸检测为什么优选YOLOv8见过不少课程设计第一反应是做人脸检测来计数理由是人脸好识别。但教室摄像头一般架在前上方或后上方从上往下看前排人脸是斜的后排人脸只有二三十个像素戴眼镜、低头、伏桌人脸检测的召回率会掉得非常难看。常见的替代方案有三类整身行人检测、头肩检测和人脸检测。整身行人检测在教室场景里受课桌遮挡太严重三个人并排坐检测框互相重叠NMS之后框会乱跳人脸检测则是漏检严重。实践下来最稳的是头肩检测——人坐着的时候头肩区域基本可见互相遮挡少框比例稳定而且标注头肩比标注整身轻松得多。YOLOv8在选型上的优势在于它把anchor-free和C2f结构做进了默认配置不需要像早期YOLO那样手动调anchor尺寸。对教室人数统计这种检测目标大小跨度大的场景无锚框的设计意味着后排小目标的召回表现比YOLOv5更稳不会因为锚框尺度设置不合理而出现系统性漏检。另外一个现实理由是生态Ultralytics把训练、验证、导出、推理封装成了一条命令行对毕设来说是省时间的决定因素。如果你做的是部署到RK3588这类边缘盒子YOLOv8导出ONNX再转RKNN的路径也是最成熟的那条。2.2 读懂yolov8网络结构图C2f、SPPF和解耦头分别卡在哪几层拿YOLOv8s为例它的结构图你会在很多博客里看到但大多数教程只画到“输入640、输出84”就没了。我一般会提醒你重点看三个模块C2f、SPPF和解耦头。C2f替代了YOLOv5里的C3它把输入分成两支一支直连另一支经过多个Bottleneck后再和直连拼接最后过卷积。C2f的深度参数在模型配置文件里叫d默认是1训练时如果把depth_multiple从0.33调到0.5感受野和参数量都会变小目标不一定更好但显存占用会上去。SPPF是空间金字塔池化作用是把不同尺度的特征融合让网络对大小不一的目标都能提取到信息。在人数统计场景前后排的人大小差异可能达到5倍以上SPPF输出的多尺度特征直接决定了后排小目标能不能被召回。解耦头是YOLOv8跟v5最大的区别分类和回归各自走一个分支。我在实操时会拿结构图跟训练输出的六条损失曲线对照着看cls_loss和dfl_loss是分类分支的反馈box_loss是回归分支的反馈。如果你的box_loss降得很低但cls_loss居高不下问题大概率出在类别标注错误而不是网络结构。2.3 看数据清单别只看图片train/val、labels与yaml到底怎么对齐拿到完整数据集的压缩包第一件事不是打开图片看标注画得准不准而是看目录结构是否满足YOLO训练的要求。最标准的布局是datasets下面分images和labels两个大目录各自再分train和val图片和标签文件名一一对应标签文件是txt每行格式为类别ID、归一化后的中心点x、中心点y、宽w、高h四个坐标值都在0到1之间。用这段命令先摸清目录结构再决定要不要自己改脚本tree datasets/ -L 2 head -n 5 datasets/labels/train/0001.txt这里head命令看的是标注文件前5行如果看到坐标值有大于1的说明标注没有归一化训练时YOLO会直接报错或强行截断这是最常见的翻车点之一。然后要看data.yaml它决定训练器去哪里找图片里面的path、train、val、names四项写错任何一个训练都会在第一步就失败。我把一个可用的yaml贴在下面作为对照模板path: ./datasets train: images/train val: images/val names: 0: person注意path写的是相对路径相对你执行训练命令时所在的目录。很多人把path写成绝对路径换台电脑就要改一次毕设答辩换机器演示时容易现场出丑。这里有一个实用习惯yaml文件和datasets目录放在同一个项目根目录下path写成./datasets这样不管项目放在哪个路径只要整体拷贝就不会失效。3. 环境搭建与首次启动GTX1660Ti跑yolov8先做算力取舍再动手3.1 GTX1660Ti跑yolov8的算力定位选YOLOv8n还是YOLOv8s在动手装环境之前先搞清楚你手里的显卡是什么水平不然装好了跑不动心态直接崩。GTX1660Ti是6GB显存的图灵架构卡放在今天跑YOLOv8s训练最大能承受的batch很小但推理完全够用。常见精度选择是想快速出演示效果用YOLOv8n权重只有6MB左右推理速度快CPU都能跑到可用的帧率想在论文里写更高一点的mAP用YOLOv8s显存占用约2GB6GB卡跑推理无压力。训练则要另说这个放到下一章重点展开。如果你手头连1660Ti都没有只有纯CPU也不是不能跑但训练就不要指望了。CPU跑推理一张640x640图片大约需要1到2秒做界面演示时可以接受做视频流实时计数就会很吃力。所以环境搭建前先运行下面这段命令确认基础环境python --version nvidia-smi看python版本要大版本不小于3.8看nvidia-smi的右上角CUDA Version这个数字只是驱动支持的上限不是已安装的CUDA版本。后面装PyTorch时要对照这个数字驱动太老而装了新版本PyTorch会报CUDA driver too old。3.2 环境隔离miniconda ultralytics就是后悔药的购买渠道见过太多人在系统Python里直接pip install ultralytics装到一半把OpenCV降级把numpy降级最后其他项目全炸了。装深度学习环境的第一原则是隔离用miniconda创建独立虚拟环境哪怕后面环境坏了删除重来也就几分钟的事这才是真正的后悔药。完整的安装命令如下conda create -n yolov8 python3.10 -y conda activate yolov8 pip install ultralytics opencv-python pillowPython版本选3.10是经过验证的稳妥选择3.11以上装某些老版本PyTorch会出现兼容警告3.8以下很多新库不再支持。ultralytics这个包会带上torch和torchvision但国内网络环境下载慢是常态我一般先用下面这行给pip换国内镜像源再安装pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ultralytics opencv-python pillow装完后不要急着跑训练先验证GPU对PyTorch是否可见这一步能帮你区分是环境问题还是代码问题import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果第二行输出True说明PyTorch和CUDA已经打通。如果输出False但nvidia-smi能识别显卡问题几乎100%出在装的PyTorch版本是非GPU版或与驱动不匹配。3.3 一行命令推理先出图后谈界面环境装好了先用命令行做一次最小推理验证模型权重能加载、图片能读入、检测能输出。命令行跑推理是排除问题最快的手段把“跑不起来”拆成“是环境问题还是代码问题”yolo predict modelyolov8n.pt sourcetest.jpg conf0.25 device0解释一下这里的逻辑model指定权重文件source指向待检测图片conf是置信度阈值device0表示使用第一张GPU卡CPU就把device改成cpu。第一次运行时yolov8n.pt会自动下载到当前目录如果下载失败常见做法是手动下载权重文件放到项目根目录再执行。运行结束后会在runs/detect目录下生成带标注结果图的输出文件打开看如果能正确框出人并标出置信度说明整条推理链路已经通了。3.4 可视化界面启动入口脚本、设备选择与灰屏排查压缩包里最显眼的通常是main.py或app.py这类可视化界面常见的是基于PyQt5或Tkinter封装里面集成了打开图片、打开摄像头、视频文件检测和人数统计曲线四个功能模块。先把界面整体结构用一张表理顺这样后面改代码时才知道去哪里改功能模块入口控件底层调用常见异常图片检测打开图片按钮YOLO.predict中文路径读不到文件摄像头计数打开摄像头按钮OpenCV VideoCapture摄像头编号错误或权限拦截视频检测选择视频按钮逐帧推理跟踪视频格式解码失败统计结果人数曲线标签计数值写入列表帧率过低导致曲线卡顿启动GUI前先确认界面依赖装全了很多压缩包默认只有代码和模型不会帮你装PyQt5。我的建议是先启动而不做任何操作看到窗口正常弹出再点功能按钮。如果窗口一闪而过看终端报错是缺模块还是端口冲突。摄像头打不开时先检查设备编号是0还是1笔记本自带的摄像头通常是0外接USB摄像头可能是1代码里对应位置一般在VideoCapture(0)这个参数上改。另一个高频坑是直接双击py文件运行时没有Python环境关联结果窗口闪退这类问题用命令行运行就能看到真实报错信息python main.py4. 用自己的数据集做训练从公开数据集到教室场景的落地路径4.1 数据集选型与VOC转YOLOCrowdHuman为什么不能直接硬套教室场景压缩包自带的完整数据集一般有两种来源一种是网上爬的教室监控截图另一种是公开数据集改造的。CrowdHuman是行人检测的经典数据集标注了人体框和头框在论文里拿来对比可以但它拍摄视角偏平视跟教室俯视视角差别很大直接用它训练出来的模型在教室场景里后排漏检率会明显偏高。真正接近教室场景的是CHD数据集或自己采集的教室图片其次是公开的行人头肩数据集。毕设项目里最常见的操作是拿公开数据集做预训练再用手里的几百张教室图片做微调。如果你的数据集不是YOLO格式而是VOC的xml标注就涉及格式转换。下面这段脚本完成VOC转YOLO的核心工作import xml.etree.ElementTree as ET def voc_to_yolo(xml_file, class_names): tree ET.parse(xml_file) root tree.getroot() size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) boxes [] for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue cls_id class_names.index(name) bndbox obj.find(bndbox) x1 float(bndbox.find(xmin).text) y1 float(bndbox.find(ymin).text) x2 float(bndbox.find(xmax).text) y2 float(bndbox.find(ymax).text) cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h boxes.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) return \n.join(boxes)这个脚本里最容易被忽略的是归一化x2减x1之后必须除以图片真实宽高。有的xml里width和height没有正确读取转换后坐标全乱训练时loss直接爆炸。脚本里img_w和img_h一定要检查有没有读到0读不到就把图片本身的尺寸作为兜底值。还有一个坑YOLO格式要求坐标是归一化小数类别ID是整数两者不能混如果你在txt里写成了带引号的类别名训练器会报class index错误。4.2 训练前必查batch、imgsz、epochs与显存的关系数据集结构确认干净之后下一步要写训练命令。YOLOv8训练的核心参数只有几个但每个都跟显存挂钩设错了不是训练中断就是一夜白跑。最稳的训练命令模板如下yolo train datadatasets/data.yaml modelyolov8s.pt epochs100 imgsz640 batch8 device0逐项解释data指定自己的yaml文件model是预训练权重epochs是训练轮数毕设实际用100轮足够再多就是纯烧时间和显卡寿命。imgsz是训练分辨率640是默认值也是速度和精度的平衡点教室后排小目标多时可以尝试把imgsz提高到960但显存占用会从约2GB涨到约5GB1660Ti直接吃紧。batch是最需要小心的参数6GB显存跑YOLOv8sbatch设为8基本是极限显存不够时优先减小batch而不是降低imgsz。下面给出不同显存下的参数建议显存batch推荐分辨率备注6GB86401650Ti / 1660Ti8GB166402060 / 207012GB246403060 / 308016GB以上32640可尝试960但收益有限训练中途显存溢出时终端会报CUDA out of memory这时fold的参数不要调架构直接把batch减半再重跑。另一个容易被忽略的是warmup_epochs默认是3训练初期学习率从0线性升到设定值这个参数太小会导致模型训练早期不稳定但一般不用动。4.3 训完看损失函数曲线图玩坏的信号不是loss不降而是验证集曲线背离训练结束后Ultralytics会在runs/train目录下生成result.png和result.csv前者是可视化曲线图后者是全部指标的数值记录。看损失函数曲线图是评估训练健康度的核心手段重点看两个信号train的loss是否持续下降、val的loss是否还在降。如果train loss一路降但val loss在第30轮开始反弹说明过拟合了这时候你再往下训练只会让验证集表现更差。解决办法是早停或者干脆用30轮时的最佳权重。Ultralytics自动保存best.pt和last.ptbest.pt是按验证集指标选的所以如果自己重新训练加载权重时永远选best.pt而不是last.pt。看曲线时还有一个细节曲线图中表现出来的一组指标里包含mAP50和mAP50-95mAP50在0.8以上对于教室场景已经算不错mAP50-95通常只有0.5上下但不要只看这两个数字。实际需要回到图片上看推断效果把验证集里那些后排坐满人、部分遮挡的图单独跑一遍看框是否稳定。一张图里如果明明坐着8个人只检测出6个即便mAP数字再好看在答辩演示时也是减分项。我习惯用best.pt对三张有代表性的图做推理一张密集场景、一张后排小目标、一张无人的远景快速建立对模型上限的直观判断。5. 教室人数统计的典型踩坑与排查现象、原因、解决5.1 训练迟迟不开始一直是CPU在跑不少同学跑训练命令后发现GPU占用率是0%风扇不转loss数值从0.01开始慢慢爬这就是典型的PyTorch和CUDA版本匹配问题所致。现象就是训练不是跑不动而是每轮迭代的时间是GPU的几十倍。原因几乎都是pip安装时默认装了CPU版的PyTorch或者是CUDA工具包的版本和驱动不一致。解决方式分两步走第一步去PyTorch官网选择适合自己的版本举例来说CUDA 11.8的安装命令是pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118第二步回到上一章的torch.cuda.is_available()这条验证没过之前不进行下一步操作。5.2 标签坐标越界和中文路径训练到一半报错或训练完成后mAP一直为0翻开错误日志大概率看到了“assert labels shape”或者“all class id is incorrect”。原因分为两种一种是VOC转YOLO脚本归一化没做好坐标值大于1模型给出的预测框直接是乱的另一种是标签文件的类别ID超出了yaml里names的总数比如yaml里只有person一个类但标签文件某一行写了class_id1。解决方式是用脚本扫一遍所有标签文件把所有超过0到1范围的坐标值和不合法类别ID找出来直接剔除。同样要注意的是数据集全路径不要带中文OpenCV和ultralytics对中文路径的支持一直有玄学报错信息千奇百怪最简单的规避方式就是数据集文件夹改成纯英文。5.3 后排小目标漏检严重调置信度也没用界面能跑起来但检测结果里后排的人明显少于前排置信度阈值调到很低的0.1依然漏。这个坑的本质是目标尺寸和网络特征层不匹配。解决方向有三个第一个方向是提高推理分辨率用imgsz960预测小目标在输入图像中占更多像素召回率会明显提升代价是推理速度下降第二个方向是把后排区域单独裁剪放大也就是做safer辅助检测这个属于进阶玩法第三个方向是换更大的模型从YOLOv8s换成YOLOv8m但如果显卡只有6GB训练会变得很尴尬。对毕设来说最实用的还是第一条。5.4 摄像头打开黑屏或直接报错界面点击打开摄像头后窗口弹出来了但画面全黑或者终端报video capture error。多数情况是摄像头编号不对OpenCV读取摄像头的默认编号是0但有些笔记本的摄像头实际编号是1或者是2因为系统层面被其他应用占用了编号。排查时先写一行命令测试python -c import cv2; capcv2.VideoCapture(1); print(cap.isOpened())输出的数字是True还是False慢慢递增编号试到True为止再把代码里VideoCapture的参数改成这个数字。还有一类场景是虚拟机环境摄像头被宿主机占用VMware等虚拟机需要单独设置USB摄像头直通否则会一直提示打不开。6. 把“跑通”变成“可答辩”验证方法、导出ONNX和一条后路6.1 用PR曲线和混淆矩阵定义你的“能造的价值”答辩现场老师问你“效果怎么样”你不能只回答“跑得通”得给出可以自圆其说的验证指标。在runs/train目录下生成的PR_curve.png展示了模型在不同置信度下的精确率和召回率曲线曲线靠近右上角表示模型性能好。你需要从图上读出两个关键值mAP50和最佳置信度阈值。最佳置信度不是默认的0.25而是精确率和召回率曲线的交叉点附近。界面里的人数值需要稳定而这个阈值决定了一个模糊的人脸算不算人所以答辩前花10分钟确认这个值比临时调confidence参数靠谱得多。6.2 导出ONNX留一条CPU也能跑的活路一旦需要换电脑演示GPU不是标配把它们导出成ONNX格式就能用CPU跑推理了。导出命令非常简单yolo export modelruns/train/exp/weights/best.pt formatonnx imgsz640跑完后会在同目录生成一个best.onnx文件用OpenCV的dnn模块或onnxruntime加载它做推理CPU推理速度大概是每秒3到5帧的级别比原生预权重格式在GPU差很多但在没有显卡的老师办公室电脑上也能打开界面演示这就是那条救命的活路。onnxruntime加载的安装和读取代码是pip install onnxruntimeimport onnxruntime as ort session ort.InferenceSession(best.onnx)这里有个习惯要先交代导出前务必确认自己的模型经过了验证集测试而不是训练完就导出避免最后的演示状态被上课老师现场抽查时暴露一堆你没见过的错误框。我自己的做法是每次训练结束后固定做一次这个操作一方面给演示场景兜底一方面顺便写下推理速度的数字写进论文的部署章节里也有内容。希望这篇笔记帮到你至少能在熬夜调环境的路上少走几个来回。本文还有配套的精品资源点击获取