传送带异物检测数据集:VOC与YOLO双格式实战指南
简介本资源为流水线皮带传送带异物检测数据集面向从事工业视觉检测、智能制造与安全生产方向的算法工程师、研究生及深度学习入门者可用于训练与验证传送带异常目标检测模型解决皮带运输场景下异物识别与预警的样本需求。压缩包共332个文件包含110张jpg原始图像、110个VOC格式xml标注文件与112个txt文件含YOLO格式标注及说明整体约17.76MBjpg用于模型输入xml与txt分别适配Pascal VOC和YOLO两种主流训练框架便于直接转换使用。数据集仅设anomaly一个类别共标注191个矩形框采用labelImg工具人工画框标注准确合理。目前已有391人学习下载适合快速搭建传送带异物检测基线、验证数据增强策略或作为课程与项目实验素材帮助读者省去从零采集与标注的成本专注模型调优与效果对比。1. 传送带异物检测数据集110 张图、191 个框这份 VOCYOLO 双格式资源到底能干什么传送带跑偏、撕裂、混入锚杆或铁片这类事故在矿山、电厂、港口散料运输线上并不少见。真要在产线上做异物检测第一步往往不是调模型而是卡在数据上——公开的传送带异物检测数据集本来就少能直接喂给 YOLO 训练的更是稀缺。这份资源给的就是一个已经标好的小样本集110 张 jpg 图片对应 110 个 Pascal VOC 格式 xml 和 110 个 YOLO 格式 txt单类别anomaly总共 191 个矩形框标注工具是 labelImg。它适合两类人一是想快速跑通「传送带异物检测」这条链路、验证方案可行性的算法工程师二是拿它当模板理解 VOC 与 YOLO 双格式如何对齐、后续自己扩标的人。110 张不算多但胜在格式齐全、类别干净拿来练手和搭 pipeline 足够。2. VOC 与 YOLO 双格式拆解xml 和 txt 到底怎么对应2.1 两种格式的坐标体系差异Pascal VOC 的 xml 用的是绝对像素坐标xmin/ymin/xmax/ymax直接对应图片上的像素位置人读起来直观但不同分辨率图片混在一起训练时模型没法直接吃。YOLO 的 txt 用的是归一化后的中心点加宽高格式是class_id cx cy w h五个值全部落在 0 到 1 之间cx cy是框中心相对整图宽高的比例w h是框宽高相对整图宽高的比例。这份数据集两种都给了意味着你可以直接用 txt 喂 YOLO也可以用 xml 转成 COCO、VOC 训练框架需要的格式省掉自己写转换脚本的功夫。需要留意的是YOLO 的class_id从 0 开始编号。这份数据集只有一个类别anomaly所以所有 txt 里的 class_id 都应该是 0。如果你拿到手发现有的 txt 第一列是 1那说明标注时类别索引没对齐训练时会出现「明明只有一个类却报两个类」的玄学问题这个后面避坑章节会细说。2.2 目录结构核对与文件配对检查拿到压缩包解压后常见做法是先核对三组文件是否一一对应jpg 数量、xml 数量、txt 数量都应该是 110。文件名主干应当一致比如chuansongdai_1.jpg对应chuansongdai_1.xml和chuansongdai_1.txt。下面这段脚本就是干这个的跑一遍能立刻发现缺图、缺标注、命名不一致的情况。import os img_dir images # jpg 所在目录 xml_dir annotations # VOC xml 目录 txt_dir labels # YOLO txt 目录 imgs {os.path.splitext(f)[0] for f in os.listdir(img_dir) if f.endswith(.jpg)} xmls {os.path.splitext(f)[0] for f in os.listdir(xml_dir) if f.endswith(.xml)} txts {os.path.splitext(f)[0] for f in os.listdir(txt_dir) if f.endswith(.txt)} print(图片数:, len(imgs), xml数:, len(xmls), txt数:, len(txts)) print(有图无xml:, imgs - xmls) print(有图无txt:, imgs - txts) print(有xml无图:, xmls - imgs)逻辑说明用集合做差集是最快的配对检查方式比逐个文件循环判断省事。参数上三个目录名按你实际解压后的结构改有的包会把 jpg 和 xml 放同一目录那就把img_dir和xml_dir指向同一个路径。跑完如果三个差集都为空说明文件配对没问题可以进入下一步如果有输出先补齐再训练否则 YOLO 在加载阶段会直接跳过找不到标签的图你以为训了 110 张实际可能只训了 100 张。2.3 用 xml 反推 txt 的校验脚本虽然这份数据集已经给了 txt但校验一遍能确认标注没被改坏。下面脚本从 xml 重新算一遍归一化坐标和现有 txt 对比容差设 1e-4。import os import xml.etree.ElementTree as ET def voc_to_yolo(xml_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w float(size.find(width).text) h float(size.find(height).text) boxes [] for obj in root.iter(object): cls obj.find(name).text bnd obj.find(bndbox) xmin float(bnd.find(xmin).text) ymin float(bnd.find(ymin).text) xmax float(bnd.find(xmax).text) ymax float(bnd.find(ymax).text) cx (xmin xmax) / 2.0 / w cy (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h boxes.append((cls, cx, cy, bw, bh)) return boxes # 对比某个样本 xml_boxes voc_to_yolo(annotations/chuansongdai_1.xml) with open(labels/chuansongdai_1.txt) as f: txt_lines [l.strip().split() for l in f if l.strip()] print(xml框数:, len(xml_boxes), txt框数:, len(txt_lines)) for xb, tb in zip(xml_boxes, txt_lines): print(xb[0], [round(float(v), 4) for v in tb[1:]])逻辑说明voc_to_yolo把 xml 的绝对坐标按图片宽高归一化得到和 YOLO 一致的五个值。参数上容差不用写死在脚本里肉眼对比小数点后四位即可正常情况应当完全一致。如果发现某个框对不上多半是标注时框被拖动过但只更新了一种格式这种脏数据在训练里会拉低召回建议以 xml 为准重新生成 txt。3. 把 110 张图喂进 YOLO划分、配置与训练命令3.1 训练集验证集划分与 data.yaml 写法110 张图做检测常见做法是按 8:2 划分训练集 88 张、验证集 22 张。样本量小不建议再切测试集否则验证集只剩十几张指标波动会大到没法看。划分时按文件名排序后固定随机种子保证每次复现一致。import os, random, shutil random.seed(42) src_img, src_lbl images, labels for d in [dataset/images/train, dataset/images/val, dataset/labels/train, dataset/labels/val]: os.makedirs(d, exist_okTrue) names sorted([f for f in os.listdir(src_img) if f.endswith(.jpg)]) random.shuffle(names) split int(len(names) * 0.8) for i, name in enumerate(names): stem os.path.splitext(name)[0] phase train if i split else val shutil.copy(os.path.join(src_img, name), fdataset/images/{phase}/{name}) shutil.copy(os.path.join(src_lbl, stem .txt), fdataset/labels/{phase}/{stem}.txt) print(train:, split, val:, len(names) - split)逻辑说明random.seed(42)固定划分方便复现。参数上 0.8 是经验值样本更少时可以调到 0.9但验证集低于 15 张时指标参考价值有限。复制而非移动保留原始文件后面扩标时不用重新解压。划分完写data.yaml这是 YOLO 系列训练的入口配置path: ./dataset train: images/train val: images/val nc: 1 names: [anomaly]nc是类别数这份数据集就是 1names顺序必须和 txt 里的 class_id 对应0 对应anomaly。写反了模型会把异物当背景学训练 loss 看着降实际一个框都检不出来。3.2 从预训练权重起步的训练命令小样本检测最忌讳从零训。常见做法是加载 YOLO 官方在 COCO 上预训练的权重做迁移让 backbone 先具备通用特征提取能力再在 110 张图上微调。下面以 YOLOv8 为例命令里的参数按你的显存和图片尺寸调整。yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch8 \ lr00.01 \ patience20 \ projectruns/belt \ nameanomaly_v1逻辑说明modelyolov8n.pt选 nano 版本110 张图用大模型容易过拟合nano 足够跑通链路。epochs100配合patience20验证指标 20 轮不涨就早停避免无效训练。imgsz640是默认输入尺寸如果原图分辨率远大于 640异物又小可以提到 960 或 1280但显存占用会明显上升。batch8是保守值显存够可以加到 16。lr00.01是微调的常见起点样本少时可以降到 0.001 更稳。训练过程中重点看三个指标box_loss是否稳定下降、mAP50是否在涨、验证集的precision/recall是否严重失衡。110 张图训到 mAP50 0.7 以上算正常如果一直卡在 0.3 以下先回去查标注别急着调参。3.3 推理验证与结果落盘训练完拿验证集或新图跑推理确认模型真的能框出异物yolo detect predict \ modelruns/belt/anomaly_v1/weights/best.pt \ sourcedataset/images/val \ conf0.25 \ saveTrue \ projectruns/belt \ namepred_v1逻辑说明conf0.25是置信度阈值低于它的框不输出。小样本模型置信度普遍偏低可以先设 0.1 看召回再逐步提到 0.3 看精度找到业务能接受的平衡点。saveTrue把带框图片存到runs/belt/pred_v1肉眼过一遍比看指标更直接——有些框位置明显偏了指标却因为 IoU 阈值宽松没暴露出来。4. 小样本异物检测的避坑清单从标注到训练的血泪经验4.1 现象训练报「no labels found」loss 直接为 0原因YOLO 按图片路径推导标签路径如果你的目录结构不是images/和labels/平行或者 txt 文件名和 jpg 主干不一致它找不到标签就跳过。这份数据集原始文件是 jpg、xml、txt 混放直接指向原目录训练必然踩这个坑。解决按 3.1 的脚本重建images/train、labels/train结构确保每张 jpg 在同级 labels 下有同名 txt。跑一遍 2.2 的配对检查脚本差集为空再开训。4.2 现象只有一个类别训练却报 nc2 或类别索引越界原因txt 第一列的 class_id 不全是 0。labelImg 在切换类别时如果没重置可能把部分框标成了索引 1而data.yaml里nc1加载时就会冲突。解决扫一遍所有 txt 的第一列统计唯一值awk {print $1} labels/train/*.txt | sort | uniq -c正常输出只有0一个值。如果出现1用 sed 批量替换回 0或者回 labelImg 重新导出。这个坑很隐蔽因为文件数量对得上只有类别索引错了。4.3 现象mAP 忽高忽低两次训练差十几个点原因110 张图样本量太小验证集只有 22 张随机划分不同、初始化不同指标波动天然就大。这不是模型坏了是小样本的固有特性。解决固定随机种子多跑几次取平均或者用 K 折交叉验证把 110 张分成 5 折轮流做验证指标更稳。别拿单次训练的 mAP 当结论尤其别因为一次跑出 0.85 就以为方案成了。4.4 现象模型在训练集上框得很准换一张新图就漏检原因过拟合。110 张图、191 个框模型很容易记住训练集的背景纹理而不是学到「异物」的通用特征。传送带背景又高度相似过拟合更严重。解决开数据增强YOLO 默认带 mosaic、翻转、HSV 扰动确认没被关掉imgsz适当调大保留小目标细节如果还是漏说明 110 张不够覆盖实际场景的异物形态该扩标了别硬调参。4.5 现象xml 和 txt 框数对不上原因标注过程中改过框但只更新了一种格式或者转换脚本跑了一半中断。这份数据集声称 xml 和 txt 都是 110 个、总框 191实际拿到手要自己核一遍。解决用 2.3 的脚本逐样本对比框数不一致的以 xml 为准重新生成 txt。总框数可以用一行命令快速统计cat labels/train/*.txt labels/val/*.txt | wc -l正常应该接近 191划分后训练加验证合计。差太多说明有标注丢失。5. 从 110 张到可用模型扩标策略与标注一致性技巧这份数据集最大的价值不是那 191 个框本身而是它给了一套干净的格式模板。真正上产线110 张远远不够通常要扩到几千张。扩标时我一般会沿用它的目录约定和类别命名把新标的数据按同样结构并入避免格式来回转换。扩标的第一原则是类别定义要窄。anomaly这个词太宽锚杆、铁片、木块、大块矸石都算异物但它们的视觉特征差异很大。如果实际场景里异物形态超过三种建议拆成metal、wood、rock这类子类而不是全塞进anomaly。类别越宽模型越难学最后每个类都检不准。拆类之后data.yaml的nc和names同步改txt 里的 class_id 也要重新映射。第二原则是标注框贴边。传送带异物检测里异物常常压在皮带边缘或部分遮挡标注时框要贴住可见部分的外沿不要把整条皮带框进去。我见过有人为了「保险」把框画大一圈结果模型学到的特征是「皮带边缘」而不是「异物」换条线就废。labelImg 里可以用Ctrl滚轮放大细调别嫌麻烦。第三原则是负样本要留。纯异物的图好标但真实产线上大部分帧是没有异物的。如果训练集全是带异物的图模型会倾向于「每张图都得框点什么」误报率飙升。扩标时按 1:1 或 2:1 混入无标注的纯背景图YOLO 对没有 txt 的图会当作负样本处理能明显压误报。验证扩标质量有个笨办法但很管用把新标的 200 张图随机抽 20 张让另一个人重新标一遍对比两版的框 IoU。如果平均 IoU 低于 0.7说明标注标准没统一回去对齐定义再继续。这个习惯我从第一次做产线检测项目就养成了当时因为两个人对「异物边界」理解不一致标出来的框差了一圈模型训了两周指标上不去排查到最后才发现是标注问题白烧了算力。从那以后我每次扩标都强制走一遍交叉校验宁可慢一点也不让脏标注进训练集。最后提一句这份数据集明确声明不对模型精度作保证这是负责任的说法。110 张、单类别、191 个框它的定位就是让你跑通流程、验证格式、搭起 pipeline不是直接拿去上线。把它当起点按上面的扩标和校验方法往下走才是这份资源正确的打开方式。希望帮到你。本文还有配套的精品资源点击获取