news 2026/10/4 23:27:24

螺丝螺母目标检测实战:423张数据集YOLO训练与增强避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
螺丝螺母目标检测实战:423张数据集YOLO训练与增强避坑指南

简介:这是一份面向机械零件识别与目标检测任务的螺丝螺母检测数据集,包含423张已标注的真实场景图片,适合训练螺丝、螺母等小目标识别模型,可用于工业质检、自动化分拣等项目的算法验证与落地实践。压缩包内共428个文件,其中jpg图片423张、txt标注文件3个、Python数据增强脚本1个及label_list类别清单1份,整体体积82.69MB,目录结构便于直接接入常见检测框架使用。标注文件已按目标检测格式整理,读者可快速划分训练集与验证集;附带的增强脚本支持旋转、缩放、亮度调节等操作,可批量扩充样本以提升模型泛化能力,对入门或进阶目标检测开发均具有实用价值。该资源目前已有606人学习下载,适合需要真实工业场景数据开展模型训练与效果调试的开发者参考使用。

1. 螺丝螺母检测数据集423张:先别纠结张数,看标注和增强脚本能不能直接复用

在质检场景里,机械零件识别检测数据集-螺丝螺母目标检测数据集423张带标注文件(附数据增强脚本程序).zip这类压缩包听起来不多,但真正值不值得留,不看423这个数字,而是看三件事:标注文件规不规整、图像有没有覆盖真实工况、数据增强脚本能不能直接跑起来。目标检测项目最怕的不是数据少,而是标注格式混乱、坐标错位、类别定义随意,最后一大半时间耗在清洗数据上。这篇按我处理同类数据集的习惯来写,从解压目录讲到训练参数,再讲透增强脚本的边界和典型坑,让这423张料真正变成能出结果的模型。适合做毕设选题、小批量产线视觉预研,或者刚入手目标检测想找一份短平快练手数据的人。

2. 拆解数据集的zip包:目录结构、标注格式与目标尺寸预检

拿到这类zip,我一般不会双击解压就开训练。先做三件事:看目录组织、确认标注格式、抽查图像分布。这三件事加起来只要十分钟,却决定了后面是直接进训练还是先修数据。对这一类机械零件识别检测数据集,常见的打包结构大概是:images目录放原图,labels或Annotations目录放标注,顶层附一个classes.txt和一个数据增强脚本。下面这张表是典型的文件清单。

顶层目录/文件常见内容说明
images/423张jpg或png原图文件名最好和标注文件同名
labels/每张图对应一个txtYOLO格式标签,一行一个目标
Annotations/每张图对应一个xmlVOC格式,和labels目录二选一
classes.txt每行一个类别名决定模型输出多少个类别
data_augment.py数据增强脚本注意脚本依赖的库版本
README.txt数据集说明与版权信息有它时先读它,能省很多事

如果你解压后发现目录不是这个结构,别慌,大部分是作者按自己的习惯组织。先找classes.txt,它写着类别名;再找后缀是xml、json或txt的标注目录;两者都找到了,这包就能用。要特别注意图片和标注是否同名,这一步决定转换脚本要不要额外做映射。zip在Windows下解压遇到中文目录名乱码的问题很常见,我习惯用Python的zipfile模块解压,编码按zip内元数据走,具体写法放在第5章避坑部分。

2.1 从标注文件后缀判断能不能直接训练:VOC、COCO、YOLO三选一

标注文件决定你能不能把图直接扔进训练。常见有三种格式:VOC的xml里,bndbox节点存的是绝对像素坐标,左上有xmin、ymin,右下有xmax、ymax;COCO的json里,annotations数组每个元素带bbox,格式是[x, y, width, height];YOLO的txt里,每行是类别id和归一化中心坐标、归一化宽高。螺丝螺母这种小物体,YOLO原生txt最省事,VOC和COCO都要转一步。我的习惯是先写个扫描脚本,只解析前几个文件,判断包的真实格式。

