机械零件识别检测数据集:423张螺丝螺母标注文件实战指南

发布时间:2026/10/10 7:11:42
机械零件识别检测数据集:423张螺丝螺母标注文件实战指南 简介这份资源面向从事机械零件视觉检测的算法工程师、高校学生及工业质检开发者提供螺丝螺母目标检测任务的完整数据集可用于训练与验证YOLO、Faster R-CNN等主流检测模型解决工业场景下零件识别样本不足的问题。压缩包共428个文件以423张jpg图像为主体另含3个txt标注文件、1个label_list类别列表和1个py数据增强脚本整体约82.69MB标注格式可直接对接常见检测框架。数据增强脚本可用于扩充样本、提升模型泛化能力label_list则明确了类别定义便于快速完成数据加载与训练配置。目前已有606人学习下载适合需要快速搭建机械零件检测基线、验证算法效果或开展课程设计的读者参考使用。1. 机械零件识别检测数据集423张螺丝螺母标注文件到底能跑出什么结果产线上掉一颗螺丝没装质检环节靠人眼盯到下午三点就开始漏检这是很多做机械零件视觉检测的团队都会遇到的场景。机械零件识别检测数据集-螺丝螺母目标检测数据集423张带标注文件(附数据增强脚本程序).zip 这个标题核心讲的就是一件事用一份小规模、带标注、带增强脚本的螺丝螺母图像数据集把目标检测模型在机械零件场景里跑通。它解决的不是“从零造数据集”的问题而是“我手头只有几百张图怎么让模型真正识别出螺丝、螺母、垫片这类小目标”的问题。适合三类人刚接触目标检测想找一个真实工业场景练手的工程师、需要快速验证产线视觉方案可行性的算法同学、以及手里有类似小数据集但不知道怎么扩增和调参的从业者。423张这个量级不算大但恰恰是大多数工业现场的真实起点能不能用好取决于你对标注质量、增强策略和评估方式的理解。2. 螺丝螺母数据集的结构拆解与标注格式选择2.1 423张图里通常包含什么拿到一个机械零件目标检测数据集第一件事不是急着训练而是把目录结构和标注文件翻一遍。常见的组织方式是这样dataset/ ├── images/ │ ├── 001.jpg │ ├── 002.jpg │ └── ... ├── labels/ │ ├── 001.txt │ ├── 002.txt │ └── ... ├── classes.txt └── augment.pyimages放原图labels放标注classes.txt定义类别名augment.py是数据增强脚本。螺丝螺母场景里类别通常不会太多常见的是screw、nut、washer、bolt这几类有些数据集会把不同规格的螺丝合并成一类有些会按 M3、M4、M5 分开。我的建议是如果你只是做“有没有装”的判断合并成大类就够了如果你要做规格分拣那类别粒度必须和产线需求对齐否则模型学出来的边界会很模糊。标注格式方面YOLO 系列用的是归一化后的class_id x_center y_center width height每行一个目标坐标都是 0 到 1 之间的小数。COCO 格式则是 JSON包含images、annotations、categories三个顶层字段。VOC 是 XML每个文件对应一张图。这份数据集标题里写的是“带标注文件”没有明确说是哪种格式但从“附数据增强脚本程序”这个描述看大概率是 YOLO 格式因为增强脚本通常直接操作images和labels两个目录。提示拿到数据集先确认标注格式用head看几行 label 文件如果每行是 5 个数字且第一个是整数基本就是 YOLO 格式。2.2 为什么小目标检测要特别关注标注精度螺丝螺母在图像里往往只占几十个像素标注框偏几个像素IOU 就从 0.7 掉到 0.5 以下。我见过一个案例标注员把螺母的内圈当成了外圈模型训练 loss 一直降不下去最后可视化才发现标注框普遍偏小。对于 423 张这个量级的数据集标注错误的影响会被放大因为模型没有足够多的样本去“平均掉”噪声。检查标注质量的一个实用方法是把 label 画回原图import cv2 import os img_dir dataset/images label_dir dataset/labels save_dir check_vis os.makedirs(save_dir, exist_okTrue) for name in os.listdir(label_dir): img_path os.path.join(img_dir, name.replace(.txt, .jpg)) img cv2.imread(img_path) h, w img.shape[:2] with open(os.path.join(label_dir, name)) as f: for line in f: cls, xc, yc, bw, bh map(float, line.strip().split()) # YOLO 格式转像素坐标 x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(os.path.join(save_dir, name.replace(.txt, .jpg)), img)这段代码的逻辑很直接读 label 文件把归一化坐标还原成像素坐标画框保存。参数上唯一需要注意的是name.replace(.txt, .jpg)这里假设图片是 jpg 格式如果你的数据集是 png要相应改掉。跑完之后随机抽 20 张看一遍如果框明显偏了或者漏标先修标注再谈训练否则后面所有调参都是在错误的基础上做优化。2.3 类别不平衡在螺丝螺母场景里的表现机械零件数据集里螺丝的数量通常远多于螺母和垫片因为一颗螺丝可能配一个螺母但垫片不一定每处都有。这种类别不平衡会导致模型对少数类召回率偏低。一个简单的判断方法是统计每个类别的标注框数量from collections import Counter counter Counter() with open(dataset/labels/all.txt) as f: for line in f: counter[int(line.split()[0])] 1 for cls_id, count in sorted(counter.items()): print(fclass {cls_id}: {count} boxes)如果发现某个类别占比低于 10%就要考虑在增强阶段做针对性过采样或者用 focal loss 这类对不平衡更鲁棒的损失函数。不过对于 423 张这个量级我更倾向于先做数据增强把少数类补上来而不是直接改损失函数因为小数据集上损失函数的改动很容易让训练变得不稳定。3. 用数据增强脚本把 423 张扩到可用规模3.1 增强脚本通常包含哪些操作标题里提到的“数据增强脚本程序”在机械零件场景下一般会包含几何变换和光度变换两类。几何变换包括随机旋转、平移、缩放、水平翻转光度变换包括亮度调整、对比度调整、加噪声、模糊。对于螺丝螺母旋转是最重要的增强方式因为产线上零件摆放角度是随机的如果训练集里螺丝都是水平放置模型遇到竖直螺丝就会翻车。一个典型的增强脚本会这样组织import cv2 import numpy as np import os import random def augment_image(img, labels): h, w img.shape[:2] # 随机旋转 -180 到 180 度 angle random.uniform(-180, 180) M cv2.getRotationMatrix2D((w / 2, h / 2), angle, 1.0) img_rot cv2.warpAffine(img, M, (w, h)) # 旋转后需要重新计算标注框这里简化处理实际要按角点变换 # 随机亮度调整 alpha random.uniform(0.7, 1.3) beta random.randint(-30, 30) img_aug cv2.convertScaleAbs(img_rot, alphaalpha, betabeta) return img_aug, labels img_dir dataset/images label_dir dataset/labels out_img_dir dataset_aug/images out_label_dir dataset_aug/labels os.makedirs(out_img_dir, exist_okTrue) os.makedirs(out_label_dir, exist_okTrue) for name in os.listdir(img_dir): img cv2.imread(os.path.join(img_dir, name)) label_path os.path.join(label_dir, name.replace(.jpg, .txt)) with open(label_path) as f: labels f.readlines() for i in range(3): # 每张图生成 3 个增强版本 aug_img, aug_labels augment_image(img, labels) cv2.imwrite(os.path.join(out_img_dir, f{name[:-4]}_aug{i}.jpg), aug_img) with open(os.path.join(out_label_dir, f{name[:-4]}_aug{i}.txt), w) as f: f.writelines(aug_labels)这段代码的逻辑是对每张原图做旋转和亮度调整生成 3 个增强版本图片和标注文件同步保存。参数上alpha控制对比度beta控制亮度偏移range(3)控制增强倍数。需要注意的是旋转之后标注框的坐标必须重新计算上面代码里为了简洁没有展开实际使用时要用旋转矩阵对四个角点做变换再取外接矩形。注意增强不是越多越好。423 张扩到 2000 张左右通常能带来明显提升扩到 10000 张以上如果增强方式单一反而会让模型过拟合到增强后的伪分布上。3.2 针对小目标的增强策略螺丝螺母属于小目标常规的随机裁剪增强对小目标不友好因为裁剪后目标可能被裁掉一半。更合适的做法是马赛克增强Mosaic把 4 张图拼成一张这样每张图里的目标相对变小但模型能看到更多上下文。YOLOv5 和 YOLOv8 都内置了 Mosaic如果你用的是这份数据集自带的增强脚本可能没有这个功能可以手动加def mosaic_augment(img_list, label_list, output_size640): # 取 4 张图拼成 2x2 s output_size // 2 mosaic_img np.zeros((output_size, output_size, 3), dtypenp.uint8) mosaic_labels [] positions [(0, 0), (s, 0), (0, s), (s, s)] for idx, (img, labels) in enumerate(zip(img_list, label_list)): img_resized cv2.resize(img, (s, s)) x_offset, y_offset positions[idx] mosaic_img[y_offset:y_offset s, x_offset:x_offset s] img_resized # 标注坐标需要按比例缩放并加上偏移 for line in labels: cls, xc, yc, bw, bh map(float, line.strip().split()) new_xc (xc * s x_offset) / output_size new_yc (yc * s y_offset) / output_size new_bw bw * s / output_size new_bh bh * s / output_size mosaic_labels.append(f{int(cls)} {new_xc:.6f} {new_yc:.6f} {new_bw:.6f} {new_bh:.6f}\n) return mosaic_img, mosaic_labelsMosaic 的核心价值在于让模型在单张图里看到不同尺度、不同背景的零件对小目标检测的泛化能力提升很明显。参数上output_size一般设 640和 YOLO 的输入尺寸对齐。如果你的显卡显存有限可以降到 416 或 320但小目标检测不建议低于 416否则螺丝在特征图上只剩几个像素模型根本学不到。3.3 增强后的数据划分与验证集构建增强完之后不能把所有图混在一起随机划分因为同一张原图增强出来的多个版本如果同时出现在训练集和验证集验证指标会虚高。正确的做法是按原图划分再对训练集做增强import os import random import shutil random.seed(42) all_images [f for f in os.listdir(dataset/images) if f.endswith(.jpg)] random.shuffle(all_images) split int(len(all_images) * 0.8) train_imgs all_images[:split] val_imgs all_images[split:] for phase, imgs in [(train, train_imgs), (val, val_imgs)]: os.makedirs(fsplit/{phase}/images, exist_okTrue) os.makedirs(fsplit/{phase}/labels, exist_okTrue) for img_name in imgs: shutil.copy(fdataset/images/{img_name}, fsplit/{phase}/images/{img_name}) shutil.copy(fdataset/labels/{img_name.replace(.jpg, .txt)}, fsplit/{phase}/labels/{img_name.replace(.jpg, .txt)})这段代码按 8:2 划分训练集和验证集random.seed(42)保证每次划分结果一致方便复现。划分完之后只对split/train做增强split/val保持原图这样验证指标才能反映模型在真实数据上的表现。423 张按 8:2 分验证集大概 85 张对于小数据集来说这个验证集规模偏小指标波动会比较大建议做 5 折交叉验证取平均指标作为最终参考。4. 训练螺丝螺母检测模型的参数配置与踩坑记录4.1 YOLOv8 训练配置的最小可用命令假设你已经把数据整理成 YOLO 格式并且写好了data.yamlpath: ./split train: train/images val: val/images nc: 4 names: [screw, nut, washer, bolt]训练命令用 YOLOv8 的话是这样yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience50 \ augmentTrue \ mosaic1.0 \ projectruns/screw_nut \ nameexp1参数上modelyolov8n.pt用的是 nano 版本参数量小适合小数据集快速验证。epochs200配合patience50如果 50 轮验证指标没提升就提前停止。lr00.01是初始学习率小数据集上可以降到 0.001 避免震荡。mosaic1.0表示 100% 使用 Mosaic 增强如果发现训练后期 loss 波动大可以在最后 20 轮关掉 Mosaic让模型在真实分布上微调。提示小数据集训练时batch16可能偏大如果显存不够改成 8 或 4同时把lr0按比例调小。4.2 螺丝螺母检测的 3 个必调参数第一个是imgsz。螺丝螺母在 640 分辨率下可能只有 20 到 30 个像素如果原图分辨率很高建议用imgsz1280训练但显存占用会翻倍。一个折中方案是训练用 640推理用 1280YOLOv8 支持rect推理模式可以在不重新训练的情况下提升小目标召回。第二个是conf阈值。默认推理时conf0.25但螺丝螺母场景下背景干扰少可以适当提高到 0.4 到 0.5减少误检。如果发现漏检多再降到 0.2 试试。这个参数没有绝对最优值要在验证集上画 P-R 曲线找拐点。第三个是iou阈值。NMS 阶段默认iou0.7如果螺丝密集排列相邻螺丝的框重叠度高可以降到 0.5 避免误抑制。我遇到过一排螺丝紧挨着的情况iou0.7时中间那颗直接被 NMS 干掉了降到 0.5 才正常检出。4.3 训练过程中的常见翻车现象现象一loss 从第一轮就不降。原因通常是标注格式不对比如 label 文件里坐标没有归一化或者类别 id 从 1 开始而不是 0。解决方法是拿一张图手动算一遍确认坐标在 0 到 1 之间类别 id 从 0 开始。现象二验证集 mAP 很高但实际推理漏检严重。原因是验证集和训练集分布太接近模型过拟合了。解决方法是检查验证集是否包含了不同角度、不同光照的样本如果都是同一批增强图指标没有参考价值。现象三训练到一半 loss 突然变成 NaN。原因通常是学习率太大或者 batch 里有脏数据。解决方法是把lr0降到 0.001同时检查有没有 label 文件为空或者坐标超出 0 到 1 范围。现象四模型把螺丝和螺母混为一类。原因是这两类在低分辨率下纹理太像模型区分不开。解决方法是提高输入分辨率或者在分类头之前加一个注意力模块让模型关注螺纹和六角形的局部特征。现象五推理速度远低于预期。原因可能是imgsz设得太大或者用了 CPU 推理。解决方法是确认device0走 GPU同时用halfTrue开启 FP16 推理速度能提升 30% 到 50%。5. 小数据集检测的进阶技巧从 423 张到产线可用5.1 用预训练权重做领域适配423 张图从零训练基本不可能收敛到可用精度必须用预训练权重。YOLOv8 在 COCO 上预训练的权重已经学到了边缘、角点、纹理等底层特征这些特征对螺丝螺母同样有效。加载yolov8n.pt后冻结 backbone 前 10 层训练 20 轮再解冻全部训练 100 轮这个两阶段策略在小数据集上比直接端到端训练稳定得多。# 第一阶段冻结 backbone yolo detect train datadata.yaml modelyolov8n.pt epochs20 freeze10 lr00.001 # 第二阶段解冻全部 yolo detect train datadata.yaml modelruns/screw_nut/exp1/weights/best.pt epochs100 lr00.0005freeze10表示冻结前 10 层lr00.001比默认值小因为只训练检测头学习率太大会破坏预训练特征。第二阶段用第一阶段的最好权重作为起点学习率再降一半让模型在目标任务上精细调整。5.2 用 TTA 和模型集成提升召回测试时增强TTA是在推理阶段对同一张图做多种变换把结果融合。YOLOv8 支持augmentTrue开启 TTAyolo detect predict modelbest.pt sourcetest_images augmentTrue conf0.3 iou0.5TTA 对小目标检测的召回提升通常在 2 到 5 个百分点代价是推理速度慢 3 倍左右。如果产线节拍允许这个开销是值得的。模型集成则是训练多个不同初始化的模型推理时取并集或投票。对于 423 张的数据集我一般训练 3 个模型分别用不同的随机种子和数据划分推理时把 3 个模型的框做加权 NMSmAP 能再提升 3 到 8 个点。5.3 一个容易被忽略的技巧负样本挖掘螺丝螺母检测的误检主要来自背景中的圆形反光、螺纹状纹理。这些负样本如果不在训练集里模型就会把它们当成目标。一个实用的做法是用训练好的模型在产线视频上跑一遍把误检的帧截下来人工确认后加入训练集作为负样本label 文件为空。这个过程迭代两到三轮误检率能下降一个数量级。# 从视频中提取误检帧 import cv2 cap cv2.VideoCapture(line_video.mp4) frame_idx 0 while True: ret, frame cap.read() if not ret: break if frame_idx % 30 0: # 每秒取一帧 cv2.imwrite(fhard_neg/{frame_idx}.jpg, frame) frame_idx 1这段代码每隔 30 帧保存一张图作为候选负样本。保存后需要人工过一遍把确实没有目标的图留下有目标的图重新标注后加入训练集。负样本挖掘是小数据集提升精度的性价比最高的手段之一但很多人会忽略因为标注负样本没有“新增类别”那么有成就感。5.4 验证模型是否真的可用的三个指标第一个是每类召回率。整体 mAP 高不代表每个类都好如果螺母的召回只有 0.6产线上就会漏装。用yolo detect val输出的 per-class 指标逐个检查低于 0.8 的类别要针对性补数据。第二个是不同光照条件下的稳定性。把验证集按亮度分成三组分别算 mAP如果暗光组比正常组低 20 个点以上说明模型对光照敏感需要在增强里加更多亮度变换。第三个是推理延迟。产线节拍如果是 500ms 一个零件模型推理加后处理必须控制在 300ms 以内。用yolo detect benchmark测一下实际延迟如果超标换更小的模型或者降低输入分辨率。我自己的习惯是每次训练完先看 per-class 召回再看混淆矩阵最后在验证集上跑一遍可视化随机抽 50 张看有没有明显漏检和误检。这三步走完基本能判断模型能不能上产线试跑。423 张的数据集不大但只要标注干净、增强合理、评估到位跑出一个能用的螺丝螺母检测模型是完全可行的。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询