ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YOLOv8实战:电梯电动车禁入识别系统的数据集训练与部署

YOLOv8实战:电梯电动车禁入识别系统的数据集训练与部署 简介一套面向智慧社区场景的基于YOLOv8的电梯电动车禁入识别系统专为计算机相关专业如计科、人工智能、自动化、电子信息等在校生的毕业设计、课程设计及大作业需求打造可快速部署并完成电动车违规进入电梯的实时检测与提醒。资源包共8个文件覆盖3个Python脚本分别用于模型训练、可视化界面与视频检测、3个模型权重文件及2个txt说明文档整体压缩后仅15.91MB结构清晰便于按说明依次运行。目前已有42人学习下载项目代码均测试通过可直接使用。配套说明文档中已附环境配置与运行指引能帮助快速复现结果。配套内容包含完整数据集、可视化页面与部署教程运行后能输出核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果及标签分布图为毕设答辩提供可靠的数据支持也适合在此基础上继续改进或拓展检测功能同时适用于课程设计、大作业及初期立项演示等场景。1. 电梯电动车禁入识别为什么我从 YOLOv8 下手智慧社区里电动车进电梯是个老大难物业靠监控大屏人工盯着盯不了多久就漏。用视觉模型做禁入识别核心是把「电动车」这个目标从视频帧里稳定地抠出来再叠加报警逻辑。YOLOv8 在目标检测里属于「部署成本低、精度够用、生态齐全」的典型选择而且训练完直接能导出权重跑视频和摄像头。这套基于 YOLOv8 的智慧社区电梯电动车禁入识别系统把源码、完整数据集、可视化界面、部署说明都打包好了训练脚本、推理脚本、界面脚本分得清清楚楚适合做毕设、课设或者拿来入门深度学习目标检测。我拆完这套资源之后的感觉是它不是为了炫技写的而是真的考虑过「交到别人手里能跑起来」这件事。2. 数据集里到底有什么YOLO标注格式、类目分布与质量检查2.1 目录结构与 YOLO 标注格式拿到资源先别急着跑训练先看数据集。常见的组织方式是 dataset 目录下分 images 和 labels各自再拆分 train 和 val。images 里放的是原始图片labels 里放的是同名 .txt 标注文件二者靠文件名一一对应。打开一张图片的标注文件内容通常是这样的0 0.514648 0.382813 0.064453 0.113281 0 0.752344 0.759375 0.067187 0.090234一行五个数从左到右分别是类别索引、归一化后的中心点 x、中心点 y、归一化后的框宽、归一化后的框高。所谓归一化就是除以图片的原始宽高所以坐标范围都在 0 到 1 之间。这个格式是 YOLO 系列通用的和 YOLOv5、YOLOv8、YOLO11 都兼容。YOLOv8 训练时读取的就是这种标注。资源里通常会有一个 dataset.yaml 或 custom.yaml 文件里面写明训练集、验证集路径和类别数量。打开看一下重点确认 names 的列表顺序和标注文件里的类别索引对不对得上。很多新手在这翻车标注里类别索引是 0但 yaml 里 names 第一项写成了「car」或者别的训练出来的模型预测结果自然对不上号。2.2 数据质量决定模型上限先做一轮标注体检「准备数据集」这件事的质量直接决定训练结果。我拆资源的第一件事不是训练而是写个小脚本把标签合法性检查一遍主要包括三件事txt 文件格式是否正确、坐标是否越界、有没有缺失标注的图片。下面这个脚本可以快速检查from pathlib import Path label_dir Path(dataset/labels/train) class_count {} for f in label_dir.glob(*.txt): if f.name classes.txt: continue with open(f, r, encodingutf-8) as fp: for line in fp: line line.strip() if not line: continue parts line.split() if len(parts) ! 5: print(f格式不对: {f.name} - {line}) continue cls int(parts[0]) x, y, w, h map(float, parts[1:]) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): print(f坐标越界: {f.name} - {line}) class_count[cls] class_count.get(cls, 0) 1 print(类别分布:, class_count)这段代码做的事很简单遍历 labels/train 下所有 txt逐个检查每行是不是 5 个数、坐标是否落在 [0,1] 区间。如果发现格式不对或越界打印出文件名和具体行。最后统计每个类别的样本数。类别分布这一步很重要如果某个类别的标注数量只有几十条而另一个类别有几千条训练时就容易出现类别不平衡导致模型对样本少的类别基本不敏感。坐标检查通过后还应该做一轮「人眼复核」——把标注框画回原图检查框是否贴合电动车轮廓、有没有把行人误标进去。下面这段代码把前 20 张图的标注可视化直接保存成图片人工翻看import cv2 from pathlib import Path for img_path in list(Path(dataset/images/train).glob(*.jpg))[:20]: img cv2.imread(str(img_path)) h, w img.shape[:2] label_path Path(dataset/labels/train) / (img_path.stem .txt) if not label_path.exists(): print(f{img_path.name} 没有对应的标签文件) continue for line in open(label_path): parts line.strip().split() cls, x, y, bw, bh int(parts[0]), *map(float, parts[1:]) x1 int((x - bw / 2) * w) y1 int((y - bh / 2) * h) x2 int((x bw / 2) * w) y2 int((y bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.putText(img, str(cls), (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite(fcheck_{img_path.name}, img)画框时先把归一化坐标乘回图片宽高再换算成左上角和右下角坐标这个换算逻辑是日常调试里重复率最高的代码。注意脚本里有个细节cv2.putText的 y 坐标用了max(0, y1 - 5)因为标签框贴到图片顶部时文字画在框上方会被裁掉。这种细节就是实际跑代码才会意识到的地方。检查完如果发现大量框偏移返回标注工具修正如果只有个别异常直接删除对应图片和标签文件即可不要带着脏数据训练。2.3 划分与类别不平衡的常见处理训练集和验证集的划分资源包里一般已经拆好。如果后续你想自己加数据重新划分我一般按约 9:1 的比例把数据集拆成 train 和 val确保验证集里每个类别都有样本覆盖。电动车在电梯场景里拍摄角度多样有正面、侧面、斜后方还有遮挡和光线差异这些都要在验证集里尽量覆盖到。如果发现某些角度完全没出现在验证集里模型有没有泛化能力完全是黑匣子。3. 用 train_mode.py 把模型训起来权重选择、超参数与指标图解读3.1 预训练权重怎么选yolov8n 还是 yolo11n资源里同时带了 yolov8n.pt 和 yolo11n.pt这是两种不同网络结构的轻量级权重。yolov8n 是 YOLOv8 的 nano 版本推理速度快、显存占用低适合部署在电梯轿厢这种算力有限的边缘设备上yolo11n 是后续推出的 YOLO11 的 nano 版本结构上做了优化在相同体积下精度通常略好一些。训练脚本 train_mode.py 里通常会在初始化模型时指定用哪个权重from ultralytics import YOLO # 二选一换不同权重路径即可 model YOLO(yolov8n.pt) # 经典 YOLOv8 nano # model YOLO(yolo11n.pt) # 结构更新精度略好 results model.train( datadataset.yaml, # 数据集配置文件 epochs100, # 训练轮数 imgsz640, # 输入图片尺寸 batch8, # 每批次图片数量 device0, # 0 为 GPU无 GPU 改成 cpu workers2, # 数据加载线程数 )这段代码的核心是model.train()Ultralytics 把训练细节封装得比较干净你只需要关注data、epochs、imgsz、batch这四个参数。data必须指向你的 yaml 配置文件里面写了 train/val 路径和类别数量epochs决定训练多长时间毕设场景 100 轮基本够用追求更好效果可以跑到 200 轮imgsz是模型输入分辨率640 是默认值也是精度和速度的平衡点batch受显存限制显存不够就调小到 4 或 2。3.2 训练前要改的参数和显存边界超参数的选择没有绝对标准但有一条经验线。如果你的显卡是 6GB 显存级别batch 设 8 配 imgsz640 基本是上限硬加到 16 会直接报 CUDA out of memory。如果没独显用 CPU 训练device 改 cpuepochs 建议砍到 30 到 50 轮先验证流程能不能走通不然一个模型训一天一夜很正常。参数推荐值说明epochs100先跑 50 轮看 loss 是否下降再决定加不加imgsz640电梯画面目标不算太小不需要提高分辨率batch4~86GB 显存用 8再低就跑得慢workers2Windows 下太高容易报 DataLoader 错误device0/cpu有 GPU 用 0没有就 cpu训练过程会实时打印每一轮的结果包括 box_loss、cls_loss 和各类指标。训练结束后在 runs/detect/train 目录下会生成一整套指标图results.png 里是损失曲线和 mAP 曲线confusion_matrix.png 是混淆矩阵F1_curve.png 是 F1 分数曲线PR_curve.png 是精确率-召回率曲线val_batch_pred.jpg 是验证集预测结果可视化。这套东西正是毕设答辩里「评审绝对信服」的部分因为这些图证明了你的模型不是玄学而是有实验数据支撑的。3.3 指标图怎么看不是所有的线都代表效果好results.png 里的曲线不止一条需要分清楚。bottleneck 是损失值应该随着训练轮数下降并趋于平缓metrics/precision 和 metrics/recall 应该上升mAP50 和 mAP50-95 是核心评估指标mAP50 达到 80% 以上说明模型对这个数据集拟合得比较好了。如果 loss 曲线下降后开始反弹大概率是学习率没配好或过拟合此时应减少 epochs 或增加数据增强。混淆矩阵图里对角线上的颜色越深越好。如果某个类别的列上出现大块浅色但不在对角线说明模型把大量其他目标误判成了这个类别。这套资源里如果训练后混淆矩阵很干净基本可以确定数据集质量不错不需要做太多调优。4. 推理与可视化界面从 best.pt 到电梯门口的检测闭环4.1 Detection_video.py 的推理流程训练完跑出来的 best.pt 是效果最好的权重。推理脚本 Detection_video.py 的作用是读取视频逐帧做检测把结果输出为带框的视频或实时显示。核心代码大致是from ultralytics import YOLO model YOLO(best.pt) # 加载训练产出的最优权重 cap cv2.VideoCapture(test_video.mp4) # 换成 0 表示读摄像头 while cap.isOpened(): ret, frame cap.read() if not ret: break results model.predict(frame, conf0.45, imgsz640, verboseFalse) for r in results[0].boxes: cls int(r.cls) # 类别索引 conf float(r.conf) # 置信度 if conf 0.45: continue x1, y1, x2, y2 map(int, r.xyxy[0].tolist()) print(f类别 {cls} 置信度 {conf:.2f} 坐标 ({x1},{y1})-({x2},{y2})) # 画框、显示或保存视频的代码省略这里的conf0.45是置信度阈值意思是只有模型认为该目标有 45% 以上的概率是目标类别时才输出。阈值设低了会频繁误检设高了会漏检电动车。电梯场景一般建议 0.4 到 0.5 之间具体值要通过跑几段真实监控视频观察效果来定。r.xyxy[0]返回的是检测框的左上角和右下角坐标r.conf是置信度r.cls是类别索引。推理脚本跑通之后建议先拿一段没有电动车的视频做负样本测试看看会不会出现误检。这一步很多人跳过但实际是检验模型泛化能力最直接的办法——如果空电梯频繁报警说明模型学歪了。4.2 Visual_interface.py 界面逻辑与禁入判定可视化界面脚本 Visual_interface.py 是给非技术用户看的通常用 PyQt5 实现界面上一块视频显示区、一个状态指示灯、一个置信度阈值调节滑块。界面和推理逻辑通过信号槽机制通信简单示意如下def update_ui(self, frame, boxes): detect_flag False for x1, y1, x2, y2, conf, cls in boxes: if cls 0 and conf self.threshold: detect_flag True # 检测到电动车 cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2) if detect_flag: self.status_label.setText(检测到电动车禁止进入) self.status_label.setStyleSheet(color: red) self.alarm_signal.emit(True) # 触发报警或联动梯控 else: self.status_label.setText(正常运行)这段代码有几个关键点。第一禁入逻辑不是「检测到任何目标」就报警而是类别索引为 0 且置信度超过滑块阈值才算。第二setStyleSheet控制状态文字颜色红色就代表报警状态。第三alarm_signal.emit(True)是把报警状态发出去实际工程里可以接蜂鸣器、电梯开门控制逻辑或物业通知。界面线程和推理线程要用信号槽解耦不然推理一卡界面直接假死。4.3 视频输入与摄像头接入的扩展资源包里默认处理的是视频文件想要接真实摄像头把cv2.VideoCapture(test_video.mp4)换成cv2.VideoCapture(0)就能读本机摄像头。楼道和电梯场景一般是 RTSP 网络摄像头地址类似rtsp://192.168.x.x:554/stream1同样可以直接传给 VideoCapture。注意网络摄像头有延迟检测效果对帧率敏感建议在读取后做抽帧处理每 2 到 3 帧检测一次即可不必逐帧全跑节省算力也不影响禁入判断的及时性。5. 部署避坑我替你踩过的五个 YOLOv8 训练与界面坑5.1 训练阶段的高频报错现象训练刚启动几秒就报CUDA out of memory。原因batch 设太大或者 imgsz 设成了 1280显存直接被吃光。很多新手上来就照抄别人的配置没意识到对方用的是 24GB 显存。解决batch 直接降到 4imgsz 保持 640。还不行就把 workers 改成 0减少数据加载时的额外内存占用。用 CPU 跑的话就认命把 epochs 砍到 30先验证数据集和代码没问题再谈效果。现象训练过程中报bad key at line或者label index out of range。原因标签 txt 文件里某个类别编号超出了 yaml 里配置的类别总数。比如 yaml 里写names: [electric]只有 1 类但标注文件里出现了1这个索引。解决用前面第 2 章给的检查脚本先格式化一遍把非法行挑出来。最粗暴的修法是把出错的那张图和标签一起删了如果出错文件多再考虑重新标注。现象训练能跑完但预测结果所有目标都是同一个类别。原因dataset.yaml 里names的顺序和标注文件里的类别索引对不上。比如标注文件里 0 代表电动车yaml 里 0 写的是行人模型按 yaml 的名字显示自然张冠李戴。解决打开 yaml 文件把 names 列表顺序和标注文件里类别分布打印出来逐行比对确保索引完全一致。5.2 推理和界面阶段的「玄学」问题现象用训练好的 best.pt 跑推理结果和没训练过的预训练权重一模一样。原因Detection_video.py 里模型加载路径写成了YOLO(yolov8n.pt)根本没加载 best.pt。这种低级错误最常见因为 Ultralytics 默认权重路径就是 yolov8n.pt复制代码时很容易忘改。解决把推理脚本里的路径统一改成best.pt的绝对路径并在启动时打印一行「loaded model: ...」确认加载的是哪个文件。现象界面脚本在本地能跑拷贝到服务器或另一台电脑上就黑屏或闪退。原因一是缺 PyQt5 环境二是界面代码里直接调用了cv2.imshow而远程服务器没有桌面环境OpenCV 的窗口函数直接报错。三是路径写的是相对路径换了目录找不到资源文件。解决部署前检查 requirements.txt 或 README.txt 里列出的依赖逐项安装完整。把视频显示统一走界面控件不要混用 OpenCV 窗口。所有模型路径、视频路径都改成绝对路径或者在脚本开头做路径拼接处理。现象电梯监控画面角度刁钻电动车只有车把或轮胎露出模型完全漏检。原因数据集里缺少这种局部遮挡样本。模型见过的大多是完整车身没见过半截车。解决训练前从监控视频里抽帧补标注专门截取遮挡严重的帧加进数据集。如果不想重新训练就把置信度阈值往下调从 0.45 降到 0.35代价是误检增加需要实际测试找平衡点。6. 进电梯之前ROI 裁剪、模型导出与答辩演示的三个技巧真实电梯场景和测试视频有一个明显区别监控画面里不只电梯门口一个区域电动车的目标在画面下半部分出现但画面顶部可能有大楼走廊、安全出口标志这种干扰源。我一般会加一层 ROI 区域掩码把检测范围固定在电梯门口附近目标中心点不落在 ROI 内就直接过滤掉减少大量无意义的误检。实现方式很简单import numpy as np def make_roi_mask(w, h, roi_ratio0.45): # 只保留画面下方 45% 区域电动车进电梯门时车体落在这里 mask np.zeros((h, w), dtypenp.uint8) mask[int(h * (1 - roi_ratio)):, :] 255 return mask # 推理时拿到检测框之后 for r in results[0].boxes: x1, y1, x2, y2 map(int, r.xyxy[0].tolist()) center ((x1 x2) // 2, (y1 y2) // 2) if mask[center[1], center[0]] 0: continue # 目标没落在电梯门口区域不触发禁入roi_ratio0.45是需要按实际摄像头角度调的参数。摄像头装得高电动车在画面下方 30% 区域就传 0.3摄像头装得低车体会占到一半画面就传 0.5。中心点判定是最保守的策略不会因为车把伸出 ROI 外就漏检也不会因为行人的手挥进检测区就误报。模型导出也是毕设答辩前的加分步骤。把 best.pt 导出成 ONNX 格式一方面可以脱离 PyTorch 环境做推理另一方面有机会部署到边缘计算盒子。执行一行命令yolo export modelbest.pt formatonnx imgsz640导出成功后可以用onnxruntime加载做推理验证确认数值和 PyTorch 版本差别不大。如果以后想上 RK3588 这类边缘设备先导出 ONNX再转成 RKNN 格式整个链路是通的这一步提前做了答辩时说到部署扩展性会非常有底气。答辩演示的顺序我建议按「痛点 → 效果 → 数据证明」来排。先放一段没有检测系统的电梯监控指出人工盯防的不可靠再切换到系统实时检测画面让评审看到电动车进入瞬间界面状态变红这一下就有冲击力最后放 results.png 和 PR_curve.png强调 mAP、精确率和召回率的具体数值。整套资源里那些混淆矩阵、F1 曲线、验证集预测结果图就是为这个环节准备的一定要在论文里引用到。这套系统我前后拆了两遍第一遍跳过数据检查直接跑训练吃了标签索引错乱的亏第二遍老老实实先检查数据再看指标图半小时就把所有脚本跑通了。从那以后我每次拿到别人的 YOLO 项目都强制走一遍流程先跑推理确认权重有效再跑训练确认数据没坏最后打开 results.png 把指标曲线从头读一遍。希望帮到你。本文还有配套的精品资源点击获取
返回列表