# 检查数据集格式:扫描标注目录并解析前3个样本 from pathlib import Path import xml.etree.ElementTree as ET import json root = Path('./机械零件_dataset') labels = root / 'labels' if (root / 'labels').exists() else root / 'Annotations' for f in sorted(labels.glob('*'))[:3]: if f.suffix == '.xml': tree = ET.parse(f) obj = tree.find('object') name = obj.find('name').text box = obj.find('bndbox') xmin = float(box.find('xmin').text) ymin = float(box.find('ymin').text) xmax = float(box.find('xmax').text) ymax = float(box.find('ymax').text) print(f'VOC格式: {f.name} class={name} box=({xmin:.0f},{ymin:.0f},{xmax:.0f},{ymax:.0f})') elif f.suffix == '.json': data = json.loads(f.read_text(encoding='utf-8')) ann = data['annotations'][0] print(f'COCO格式: {f.name} category_id={ann["category_id"]} bbox={ann["bbox"]}') elif f.suffix == '.txt': lines = f.read_text(encoding='utf-8').strip().splitlines() cid, cx, cy, w, h = map(float, lines[0].split()) print(f'YOLO格式: {f.name} class_id={int(cid)} cx={cx:.4f} cy={cy:.4f} w={w:.4f} h={h:.4f}')

这个脚本只取前3个文件,是为了避免你在超大目录上浪费时间。看到输出后,你立刻能判断:如果是VOC或COCO,下一步就要做格式转换;如果是YOLO txt,还要看坐标是否在0到1之间,cx和cy不在这个范围就说明标签已经损坏。参数说明:labels路径要根据实际解压目录调整,如果压缩包里同时存在labels和Annotations两个目录,先看哪个目录的文件数量和images一致,以那个为准。

2.2 423张图的视觉预检:分辨率、目标尺寸与分布盲区

数据下载下来,数量从来不是第一问题,分布才是。CCPD、HRSC2016这类公开数据集都是很好的例子,数据量大但场景单一,换到真实环境照样要重新采样。螺丝螺母是结构稳定的工业零件,423张可能大量集中在同一光照、同一角度,甚至同一个料盘背景。我的做法是跑一个小脚本,统计图像分辨率和每张图的目标数量,确认目标在图中占多大面积。

# 统计图像分辨率与单张目标数分布,判断小目标比例 from pathlib import Path from PIL import Image import numpy as np img_dir = Path('./机械零件_dataset/images') obj_counts = [] for img_path in sorted(img_dir.glob('*.jpg')): w, h = Image.open(img_path).size # 只读头信息,不加载整图 label_path = None for cand in ['labels', 'Annotations']: p = img_path.parent.parent / cand / (img_path.stem + '.txt') if p.exists(): label_path = p break if label_path is not None: n = sum(1 for _ in open(label_path)) obj_counts.append(n) else: obj_counts.append(0) arr = np.array(obj_counts) print(f'图像数量: {len(arr)}') print(f'单张目标数: min={arr.min()}, 中位数={np.median(arr):.0f}, max={arr.max()}')

这段脚本的信息量比想象中大。如果单张目标数的中位数只有1,说明绝大多数图里只有一个零件,训练出来的模型很难处理密集摆放场景;如果max是30以上,又说明存在高度拥挤的极端样本。再看图像分辨率,如果原图都是640x640而螺丝只有20x20,那它就是典型小目标,后面训练imgsz不能开小。参数说明:图片后缀要按实际改成png或bmp;labels和Annotations的路径判断逻辑假设它们和images平级,如果嵌套更深,先把目录结构打平再跑脚本。

3. 用ultralytics练螺丝螺母:环境配置、格式转换与第一个可跑的模型

第2章确认完数据可用,接下来就是把它跑成模型。螺丝螺母这类小目标检测,我几乎固定用YOLO系,不是因为它最先进,而是因为它最适合这个数据量级和部署场景。你不需要在YOLOv8、YOLOv11之间纠结,ultralytics仓库的接口基本一致,下面的流程两个版本都吃。

3.1 为什么螺丝螺母这个小目标场景首选YOLO系而不是Transformer

