资讯动态

电瓶车进电梯检测:200张VOC+YOLO数据集训练与避坑指南

发布时间:2026/10/5 5:26:58 来源:尧图企业网站定制
简介本数据集面向计算机视觉入门与目标检测实践者聚焦“电瓶车进入电梯”这一社区安防场景可用于训练和验证单类别检测模型帮助读者快速搭建针对电动踏板车闯入电梯的识别方案。资源包共602个文件包含200张jpg原图、200个Pascal VOC格式xml标注和200个YOLO格式txt标注另有少量说明文件压缩包约11.07MB两种标注格式可分别适配不同检测框架省去格式转换步骤。所有图片均使用labelImg手工绘制矩形框标注类别为electric scooter共210个标注框标注准确合理。目前已有205人学习下载适合作为课程设计、毕业设计或算法验证的小型数据集读者可直接用于模型训练、数据增强与检测效果对比快速验证单类别检测流程。1. 电瓶车进电梯检测200 张 VOCYOLO 数据集到底能跑出什么电瓶车进电梯这件事物业头疼、业主害怕但真正落到算法层面它其实是一个典型的「小目标 固定场景 单类别」检测问题。你拿到的这份电瓶车进入电梯检测数据集200 张图VOC 和 YOLO 两种标注格式核心目标只有一个把电梯轿厢里的电瓶车框出来。听起来简单但 200 张这个量级决定了它不是一个能直接冲 SOTA 的数据集而是一个用来验证 pipeline、做 demo、跑通训练流程的起点。适合谁适合手头有电梯监控画面、想快速验证检测可行性的人也适合刚接触 YOLO 训练、需要一个真实场景数据集练手的人。别指望 200 张能覆盖所有电梯型号和光照条件但它足够让你把「数据标注→格式转换→训练→推理→部署」这条链路完整走一遍知道坑在哪。2. 拆开这份数据集VOC 与 YOLO 双格式的选型逻辑与目录结构2.1 为什么同一批图要同时给 VOC 和 YOLO 两种格式VOC 格式是 XML 文件每个图对应一个 XML里面用bndbox记录xmin/ymin/xmax/ymax坐标是绝对像素值。YOLO 格式是 TXT 文件每行class_id x_center y_center width height全部归一化到 0~1。两种格式同时给本质上是照顾不同训练框架的输入习惯。YOLOv5/v8/v11 系列默认吃 YOLO 格式而一些老代码、MMDetection 配置、或者你自己写的 PyTorch Dataset 可能更顺手用 VOC。常见做法是拿 YOLO 格式直接喂 ultralytics拿 VOC 格式做数据校验和可视化因为 XML 可读性更好出问题容易定位。注意两种格式的类别索引必须对齐。VOC 里类别名是字符串YOLO 里是数字如果转换时类别映射写错训练时 loss 会正常降但 mAP 极低这是血泪经验。2.2 200 张图的目录应该怎么摆拿到压缩包解压后别急着改路径。先按下面这个结构整理后面所有脚本都基于这个结构写dataset/ ├── images/ │ ├── 001.jpg │ ├── 002.jpg │ └── ... ├── annotations_voc/ │ ├── 001.xml │ ├── 002.xml │ └── ... ├── labels_yolo/ │ ├── 001.txt │ ├── 002.txt │ └── ... └── classes.txtclasses.txt里只写一行ebike或者你数据集里定义的类别名。这个文件是后面转换和训练时类别映射的唯一依据不要散落在代码里硬编码。2.3 用脚本检查 VOC 标注有没有越界和漏标200 张图虽然少但标注错误率往往不低。先跑一个校验脚本把xminxmax、yminymax、坐标超出图像宽高的 XML 全部揪出来import os import xml.etree.ElementTree as ET from PIL import Image voc_dir dataset/annotations_voc img_dir dataset/images for xml_file in os.listdir(voc_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(voc_dir, xml_file)) root tree.getroot() img_name root.find(filename).text img_path os.path.join(img_dir, img_name) if not os.path.exists(img_path): print(f[缺失图像] {xml_file} - {img_name}) continue w, h Image.open(img_path).size for obj in root.findall(object): name obj.find(name).text bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) if xmin xmax or ymin ymax: print(f[坐标颠倒] {xml_file} {name} ({xmin},{ymin},{xmax},{ymax})) if xmin 0 or ymin 0 or xmax w or ymax h: print(f[越界] {xml_file} {name} 图像尺寸({w},{h}) 框({xmin},{ymin},{xmax},{ymax}))逻辑说明逐 XML 解析先确认对应图像存在再读图像宽高最后对每个 object 做坐标合法性判断。参数说明voc_dir和img_dir按你实际路径改如果类别名不是ebike脚本不关心名字只查坐标所以不用改类别相关逻辑。跑完如果输出很多越界说明标注时可能用了缩放后的图需要统一回原图坐标。3. 从 VOC 转 YOLO转换脚本、归一化参数与四个边界坑3.1 转换脚本的核心逻辑与类别映射VOC 转 YOLO 的公式很简单x_center (xmin xmax) / 2 / wy_center (ymin ymax) / 2 / hwidth (xmax - xmin) / wheight (ymax - ymin) / h。但写脚本时最容易翻车的是类别索引和文件名对齐。下面这个脚本直接可用import os import xml.etree.ElementTree as ET from PIL import Image voc_dir dataset/annotations_voc img_dir dataset/images out_dir dataset/labels_yolo classes [ebike] # 按 classes.txt 顺序 os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(voc_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(voc_dir, xml_file)) root tree.getroot() img_name root.find(filename).text img_path os.path.join(img_dir, img_name) w, h Image.open(img_path).size lines [] for obj in root.findall(object): name obj.find(name).text if name not in classes: print(f[未知类别] {xml_file} - {name}) continue cls_id classes.index(name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) x_center (xmin xmax) / 2.0 / w y_center (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) out_name os.path.splitext(xml_file)[0] .txt with open(os.path.join(out_dir, out_name), w) as f: f.write(\n.join(lines))逻辑说明先建输出目录逐 XML 读图像尺寸再对每个 object 做归一化最后按同名 txt 写出。参数说明classes列表必须和classes.txt完全一致顺序不能错:.6f保留六位小数YOLO 训练时精度足够不要用科学计数法。3.2 转换后必须做的三项校验转完不是就完了至少做三件事第一随机抽 10 个 txt用cat看有没有空文件或者坐标超过 1第二用 Python 统计每个 txt 的行数和 XML 里 object 数量对比不一致的记下来第三把 YOLO 格式反画回图上肉眼确认框位置没偏。反画脚本很多核心就是x_center*w还原成像素坐标再画矩形。这一步能抓住 90% 的转换错误。3.3 四个边界坑空标注、截断框、类别名大小写、文件名空格空标注有些图可能没有电瓶车XML 里没有 object转出来是空 txt。YOLO 训练时空 txt 是合法的负样本但如果你数据集里全是正样本突然混入空文件要确认是不是漏标。截断框电瓶车只露出一半时标注可能贴着图像边缘归一化后坐标接近 0 或 1训练时要注意 YOLO 的rect推理模式可能裁掉边缘。类别名大小写Ebike和ebike在 Python 里是两个字符串映射会失败统一用小写。文件名空格如果图像文件名带空格XML 里filename可能被截断转换时读不到图建议批量重命名去掉空格。4. 用 YOLOv8/v11 训练 200 张电瓶车数据参数怎么设、多久能收敛4.1 环境配置与数据 YAML 写法ultralytics 环境配置不复杂但版本要对齐。常见做法是 Python 3.9pip install ultralyticsGPU 驱动和 CUDA 按你机器来。数据 YAML 文件这样写path: /abs/path/to/dataset train: images val: images names: 0: ebike200 张图train 和 val 都指向images是无奈之举因为量太少再切 20% 验证就只剩 160 张训练模型根本学不动。更合理的做法是train 用全部 200 张val 也用全部 200 张只看 loss 和训练集 mAP当作过拟合验证。等有更多数据再切分。4.2 训练命令与关键参数解释yolo detect train \ datadataset.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch8 \ lr00.001 \ patience50 \ device0modelyolov8n.pt用 nano 版200 张图用大模型纯属浪费。epochs200是因为数据少需要多轮才能记住但patience50防止过拟合后继续跑。batch8看显存8G 显存跑 640 分辨率 batch 8 没问题。lr00.001比默认 0.01 小小数据集用大学习率容易震荡。imgsz640是 YOLO 默认电梯场景电瓶车占画面比例不小640 够用。4.3 训练过程看什么loss 曲线、mAP50 和混淆矩阵200 张图训练loss 下降快是正常的可能 30 轮就降到很低。重点看mAP50有没有到 0.8 以上如果一直在 0.5 徘徊大概率是标注问题或者类别映射错了。混淆矩阵在runs/detect/train/下如果出现大量背景误检说明电梯里其他物体比如人、推车被误判成电瓶车需要加负样本。训练完的results.csv可以用 pandas 读出来画图看有没有过拟合。5. 避坑与排查200 张小数据集训练电瓶车检测的 5 个真实翻车记录5.1 现象训练 loss 正常降但推理时框全图乱飞原因VOC 转 YOLO 时坐标没归一化或者归一化用了错误的宽高比如用了缩放后图像的尺寸。解决回头检查转换脚本确认w, h来自原图且x_center等值都在 0~1 之间。用cat看一个 txt如果出现大于 1 的数就是没归一化。5.2 现象mAP50 始终为 0但 loss 在降原因类别索引不匹配。YAML 里names: 0: ebike但 txt 里写的是1或者 VOC 里类别名是Ebike而 classes 列表写的是ebike。解决统一类别名大小写检查classes.txt、YAML 和转换脚本里的classes列表三者一致。5.3 现象验证集 mAP 很高但实际电梯监控画面里检测不到原因200 张图可能来自同一部电梯、同一角度、同一光照模型过拟合到背景。解决如果条件允许拿几段不同电梯的监控截图做测试不要只看验证集。没有新数据的话至少做数据增强比如hsv_h0.015、hsv_s0.7、hsv_v0.4、fliplr0.5在 YAML 里加augment: True。5.4 现象训练时提示No labels found原因YOLO 默认在images同级找labels目录但你的 txt 放在labels_yolo。解决要么把labels_yolo改名为labels要么在 YAML 里用train: images和val: images的同时确保 ultralytics 能通过路径替换找到标签。最稳的办法是目录结构改成images/train和labels/train但 200 张图没必要直接改名labels最快。5.5 现象推理时电瓶车被切成两半只框住一半原因电瓶车在电梯里可能被门或人遮挡标注时只标了可见部分模型学到的是部分特征。解决标注时尽量标完整车身遮挡严重就标可见部分并在训练时用mosaic增强让模型适应遮挡。YOLO 默认开启 mosaic不用额外设。6. 200 张之后把电瓶车检测推到可用的三个进阶技巧200 张图跑通训练只是起点真要放到电梯里用还得做三件事。第一用训练好的模型对未标注的电梯监控视频做推理把置信度高于 0.6 的帧自动保存人工筛选后加入训练集这是最省力的数据扩充方式。第二导出 ONNX 或 TensorRT 模型在边缘设备上测帧率电梯场景不需要 30 帧5 帧就够报警但延迟要低。第三加一个简单的跟踪逻辑连续 3 帧检测到电瓶车才触发报警避免单帧误检导致误报。我自己的习惯是每次扩充数据后重新训练时把lr0再降一半因为新数据分布和老数据有差异小学习率更稳。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