首页 / 资讯中心 / 文章详情

YOLOv8电梯内电瓶车检测实战:从数据集到部署全流程

YOLOv8电梯内电瓶车检测实战:从数据集到部署全流程 ★ FEATURED ARTICLE
先交代一下背景。我在做智慧社区安防相关项目的时候接触了不少物业和梯控厂商的需求被反复提及的一个场景就是识别进入电梯的电动自行车。这个需求听起来不复杂但真正落地起来坑不少。于是我自己用YOLOv8做了一整套电梯内电瓶车检测识别项目把数据集整理、模型训练、实时推理、报警联动全部跑通还特意做了中英文双版效果演示和完整源码都整理到了配套资源里。这篇文章不是官方文档的搬运而是我从零到一做完之后的完整复盘包括网上搜不到答案的踩坑记录适合准备做相关毕业设计、竞赛项目或者想给门禁系统做技术验证的同学参考。1. 电梯场景里的“伪装者”为什么这个需求没有想象中简单1.1 先看清要解决的真实问题电动自行车进电梯、入户充电一直是物业管理里比较头疼的事。大部分小区的解决办法是贴告示、派人巡查但人力有限总有漏网之鱼。电梯轿厢里的摄像头往往装在吊顶角落是俯视广角视角再加上轿厢内灯光复杂、金属壁反光严重光线条件比室外监控差不少。这就导致一个看似简单的“识别电动车”任务在真实电梯画面里会变成目标尺度小、形变大、光照不稳定、遮挡频繁。我在项目启动前专门去朋友小区的地下车库和电梯口蹲了几天拍了大量真实画面。发现一个关键问题很多电动车进出电梯时车身会和人的身体贴得很近甚至只露出后半截而抱小孩的婴儿车、送餐用的手推车、搬家用的平板车从俯视视角看轮廓和电动车非常接近。如果模型训练得不够好很容易把轮椅、推车误判成电瓶车报警响个不停物业最后只能把系统关掉。所以这个项目的核心难点不是“能不能检测出来”而是“在电梯这种特殊场景里怎么做到误报少、漏检少、实时性还能跟上”。1.2 对比了几条技术路线之后为什么留在YOLOv8我在动手之前先评估过几种方案。早期目标检测常用的Faster R-CNN精度不错但在CPU或者低端GPU上实时性不够电梯监控往往要接多路视频流单路跑不到实时就很麻烦。SSD速度快但小目标检测能力偏弱而电梯画面里电动车经常离摄像头远、只占很小一块区域SSD在这种场景下不太合适。YOLOv5确实成熟社区资料多但和YOLOv8相比训练流程和内置的数据增强策略没那么顺手尤其是YOLOv8的Anchor-Free检测头在处理遮挡和形变目标时表现更好。我做了一张简单的对比表方便你根据自己的硬件条件做选择模型精度表现推理速度小目标能力部署难度适合场景Faster R-CNN高慢中高离线分析SSD中低快弱中常规固定场景YOLOv5中高快中低通用实时检测YOLOv8高快较强低实时监控、边缘设备实际用下来YOLOv8在电梯这种遮挡多、目标小的场景里收敛速度和最终精度都要比YOLOv5省心一些。而且Ultralytics官方仓库的生态比较完整训练好的权重可以直接导出ONNX、TensorRT、RKNN等格式后面如果想从PC搬到嵌入式设备上不用重写整个推理逻辑。1.3 我用的训练和推理环境训练阶段我用了一张GTX 1660Ti6G显存这在现在的深度学习环境里属于比较入门的配置。一开始我也担心显存不够用但实测下来用YOLOv8n模型输入尺寸640×640batch size设成8开启AMP混合精度训练完全跑得动每轮epoch大概需要三四分钟。如果你是RTX 3060或者更好的卡可以直接把batch size提高到16或者32训练速度会快很多。有一点要提前说清楚训练环境和部署环境不一定要一样。很多项目在PC上训练最终部署到NVR后端或者RK3588这类边缘盒子上。我的工程里推理脚本先以普通PC摄像头为基准做了验证后面单独留了模型转换的脚本方便你把训练好的权重转成其他格式这个我们到第四章再展开。2. 数据集是项目的“地基”电梯场景样本怎么凑、怎么标2.1 数据从哪里来公开数据集加自己补拍很多初学者直接拿COCO数据集里的“摩托车”类别来训练然后发现到了电梯场景里完全不能打。原因很简单COCO里没有“电瓶车/电动自行车”这个独立类别只有bicycle和motorcycle而且拍摄视角大多是平视路拍和电梯轿厢的俯视广角画面差别太大。用这种模型做迁移学习效果很差。我的做法是分成三个来源凑数据从开源数据集中筛选像UA-DETRAC这类车辆检测数据集里有一部分包含电动自行车和摩托车的街拍画面可以作为基础样本补充。网上公开的监控片段截图视频平台上有不少小区电梯监控公开片段我会抽帧出来专门截取包含电动车出入的画面。自己补拍真实场景这是最重要的一部分。我借了一台运动相机在朋友小区的电梯门口和地下车库出入口拍了大量视频覆盖不同时段、不同光照、不同角度。最终整理下来正样本包含电瓶车的画面大约1500张负样本只有行人、婴儿车、轮椅、大件行李的电梯画面大约1000张。负样本的数量一开始不够后面吃了大亏这个我在第五章会详细说。2.2 标注格式与类别定义我用的标注格式是YOLO系列通用的txt格式每个图片对应一个同名txt文件每行内容依次是类别编号、中心点x坐标、中心点y坐标、目标宽度、目标高度所有坐标都归一化到0到1之间。类别这里我只定义了一个类electric_bicycle也就是电动自行车。有人会问要不要把摩托车和电瓶车分成两类从实际场景看电梯里出现的两轮车绝大多数是电瓶车摩托车极少所以我干脆合并成一个大类避免类别太细导致标注工作量翻倍、模型反而学不好。为了把网上找到的VOC格式XML标注转成YOLO格式我写了一个小脚本核心逻辑其实就是读取XML里每个object的bndbox坐标再除以图片宽高做归一化。这个脚本我已经放进源码包了叫tools/xml2yolo.py如果你手头有labelImg或者Labelme标好的数据可以直接用它转格式。2.3 针对电梯轿厢环境的增强策略YOLOv8内置了Mosaic、MixUp、HSV变换、随机翻转等数据增强。但要注意电梯场景不能所有增强都拉满我调参时踩过一个很典型的坑默认配置里随机旋转的范围比较大模型学到了“倒着的电动车”但实际电梯画面里电动车永远是竖着的这种增强反而增加了误检。我在最终训练时把旋转角度关掉了只保留了垂直翻转和水平翻转因为这两个翻转在真实场景里是合理的摄像头视角变化也会产生类似效果。同样的亮度扰动我调小了。电梯轿厢内部灯光相对稳定不像室外场景那样有强烈的早晚光照变化过大的亮度扰动会让模型对光影过度敏感反光一强就乱报。我最终的增强方案是mosaic开启、mixup开启、HSV饱和度扰动控制在0.2以内亮度扰动控制在0.1以内旋转关闭。这些参数都写在项目的data/hyp.yaml里你可以根据自己的实际画面微调。3. 训练过程全记录参数、损失曲线与翻车现场3.1 环境安装与一个容易被忽略的版本坑环境配置本身不难我用的组合是Python 3.9、PyTorch 2.0、CUDA 11.8、Ultralytics 8.0. 具体安装命令如下conda create -n yolo8 python3.9 conda activate yolo8 pip install torch2.0.0 torchvision0.15.0 --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics8.0.0这里有一个很容易被忽略的版本问题Ultralytics的迭代速度非常快不同小版本的API会有细微变化。比如早期版本里model.predict()返回的结果结构和后续版本就略有不同。如果你按照网上的旧教程写推理代码复制过来可能直接报错。我的建议是尽量锁版本用我上面给出的ultralytics8.0.0整个工程按这个版本测试过你直接复现不会遇到莫名其妙的报错。另外Windows系统下训练时数据集路径不要带中文否则有些图像加载库会随机出问题。这个坑我帮朋友排查过好几次都是同一个原因。3.2 训练命令与参数解读数据准备好之后训练命令其实很简洁yolo detect train datadata/elevator.yaml modelyolov8n.pt epochs150 batch8 imgsz640 ampTrue重点解释几个参数为什么这么设modelyolov8n.pt这是从官方预训练权重开始继续训练而不是从随机权重开始。因为YOLOv8已经在COCO上见过大量通用物体电梯里的电瓶车虽然COCO没有专门类别但车身纹理、轮廓特征和摩托车、自行车有重叠迁移学习能明显加快收敛速度。imgsz640YOLOv8默认输入就是640这个尺寸在检测精度和推理速度之间比较平衡。如果你对视距远的小目标要求很高可以试1280但显存占用会成倍上涨先640起步。ampTrue混合精度训练显存不够时的救命稻草。1660Ti 6G显存能跑batch8靠的就是它。我训练的时候还加了patience30意思是30个epoch内mAP没有提升就自动早停。这样挂机训练不怕浪费时间。3.3 损失曲线怎么看mAP不涨怎么办训练过程中的runs/detect/train文件夹下会保存loss曲线。重点关注三个损失box_loss边框损失、cls_loss分类损失、dfl_loss分布焦点损失。正常情况下三者都是逐步下降然后趋于平缓。我在测试过程中遇到过一次mAP卡在0.6上不去的情况排查步骤如下先看训练集loss和验证集loss的差距如果训练集loss很低、验证集loss还很高那就是过拟合需要增加数据增强或者增加负样本数量。再看标注文件有没有错误类别。我抽查过一个图片文件夹发现有两张图的标注框把“人”框了进去导致模型学到了一些错误的特征。最后看样本是否均衡。电梯里电瓶车出现次数远少于正常人流量如果正负样本比例差太多模型会倾向于把所有两轮目标都“保守”地判成负样本也就是漏检率高。我最终把负样本里“类似电瓶车轮廓”的目标单独挑出来重新标注模型精度才有了明显提升。这一套排查下来最终我的模型在测试集上mAP50达到了0.93mAP50-95大概0.67对于电梯场景来说属于能用的水平。4. 推理部署与中英文双版设计4.1 实时推理的最小可用脚本训练完成后推理脚本就简单多了。下面这段代码可以直接读取摄像头或视频文件逐帧推理之后画框显示import cv2 from ultralytics import YOLO model YOLO(weights/best.pt) cap cv2.VideoCapture(0) # 改成RTSP地址就可以接监控摄像头 while True: ret, frame cap.read() if not ret: break results model.predict(frame, conf0.45, imgsz640, verboseFalse) for r in results: boxes r.boxes.xyxy.cpu().numpy() confs r.boxes.conf.cpu().numpy() for box, conf in zip(boxes, confs): x1, y1, x2, y2 map(int, box) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.putText(frame, felectric_bicycle {conf:.2f}, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.imshow(elevator detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()如果你的摄像头是网络摄像头只要把cv2.VideoCapture(0)里的0换成rtsp://用户名:密码IP:端口/stream1这样的地址就行。我实测过用YOLOv8n模型在1660Ti上跑推理延迟稳定在30毫秒左右一秒钟大概能处理20到28帧完全满足实时监控需求。4.2 中文版和英文版输出怎么切换标题里提到的“中英文双版”我是这样设计的整个工程内部通过一个config.yaml里的language字段控制可选zh或者en。它影响两处一处是运行时画框上的标签文字另一处是报警推送文案。实现方式很简单就是一个字典映射LANG { zh: {label: 电瓶车, alert: 检测到电瓶车请勿进入电梯}, en: {label: electric_bicycle, alert: Electric bicycle detected, please do not enter the elevator} }检测时根据config.yaml里配的语言从字典里取对应的文案。项目里另外还准备了两份README一份中文一份英文代码注释也按中英双语写的。这样不管你是拿去写中文报告还是给国外客户演示英文界面都不用改代码结构只改一个配置项。4.3 报警联动与延迟控制电梯场景如果每帧都检测到一点疑似目标就报警体验会非常差。我在工程里加入了一个时间窗口平滑逻辑只有当连续N帧都检测到电瓶车时才触发报警提醒。N默认是3你可以在配置文件里调整。这样一个人快速推着婴儿车经过即使某一帧被误判成电瓶车也不会立刻报警而真正的电瓶车在电梯里停留的时间通常远超过0.1秒连续确认机制不会影响最终报警。报警触发之后我预留了两个输出接口控制台打印和语音播报。语音播报用的是系统自带TTS中文版和英文版各一个音频文件触发时直接播放。如果你有梯控联动需求也可以把报警信号换成串口指令或者网络请求这个接口我封装在alarm.py里你只要改一个回调函数就行。4.4 边缘端部署的一个预习目前工程默认在PC上跑但实际商用场景更多是接到轻量级边缘计算盒子上。我的源码包里专门放了一个tools/export_onnx.py脚本一行命令就能把best.pt转成ONNX格式。再往下走如果目标设备是RK3588这种带NPU的板子ONNX可以继续转成RKNN格式部署后推理速度能做到几十毫秒一帧。这块内容展开又是一整篇文章我的建议是先把PC端的检测精度和稳定性调好再去折腾边缘部署否则两头一起搞出问题都不知道该排查哪一边。5. 实测数据与误报漏报案例分析5.1 测试集表现模型训练完我用了一部分完全没参与训练的电梯监控片段做测试总共约500张画面结果如下指标数值精确率Precision0.93召回率Recall0.89mAP500.93单帧推理耗时1660Ti约35ms连续视频流FPS约22-28从数值上看能覆盖绝大多数电梯进出画面。但数字背后的问题只有看失败案例才说得清楚。5.2 最容易翻车的几类画面我把翻车画面分成了三类每一类都给了解法。第一类是轮椅。轮椅的反光金属支架、轮辐线条和电瓶车轮廓接近早期模型误报率很高。解决办法是在负样本里大量加入推轮椅的画面让模型明确学到“这种结构不是电瓶车”。加了大约200张轮椅负样本后这类误报基本消失。第二类是金属反光。电梯内壁是不锈钢当电瓶车靠近内壁时倒影会造成重影模型可能在一个画面上检测出两个框。我在后处理里加了简单的NMS去重并在线标注时把置信度阈值从0.3提高到0.45重影问题明显缓解。第三类是目标过小。电动车还在电梯门口、只露出一小半时模型有时会漏检。针对这个问题我把测试用的输入尺寸从640提高到了960小目标召回率提升了5个点左右代价是推理速度从35毫秒涨到了55毫秒。如果你要部署在低端设备上这个提升不一定划算需要现场权衡。5.3 如果现场效果不满意怎么办我个人的建议是优先加数据而不是换模型。很多同学一看到精度不够就想着换YOLOv8s、YOLOv8m但很多时候问题的根源是样本覆盖不全。你在现场拍30分钟视频抽帧找出所有“模型检测失败的画面”把这些失败样本单独拷贝出来用labelImg重新标注然后和原数据集合并重训这比盲目换大模型有效得多而且成本低。我最终版本就是在第一版的基础上连续迭代了三轮数据每一步都只是增加失败样本没有动模型结构mAP就从0.82涨到了0.93。6. 完整源码工程结构与复现步骤6.1 工程目录说明我把整套工程打包成了一个压缩包名字是detect_electric_bicycle_yolov8.zip里面包含训练代码、推理脚本、配置文件、训练好的权重和一段效果演示视频。目录结构大致如下detect_electric_bicycle_yolov8/ ├── data/ │ ├── elevator.yaml # 数据集配置文件 │ ├── hyp.yaml # 数据增强参数 │ └── elevator_dataset/ # 图片与标注文件夹 ├── weights/ │ └── best.pt # 训练好的权重 ├── scripts/ │ ├── train.py # 训练入口 │ ├── detect_camera.py # 摄像头实时检测 │ ├── alarm.py # 报警联动模块 │ └── utils/ │ ├── xml2yolo.py # VOC转YOLO工具 │ └── export_onnx.py # 权重导出脚本 ├── config.yaml # 中英文切换与置信度配置 ├── README_CN.md # 中文说明 ├── README_EN.md # English README └── demo_video.mp4 # 效果演示视频建议你拿到工程之后先看README_CN.md里面写了详细的目录说明和运行顺序然后打开config.yaml把语言和置信度阈值按需改好。6.2 从下载到出效果的七步第一步解压压缩包确认Python环境是3.9以上按照第三章的命令装好PyTorch和Ultralytics。第二步修改data/elevator.yaml里的路径如果你不打算重新训练只做推理这一步可以跳过。第三步运行python scripts/detect_camera.py这时会打开本地摄像头加载weights/best.pt权重直接开始实时检测。第四步如果一切正常你会在画面里看到红色的检测框标签根据config.yaml里的语言设置显示“电瓶车”或“electric_bicycle”。第五步想测试报警功能找一段包含电瓶车的视频文件把detect_camera.py里的视频源改成文件路径连续检测3帧以上就会触发语音提醒。第六步想自己重新训练模型把elevator_dataset文件夹换成你自己的数据集运行python scripts/train.py训练完成后新的权重会输出到runs/detect/train/weights/best.pt。第七步想要部署到边缘设备运行python scripts/utils/export_onnx.py导出ONNX模型后续可以自行转换。6.3 想换更准或更快的模型怎么改YOLOv8有n、s、m、l、x五个尺寸版本我的工程默认用的是n版体积小、速度快。如果你的显卡性能充裕或者目标场景比较复杂把训练命令里的yolov8n.pt换成yolov8s.pt或yolov8m.pt就可以Python推理脚本里对应改一下权重路径。三个版本的大致对比模型版本参数数量推理耗时1660Ti适用场景YOLOv8n约300万约35ms边缘设备、实时要求高YOLOv8s约1100万约55ms精度和速度平衡YOLOv8m约2600万约90ms精度优先、算力充足最后说一点我在实际项目中体会比较深的东西模型检测只是整个系统里的一环真正上线时还要考虑摄像头安装角度变化、早晚光线差异、设备端算力波动还有物业管理员对误报的容忍度。我的经验是交付时宁可把置信度阈值调高一点、让少量漏检存在也不要让系统一天到晚乱报警否则用户很快就会把系统关掉。这个项目做到现在我认为最实用的部分不是YOLOv8本身而是那一套“如何针对真实场景不断迭代数据和参数”的思路。你可以直接拿这套工程去做类似的目标检测需求比如电梯里识别婴儿车、楼道里识别杂物堆积换数据、换类别流程完全通用。
阅读完成 · 觉得有帮助?
咨询建站