423张原图加增强后大约几千张,这个规模对检测Transformer来说偏小。YOLO是anchor-based单阶段模型,先验框对螺丝螺母这种固定长宽比的目标很友好,训练收敛快,显存占用低,导出ONNX后随便一个工业相机盒都能跑。检测Transformer当然可以做,但同样的样本量下很难超过同参数的YOLO,推理速度还要再打折。如果是带旋转角度的零件装配场景,你已经能看到像MMRotate训练DOTA数据集那种旋转框方案,但那属于进阶方向,后面第6章再展开。现阶段先把水平框做到位。

3.2 零基础配置ultralytics:conda建环境,验证CUDA可用

目标检测初学者最大的障碍往往不是模型,而是环境装完发现torch版本和CUDA对不上。我一般这样装:

# 用conda创建独立环境,避免把系统Python搞乱 conda create -n bolt_yolo python=3.10 -y conda activate bolt_yolo pip install ultralytics # 验证CUDA是否可用,这一步决定训练是分钟级还是小时级 python -c "import torch; print('CUDA available:', torch.cuda.is_available())"

这个流程的核心是让torch拿到GPU。如果最后一行打印的是CUDA available: False,不要怀疑模型代码,先查显卡驱动和CUDA版本,驱动版本用nvidia-smi看,torch对应的CUDA版本由pip安装时自动匹配。电脑没独显也能跑,训练速度会慢很多,建议先把epochs调小,流程跑通再上完整训练。参数说明:python=3.10是当前最稳的组合,3.12有时会遇到onnx相关的依赖坑;如果你机器上已经有torch的CUDA环境,可以跳过pip install ultralytics里的torch依赖,先装已有torch再装ultralytics。

3.3 把VOC格式转成YOLO格式:转换脚本里的四个关键参数

如果压缩包里的标注是VOC或COCO,直接拿去做YOLO训练会报格式错,或者不报错但模型乱学。我在第2章已经确认过格式,这一步就写转换脚本。核心不是代码本身,而是四个参数:图片真实宽高、类别映射表、归一化边界检查、输出目录。下面脚本按这几个点写:

# VOC转YOLO:核心是从同名图片读取宽高,并按真实尺寸归一化 import xml.etree.ElementTree as ET from pathlib import Path voc_dir = Path('./机械零件_dataset/Annotations') img_dir = Path('./机械零件_dataset/images') out_dir = Path('./机械零件_dataset/labels_yolo') out_dir.mkdir(exist_ok=True) # 注意:这个映射必须和classes.txt逐行对应 class_map = {'screw': 0, 'nut': 1} def convert_xml(xml_path): tree = ET.parse(xml_path) root = tree.getroot() # 从同名图片读宽高,绝不自己猜 img_path = img_dir / (xml_path.stem + '.jpg') if not img_path.exists(): print(f'找不到图片: {img_path}') return w_img, h_img = 0, 0 # 这里用PIL读尺寸,避免cv2在灰度图上读错通道 from PIL import Image w_img, h_img = Image.open(img_path).size lines = [] for obj in root.iter('object'): name = obj.find('name').text.strip() cls_id = class_map.get(name, 0) box = obj.find('bndbox') xmin = float(box.find('xmin').text) ymin = float(box.find('ymin').text) xmax = float(box.find('xmax').text) ymax = float(box.find('ymax').text) # 严格按YOLO归一化公式计算中心坐标和宽高 x_center = (xmin + xmax) / 2 / w_img y_center = (ymin + ymax) / 2 / h_img bw = (xmax - xmin) / w_img bh = (ymax - ymin) / h_img # 越界框直接报警,不要带病训练 if not (0 <= x_center <= 1 and 0 <= y_center <= 1 and bw <= 1 and bh <= 1): print(f'警告: 越界框 {xml_path.name}: cx={x_center:.4f}, cy={y_center:.4f}, w={bw:.4f}, h={bh:.4f}') lines.append(f'{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}') (out_dir / (xml_path.stem + '.txt')).write_text('\n'.join(lines) + '\n', encoding='utf-8') for xml_file in voc_dir.glob('*.xml'): convert_xml(xml_file) print('转换完成,请检查labels_yolo目录')

