简介:面向工业目标检测与YOLO模型训练,数据集聚焦自动化装配、智能质检和机器人视觉引导场景,适合算法工程师与制造行业开发者使用。数据集提供YOLO格式标注,覆盖枪型工具、钳型工具、尖头工具、扫描工具及手部共5类目标,可直接接入YOLOv5/v8等主流框架,便于构建工具识别与操作合规性检测模型。压缩包内共2000个文件,以1873个txt标签文件为主体,辅以125张jpg图片、1个yaml配置文件和1个说明文档,整体大小80.98MB,结构清晰,适合直接导入训练流程。目前已有187人学习下载。样本来自真实装配线,包含多角度操作细节,可增强模型在复杂光照和遮挡条件下的鲁棒性。获取后即可获得带标注数据集、类别配置及配套说明,能显著缩短工业场景数据准备周期,支撑装配质量追溯与机器人自动化升级实践。
1. 工具装配检测数据集:通用预训练权重在产线上为什么失效
产线上的工具检测和公开 COCO 数据里的杯子、椅子完全是两种难度:镜头离工具很近,金属表面反光,枪型工具和钳型工具在侧面视角下轮廓经常叠在一起,还要同时判断操作者的手是否接触工具。拿通用预训练权重直接上线,漏检和误检会非常明显。这份「工具装配检测数据集」是工业装配场景实拍帧的标注集合,训练集 1,873 张,包含 gun-type tool、hand、pliers-type tool、pointed tool、scanning tool 五类,标注以 YOLO 格式给出。因为标签文件可以直接喂给 YOLOv8 乃至更新的 YOLOv12,所以适合用来训练自己的装配监控模型,也适合做机器人抓取前的视觉定位和工位合规性判断。下面先从数据文件格式和类别语义开始拆。
2. 五类标签与 YOLO 标注文件:先从数据文件格式说起
数据集的核心不是图片本身,而是图片名、标签文件与类别命名之间的对应关系。工业目标检测项目和学术比赛不一样,类别少但语义接近,像 gun-type tool 与 pliers-type tool 在这个数据集里都带有长条形手柄,如果只看局部特征很容易混。理解这五类为什么存在,比直接跑训练更重要。
2.1 类别设计与工业语义:为什么“手”也是检测目标
这个数据集的标签只有五类,但每一类都有明确的产线语义。gun-type tool 指喷枪、胶枪这类以扳机触发为主的手持工具;pliers-type tool 是钳子、夹持工具;pointed tool 是螺丝刀、锥子、探针这类尖头工具;scanning tool 是扫码枪、探伤笔这类用于扫描确认的电子工具;hand 则覆盖人的手掌、手指和半握状态。
| category id | 标签名 | 中文语义 | 常见误配情况 |
|---|---|---|---|
| 0 | gun-type tool | 枪型工具,触发面通常有弧线 | 与 pliers-type 在侧视时混淆 |
| 1 | hand | 手部,覆盖不同肤色/手套 | 手持工具时框重叠导致一个框框两个目标 |
| 2 | pliers-type tool | 钳型工具,头部短粗、手柄长 | 与 gun-type 的握把部分混淆 |
| 3 | pointed tool | 尖头工具,细长导向明显 | 与小型 pliers 混淆程度低,但小目标多 |
| 4 | scanning tool | 扫描工具,通常带指示灯或屏幕 | 与抢型工具的握持区域混淆 |
hand 作为独立类别,作用不是“检测人”,而是用来支撑合规性判断。装配线经常要求“拿取工具时必须让工具离开工件”,或者“扫描前手不能遮挡条码”。只有同时检测到 hand 和 tool 各自的边界框,才能进一步计算两个框之间的交并比,从而判定持握、接近还是非法接触。所以训练时不能因为觉得 hand 目标太大而删掉这一类。
2.2 解析 YOLO 标注:一行标签的五个数值顺序
YOLO 格式每个 .txt 文件对应一张同名图片,每一行代表一个目标:类别 id、归一化中心点 x、归一化中心点 y、归一化宽度 w、归一化高度 h。我拿到标签后习惯先写个小脚本把标注打出来,确认坐标是否落在一个非空区域内,避免后面训练时 loss 一开始就爆炸。
import os label_file = "data/train/labels/1591587432198_jpg.rf.6cee4fe03f30966306dcc3e8d7360995.txt" with open(label_file, "r", encoding="utf-8") as fp: lines = [line.strip().split() for line in fp if line.strip()] for row in lines: cls_id = int(row[0]) x_center, y_center, width, height = map(float, row[1:]) print(f"cls={cls_id} " f"cx={x_center:.3f} cy={y_center:.3f} " f"w={width:.3f} h={height:.3f}")这段代码的关键点有三个:第一,row[0]是类别 id,必须与 data YAML 里 names 的下标一致,比如 0 对应 gun-type tool 而不是 hand;第二,后用四个浮点数都是相对图片尺寸的归一化坐标,数值范围在 0 到 1 之间,画框、裁剪时要重新乘以图像宽高;第三,坐标描述的是矩形中心点和宽高,不是左上角与右下角,许多刚从 COCO 转 YOLO 的人会在这里画错矩形。打印出来后,如果出现w或h大于 1,说明标注文件已经损坏或没归一化,需要优先清洗而不是直接训练。
2.3 文件名里的.rf.与多时序样本结构
从文件名能读出不少采集信息,例如WIN_20240613_04_24_07_Pro_mp4-0095_jpg.rf....jpg,前半段多半是 Windows 设备在 2024 年 6 月 13 日凌晨 04:24 录制的视频,mp4-0095表示从该视频第 95 帧附近抽帧;而1591587432198_jpg这种纯时间戳命名,更可能来自另一路摄像头或手机连续拍摄。两类文件名混合在一起,说明这个数据集的“训练集 1,873 张”并不是同一机位的简单连续帧,而是跨日期、跨时段、跨设备的样本集合。
.rf.是导出工具在处理图片后追加的 id 后缀,常见于 Roboflow 导出的 zip 包。它不会影响模型读取,因为 YOLO 训练时只依赖图片路径和同名 txt 路径,不解析文件名里的随机 hash。但你应该知道,这类导出包通常按train/valid/test三个子目录组织。如果解压后只有 train 目录,也完全够用,只需要再用脚本从 train 里按比例切出一部分做验证集,而不是直接拿全部训练集去训练,否则最后只能看到过拟合后的 mAP。
3. 用 YOLOv8 微调:目录整理、YAML 配置与训练参数调整
拿到工具装配检测数据集后,最直接的方式是先用 YOLOv8 把基线跑出来。YOLOv8 对 YOLO 格式的原生支持最好,安装 ultralytics 后不需要写自定义 Dataset 类。这一章从目录整理讲到训练参数,每一步都是可以照抄的。
3.1 统一目录结构并声明数据 YAML
Roboflow 导出的 zip 解压后路径不统一,有的直接是train/images,有的多套一层文件夹。为了让训练命令可重复执行,我会先整理成标准结构:
mkdir -p dataset/{images/{train,val},labels/{train,val}} mv original/train/*.jpg dataset/images/train/ mv original/train/*.txt dataset/labels/train/ # 从训练集抽 8% 做验证集,这里用简单 shell 方式,正式项目可以写 sklearn 脚本 cd dataset/images/train && ls *.jpg | shuf -n 150 | xargs -I {} mv {} ../val/ cd ../../labels/train && ls *.txt | shuf -n 150 | xargs -I {} mv {} ../val/把图片和标签保持同名同步移动很关键,因为 YOLO 训练只找同名 txt,没有匹配标注的图片会被自动忽略,而缺少图片的孤立 txt 不会被检查。移动完成后,写一个数据描述文件tools_dataset.yaml:
path: /absolute/path/to/dataset train: images/train val: images/val names: 0: gun-type tool 1: hand 2: pliers-type tool 3: pointed tool 4: scanning toolpath建议写绝对路径,训练进程的工作目录经常变化,相对路径会让 ultralytics 找不到数据。names的顺序就是类别 id 的顺序,必须和标签 txt 里的 0-4 一一对应,这里顺序错一位,整个模型的输出语义就全部错位。如果你的解压包里有 valid 目录,直接把val指向images/valid即可。
3.2 训练命令与超参数选择
在 1,873 张图上,我习惯先用轻量骨架做一次快速验证:
yolo detect train \ data=tools_dataset.yaml \ model=yolov8n.pt \ epochs=120 \ batch=16 \ imgsz=640 \ patience=20 \ project=tools_det \ name=baseline_nmodel=yolov8n.pt表示加载 COCO 预训练权重,而不是从随机初始化开始;对工业小数据集来说,这一步能省大量收敛时间。epochs=120在百级批量上足够,patience=20是连续 20 个 epoch 验证集 mAP 不再提升就早停,防止最后过拟合。batch=16配合imgsz=640大约需要 16GB 以上显存,如果显存吃紧,优先把batch降到 8,再把imgsz降到 512,不要同时降两个。
训练结束后,runs/detect/tools_det/baseline_n/weights/下会生成last.pt和best.pt,前者是最后一个 epoch 的权重,后者是验证指标最好的权重。后续验证和部署全部使用best.pt。
3.3 统计各类别样本量,提前发现不均衡
很多人拿到数据集直接训练,跑完发现手部类别 AP 很高,工具类别 AP 很低,回头一查才发现 hand 的框比所有工具加起来还多。所以在第一次训练前,我会先统计一下标签文件中各类别的目标数:
import glob from collections import Counter total = Counter() for txt_path in glob.glob("dataset/labels/train/*.txt"): with open(txt_path, "r", encoding="utf-8") as fp: for line in fp: if line.strip(): total[int(line.split()[0])] += 1 print(total)这段脚本把每个 txt 的第一列取出来做累加,输出类似Counter({1: 3021, 0: 876, 2: 643, 4: 421, 3: 358})的结果。如果 hand 的样本量接近其他类别总和的 2 倍以上,就不需要额外处理太多,因为 hand 本来就是一个高变化度的类别,多一些负样本能降低误报;但如果某个工具类别只有 300 多个目标,接下来就要在数据增强阶段给这个类别更保守的翻转和裁剪策略,避免小类别的形态特征被过度破坏。
4. 数据增强与混淆排查:让模型在反光和遮挡下更稳定
工业场景图片看着干净,但真实推理时经常会遇到镜头抖动、工件遮住工具、金属反光让局部纹理消失等情况。这一类问题不能只靠加数据,要把增强策略稳定住,并且用验证集的混淆矩阵来判断模型到底在哪些类别之间打转。
4.1 用 YOLOv8 内置增强参数模拟产线环境
YOLOv8 允许在数据 YAML 中直接覆盖增强参数,不需要修改代码。我在 baseline 跑通后,会复制一份tools_aug.yaml并追加:
path: /absolute/path/to/dataset train: images/train val: images/val names: 0: gun-type tool 1: hand 2: pliers-type tool 3: pointed tool 4: scanning tool hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.5 degrees: 15 translate: 0.1 scale: 0.4 fliplr: 0.5 mosaic: 0.8 mixup: 0.1hsv_s和hsv_v负责模拟不同灯光下的饱和度与亮度变化,speckle类增强在 ultralytics 中没有直接参数,所以用 HSV 扰动替代。degrees=15只做小角度旋转,超过 30 度会让钳型工具看起来像枪型工具,反而引入标签噪音。mosaic=0.8把四张图拼在一起训练,对小目标检测有提升,但装配工具本身不是小目标,mosaic 过高会把细长工具的语义截断。
在启动训练时把增强 YAML 传给同一个命令:
yolo detect train \ data=tools_aug.yaml \ model=runs/detect/tools_det/baseline_n/weights/best.pt \ epochs=80 \ batch=16 \ imgsz=640 \ patience=15这一步是迁移式微调,从 baseline 的 best.pt 继续训练而不是重新加载 COCO 权重,可以让增强策略在已经收敛的模型上发挥作用,训练时间只有第一次的一半左右。
4.2 验证阶段必须看混淆矩阵而不是只看 mAP
命令行里显示的平均 mAP 只能反映整体水平,看不出“枪型被识别成钳型”这类具体错误。训练结束后,我会单独跑一次验证,并强制保存所有可视化文件:
yolo val \ model=runs/detect/tools_det/tools_aug/weights/best.pt \ data=tools_dataset.yaml \ save_json=True在验证输出目录里找confusion_matrix.png。如果gun-type tool和pliers-type tool之间存在明显的交叉误检,先检查增强参数中degrees是否过大;如果还是混淆,就在标注层面统一标准,比如同一把工具的钳口在 45 度视图中是否仍然标注为 pliers,而不是把不同标注习惯的样本混在一起。另一个高频问题是在hand和工具重叠时,两个框的 IoU 很高,推理时 NMS 很可能把其中一个删掉。遇到这种情况,我会提高iou阈值到 0.6 重新验证,确认模型的原始输出是被后处理抑制还是真的漏检。
4.3 迁移到 YOLOv12 前的基线对比策略
如果你看到 YOLOv12 或其他新结构的发布信息,想换模型再刷一轮精度,我的建议是先把当前 YOLOv8 的结果保存为基线,不要直接迁移。标注格式和 YAML 对 YOLOv12 同样可用,因为这类模型都沿用 COCO 风格的五字段标注,数据端不需要改,但新结构的头模块对不同类别混淆的改善程度不一样。把两个版本的results.csv放到同一张图里,分别对比各类 AP 而不是总 mAP。对于这个工具装配数据集,通常值得关注的不是整体精度提高多少,而是pointed tool这类细长类别是不是真的受益于新注意力机制。如果换了模型只是把 hand 的 AP 从 0.96 提到 0.97,而对 pliers 毫无改善,那产线收益几乎为零,还要额外承担 TensorRT 插件兼容成本。
5. 导出 TensorRT 并实现“手是否持握工具”的判定逻辑
训练完成只是第一步,实际部署到工位边缘盒子时,需要把 PyTorch 权重转成 ONNX 再转 TensorRT,同时在推理代码里加上工具与手的空间关系判断。
5.1 导出固定尺寸 ONNX 和 TensorRT 引擎
yolo export \ model=runs/detect/tools_det/tools_aug/weights/best.pt \ format=onnx \ opset=12 \ simplify=True \ imgsz=640 trtexec --onnx=best.onnx --saveEngine=best.engine --fp16opset=12对 TensorRT 8.x 兼容性较好,simplify=True会删除 ONNX 中冗余 reshape 节点。如果后续部署端的输入分辨率固定为 640x640,就不需要动态 batch,TensorRT 引擎会按静态输入做层融合,推理速度更快。
5.2 用 IoU 判定“手是否接触工具”
from ultralytics import YOLO model = YOLO("best.engine") def box_iou(a, b): inter_w = max(0, min(a[2], b[2]) - max(a[0], b[0])) inter_h = max(0, min(a[3], b[3]) - max(a[1], b[1])) inter = inter_w * inter_h area_a = (a[2] - a[0]) * (a[3] - a[1]) area_b = (b[2] - b[0]) * (b[3] - b[1]) return inter / (area_a + area_b - inter + 1e-6) results = model("frame_0240.jpg", conf=0.35, iou=0.45)[0] boxes = results.boxes.xyxy.cpu().numpy() classes = results.boxes.cls.cpu().numpy().astype(int) hand_boxes = boxes[classes == 1] tool_boxes = boxes[(classes == 0) | (classes == 2) | (classes == 3) | (classes == 4)] for h in hand_boxes: if any(box_iou(h, t) > 0.15 for t in tool_boxes): print("hand holding tool")conf=0.35是工位摄像头这类近距离动态场景的折中选择,如果现场误报多,再升到 0.5。iou=0.45控制 NMS 合并阈值,两个工具重叠时保留置信度更高的框。box_iou里的 0.15 不是随意取的,手和工具只要发生接触,两个框的 IoU 通常在 0.1 到 0.35 之间;低于 0.1 说明手只是靠近,还没拿起来,高于 0.4 则大概率是标注框重叠过大。如果你想判断“手拿着枪型工具对准工件”,可以进一步要求 gun-type tool 的框同时与某个工件区域重叠,这个区域可以在工位投影坐标系里预先划定。
本文还有配套的精品资源,点击获取