这段脚本里最容易出问题的两行是w_img和h_img的来源。VOC的xml不存图片尺寸,必须从同名图片读,如果图片实际是1920x1080,你从某个yaml里猜一个640,所有框都会偏移。class_map要和前面classes.txt逐行对一遍,名字对不上,类别id就会错位,模型会把螺丝当螺母学。print里的越界警告不是摆设,出现一条就要找原因,不然训练时模型会学到错误坐标。参数说明:图片后缀按实际改成png;如果图片和标注不同名,先在第2章脚本里把对应关系打出来,建立映射再做批量转换。

3.4 第一次训练的启动命令:epochs、imgsz、batch、patience怎么定

数据准备好后,第一次训练我建议用yolov8s.pt作为预训练权重,而不是从零开始。命令如下:

yolo detect train \ data=bolt.yaml \ model=yolov8s.pt \ epochs=200 \ imgsz=640 \ batch=16 \ patience=30 \ project=./runs_bolt \ name=exp1

这组参数是我处理小样本数据集的默认值。其中bolt.yaml是数据集描述文件,内容至少包含train路径、val路径和nc、names两个字段;如果你把423张按8:2拆成训练和验证,train指向训练集图片目录,val指向验证集图片目录就行。imgsz要结合第2章的统计结果来定,如果螺丝在图中最大不到40x40,建议直接把imgsz加到960甚至1280,代价是显存占用上升。batch=16在8GB显存下是安全线,如果显存只有6GB,先降成8。patience=30表示30个epoch验证指标不涨就自动停,小样本训练最怕死等300个epoch,早停能省很多时间。

4. 增强脚本的参数边界:423张翻到4000张,也要翻对方向

这个压缩包的价值点之一就是带数据增强脚本。增强本身是把423张底图扩充成几千张,但对螺丝螺母这类金属小零件,不是所有增强都安全。高强度的仿射变换会让长螺丝出现离谱透视,颜色增强太狠会让不锈钢螺母亮成白色。增强不只是调参,它是在给模型编造训练分布,编得偏离真实工况,模型就学歪。

4.1 螺丝螺母适用的增强组合与参数建议

下面这张表是我处理同类零件时的参数参考,可以直接抄进脚本里。

增强操作建议参数为什么这样设
水平翻转p=0.5螺丝左右对称,翻转不改变语义
亮度扰动brightness=0.7~1.3模拟车间不同角度的光照波动
小角度旋转degrees=±10模拟零件摆放倾斜,超过30度会产生无意义姿态
高斯噪声sigma=5~15增加传感器噪声鲁棒性
随机裁剪裁剪后resize回原尺寸只裁中间区域,避免切掉零件主体
色彩抖动hsv_v=0.2~0.4只动亮度,别动色相,金属零件颜色信息很敏感

表格里最容易被忽略的是旋转角度的上限。装配线上的螺丝在成像里最多倾斜十几度,你如果给它做90度旋转,等于告诉模型"倒着放的螺丝也是正样本",实际产线根本不会出现这个姿态,模型反而会把正常姿态的特征学偏。亮度扰动也要克制,螺丝在暗场和高光下的纹理差异很大,调太强会让模型去认背景反光而不是认零件轮廓。

4.2 增强脚本的正确写法:图像和标注框要做同一套变换

离线增强脚本最隐蔽的坑,是只处理了图片、没有同步处理标注。图转了30度,标注框还停在原来的位置,训练时模型看到目标位置和标签对不上,loss降不下来不说,还可能直接学出一个"偏移修正网络"。正确写法是让图像和标注框共用同一个变换矩阵,下面这段是旋转增强的示例:

# 旋转增强:图像旋转theta度,标注框由同一矩阵同步变换 import cv2 import numpy as np def rotate_image_and_boxes(img, boxes, angle_deg): h, w = img.shape[:2] center = (w / 2, h / 2) rot = cv2.getRotationMatrix2D(center, angle_deg, 1.0) cos_a, sin_a = abs(rot[0, 0]), abs(rot[0, 1]) # 计算旋转后画布的尺寸,避免边缘被裁剪 new_w = int(h * sin_a + w * cos_a) new_h = int(h * cos_a + w * sin_a) rot[0, 2] += new_w / 2 - center[0] rot[1, 2] += new_h / 2 - center[1] img2 = cv2.warpAffine(img, rot, (new_w, new_h)) new_boxes = [] for box in boxes: # box格式: [xmin, ymin, xmax, ymax] 像素坐标 pts = np.array([[box[0], box[1]], [box[2], box[1]], [box[0], box[3]], [box[2], box[3]]], dtype=np.float32) pts2 = cv2.transform(pts.reshape(-1, 1, 2), rot).reshape(-1, 2) nx_min, ny_min = pts2.min(axis=0) nx_max, ny_max = pts2.max(axis=0) # 旋转后框会外扩,裁剪回画布边界内 nx_min = max(0, nx_min); ny_min = max(0, ny_min) nx_max = min(new_w, nx_max); ny_max = min(new_h, ny_max) new_boxes.append([nx_min, ny_min, nx_max, ny_max]) return img2, new_boxes

这段代码的关键在于,图像的旋转矩阵和标注框角点的变换用的是同一个rot矩阵,而不是对图像转一次、对坐标再算一次。旋转后取四个角点的外接矩形,是为了在保持标注语义的前提下不引入多余的空背景。参数说明:angle_deg建议按4.1表格控制在±10度;如果你的增强脚本还要做缩放和裁剪,记住一个原则——所有几何变换先拼成一个矩阵,再一次性作用于图和框,拆分操作越多越容易错位。

4.3 离线增强和在线增强怎么配合:mosaic与hsv参数

离线增强脚本负责把数据集做大,ultralytics训练时的在线增强负责在训练过程中继续加扰动,两者互补,你不需要二选一。在线增强不需要改数据,在训练命令里追加参数即可:

yolo detect train \ data=bolt.yaml model=yolov8s.pt \ epochs=200 imgsz=640 batch=16 \ hsv_v=0.4 hsv_s=0.7 \ degrees=10 fliplr=0.5 mosaic=0.5

hsv_v是亮度扰动幅度,0.4配合离线脚本的亮度增强会让样本变化更丰富;degrees=10和离线旋转保持一致,避免两个阶段的分布打架;mosaic=0.5表示一半的batch用马赛克拼接,这会显著增加小目标的数量。> 提示:当数据集只有423张时,mosaic不要开到1.0,拼接图太抽象容易让模型学到拼接缝,开0.5是安全值。在线增强的参数在ultralytics不同小版本里名称基本一致,如果你的版本报参数不识别,先yolo detect train --help看当前版本支持的参数名。

5. 螺丝螺母目标检测避坑记录:5个把训练搞翻车的高频问题

数据量小意味着容错率低,一个坑就能让整个训练白跑。下面这5条是我在这些年处理零件检测数据集时踩过的真实问题,按现象、原因、解决的顺序写,希望你不用重走这些弯路。

5.1 解压后文件名乱码,图片和标注对不上

现象:Windows下解压zip后,目录名变成一堆乱码,图片能打开,但labels目录里的文件名和图片对不上,构建数据集时报找不到标注。

原因:压缩包在非Windows环境打包,中文文件名按UTF-8存储,Windows自带解压用本地代码页GBK去解释,名字就坏了。

解决:用Python的zipfile模块解压,Python按zip的flag位正确读取UTF-8元数据,文件名不会再乱。参考写法:

# 用Python解压zip,按包内UTF-8元数据还原文件名 import zipfile from pathlib import Path zip_path = '机械零件识别检测数据集-螺丝螺母目标检测数据集423张带标注文件(附数据增强脚本程序).zip' out_dir = Path('./dataset') out_dir.mkdir(exist_ok=True) with zipfile.ZipFile(zip_path) as zf: for name in zf.namelist(): # 统一路径分隔符,避免Windows下混用/和\ target = out_dir / name.replace('\\', '/') if name.endswith('/'): continue zf.extract(name, out_dir) print('解压完成,请检查dataset目录下的文件名是否正常')

逻辑说明:zipfile在extract时按zip条目记录的编码处理文件名,比Windows资源管理器直接调系统API更可靠。参数说明:out_dir改成你自己的路径;如果解压后还是乱码,用zf.namelist()把所有条目先打印出来,人工核对后再全局解压。

5.2 转换后坐标全是0,训练loss纹丝不动

现象:VOC转YOLO跑完,labels目录里出现cx=0.000000、w=0.000000,训练时loss不降,验证集mAP一直是0。

原因:多数是xml的bndbox解析成了空字符串或带单位字符串,float()转换失败被异常吞掉;少数情况是归一化时把图片宽高写反了,用宽除以高。

解决:先写个小脚本统计非法标注,逐行打印前10个坏样本:

# 快速排查:统计YOLO标注文件里的非法坐标 from pathlib import Path bad = [] for f in Path('./机械零件_dataset/labels_yolo').glob('*.txt'): for line in f.read_text(encoding='utf-8').strip().splitlines(): v = list(map(float, line.split())) if len(v) != 5 or v[2] <= 0 or v[3] <= 0 or v[2] > 1 or v[3] > 1: bad.append((f.name, line)) print(f'非法标注样本数量: {len(bad)}') for name, line in bad[:10]: print(name, line)

这段代码把长度不为5、宽高为负、归一化后大于1的行都挑出来。你看到具体行之后,回到对应xml检查bndbox节点是不是有小数点以外的字符。参数说明:判定条件是v[2]和v[3],即归一化宽高;如果打印出来全是0,大概率是xml路径没对上,解析了空文件。

5.3 增强脚本跑完,标注框和目标错位

现象:增强后拿标注可视化工具打开新图,发现框还在原位置,但目标已经被旋到了另一个角,训练时模型学不到正确位置。

原因:脚本只调用了仿射变换处理图像,没有把标注框做变换;或者用了先裁剪后旋转的拆分步骤,框的原始坐标已经失效。

解决:按第4.2节的方式,把图像和框交给同一个变换矩阵。增强完之后别直接训练,先抽10张图做可视化拼图检查:

# 增强后抽查:把预测框画回图上,肉眼确认对位 import cv2 from pathlib import Path for img_path in list(Path('augmented_images').glob('*.jpg'))[:10]: img = cv2.imread(str(img_path)) label_path = Path('augmented_labels') / (img_path.stem + '.txt') if label_path.exists(): for line in label_path.read_text().strip().splitlines(): cid, xc, yc, bw, bh = map(float, line.split()) x1 = int((xc - bw/2) * img.shape[1]) y1 = int((yc - bh/2) * img.shape[0]) x2 = int((xc + bw/2) * img.shape[1]) y2 = int((yc + bh/2) * img.shape[0]) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imwrite(f'check_{img_path.stem}.jpg', img)

这段脚本把归一化坐标换算回像素坐标,并画框。参数说明:如果框整体偏移但大小不变,是平移没同步;如果框大小和形状不符,是缩放或旋转矩阵没有作用到框上。可视化是增强脚本的后悔药,千万别省。

5.4 验证集mAP很高,换相机拍的照片漏检一半

现象:验证集mAP到了0.9,看着很漂亮,拿到产线用工业相机或手机新拍的照片,漏检率超过一半。

原因:数据集本身场景单一,增强脚本又只做了画风扰动,模型学到的是训练集里特定背景和光照分布,不是螺丝本身的几何特征。更隐蔽的是验证集和训练集来自同一组图的简单拆分,模型过拟合了训练集,验证集也判断不出来。

解决:训练集和验证集来自不同拍摄批次,至少也要按不同料盘分。增强强度按真实工况校准:把产线照片的亮度直方图跑出来,和训练集的亮度分布对比,差太多就降低hsv_v。看指标不要只看mAP50,打开PR曲线看confidence在0.25以下时recall的下滑速度,下滑越快说明模型越虚。

5.5 螺丝目标太小,imgsz=640训练完根本看不见

现象:训练时loss正常,测试时大螺母能找回,小螺丝全漏,mAP50-95比mAP50低一大截。

原因:螺丝在原始图里只有20x20像素,以imgsz=640、stride=32计算,下采样后的特征图上只剩不到一个像素,特征全被卷积吃掉了。

解决:imgsz加到960甚至1280,让小目标在特征图上多占几个点;或者把原始大图裁成几个不重叠的patch再检测,相当于把小目标放大,检测完再把框映射回原图坐标。如果装配角度是个主要干扰源,再考虑上旋转目标检测框架,比如MMRotate那套DOTA训练管线,但先确认是尺寸问题还是角度问题,别一上来就换框架。

6. 最后一步:用没进过训练集的实拍图验收模型效果

训练结束不代表能上线,模型是自己人,但实拍图是裁判。每次拿到这类数据集的模型,我先不看测试集指标,而是找一批没参与过训练、甚至没参与过验证的实拍照片来验收。

6.1 用一批没进过训练的照片做批量推理验收

把实拍图放进一个干净目录,然后跑推理:

yolo detect predict \ model=runs_bolt/exp1/weights/best.pt \ source=./real_capture \ imgsz=960 conf=0.25 iou=0.5

output目录里会生成带框的标注图,打开看三件事:漏检的目标有多少、框贴得紧不紧、有没有把背景零件误报成螺丝。如果漏检集中在某个角度,回到增强脚本补那个角度的离线增强;如果框普遍偏大或偏小,检查标注转换时是否读错了图片尺寸。这个环节比mAP数字可靠得多,因为测试集和训练集同源时,mAP天然虚高。

6.2 效果不够时的两个进阶方向

如果水平框已经做到极限,再往上走有两个方向。一是从目标检测切到旋转目标检测,像MMRotate训练DOTA数据集那样,给螺丝加旋转角标签,适用于装配线上零件朝向混乱的场景;二是从固定类别走向开放词汇目标检测,让模型能处理"没见过的零件",但423张这个体量支撑不起大规模开放词汇训练,多半还要借力预训练模型。如果目标本身是设备健康管理而不是视觉定位,那该去研究的是PHM2012这类带退化标签的数据集,而不是检测包。

我现在拿到任何一种zip数据集,第一件事永远是打开看几十张原图和标注框,第二件事才是跑训练。这个习惯让我少翻了很多次车,模型是个黑匣子,但数据不是。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 23:21:54

离线蓝屏修复工具实战:从STOP错误码到PE命令行修复

简介&#xff1a;完美蓝屏修复工具是一款面向Windows系统用户的轻量级辅助工具&#xff0c;专门解决内核模式驱动程序或子系统引发非法异常而导致的蓝屏崩溃问题。与传统重装系统相比&#xff0c;它提供一键化检测与修复机制&#xff0c;普通用户、系统维护人员及运维初学者均可…

作者头像 李华
网站建设 2026/10/4 23:19:01

浏览器端侧视觉AI工程实践:神经网络在标签页实时推理

1. 项目概述&#xff1a;当视觉AI不再依赖服务器&#xff0c;而是在你打开的标签页里实时呼吸 “把神经网络塞进一个浏览器标签页”——这句话乍听像一句技术圈的玩笑话&#xff0c;但过去三年里&#xff0c;我亲手在 Chrome、Edge、Safari 上跑过 YOLOv5s 的实时目标检测&…

作者头像 李华
网站建设 2026/10/4 23:07:32

C# TCP/IP最简例程:TcpClient与TcpListener服务端客户端互通指南

简介&#xff1a;面向C#初学者的TCP/IP通信例程包&#xff0c;内含服务端与客户端两个独立完整模块&#xff0c;清晰演示了传输控制协议下如何通过TcpListener、TcpClient和Socket类完成建立连接、发送数据与接收响应的全过程&#xff0c;适合刚刚接触网络编程、希望快速跑通首…

作者头像 李华
网站建设 2026/10/4 23:03:28

会议室预定系统微服务实战:SpringCloud+分布式锁+分布式事务

去年接了一个会议室预定系统的项目&#xff0c;需求方把技术栈圈得很死&#xff1a;SpringBoot Vue SpringCloud&#xff0c;而且明确要求做成微服务分布式架构&#xff0c;不能拿单体应用糊弄。心里第一反应是&#xff0c;会议室预定这种业务也要上微服务&#xff1f;但做完…

作者头像 李华
网站建设 2026/10/4 22:54:53

OpenClaw人人养虾:Kilocode 接入 Kilo Gateway 的 API Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华