ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PCB缺陷检测数据集与YOLO11训练全流程:1000张图、三种标签格式落地指南

PCB缺陷检测数据集与YOLO11训练全流程:1000张图、三种标签格式落地指南 简介这份资源面向从事工业质检与目标检测算法训练的开发者提供PCB板表面缺陷检测数据集可用于搭建缺陷识别模型或作为通用工业场景数据的补充。数据集真实采集多款PCB板高清表面图像涵盖俯拍正拍与旋转拍摄姿态标注missing_hole、mouse_bite、open_circuit、short、spur、spurious_copper六个缺陷类别采用labelimg标注质量较高。资源包内含1个PDF文件大小约6.92MBPDF中说明数据集基本情况与获取方式并附VOC、COCO、YOLO三种格式标签的说明可直接用于YOLO等算法训练。此外还提供YOLO11一键训练脚本支持GPU、CPU及Mac多平台方案并附博主训练结果日志供参考。目前已有974人学习适合需要快速开展PCB缺陷检测实验的读者获取完整数据与训练支持。1. PCB缺陷检测数据集1000张图、三种标签格式与YOLO11一键训练到底怎么落地手上拿到一块刚回流的PCB焊盘拉尖、线路缺口、阻焊起泡这些缺陷靠人眼在放大镜下一个个看一天下来眼睛发花还容易漏检。工业质检场景里PCB板表面缺陷检测是目标检测落地最密集的方向之一而真正卡住大多数人的不是模型结构是数据。这个标题讲的是一套已经整理好的PCB缺陷数据集1000张图配VOC、COCO、YOLO三种格式标签外加一套能在GPU、CPU、Mac三平台跑起来的YOLO11一键训练脚本。它解决的是从零标注到模型跑通之间那段最耗时的脏活适合想快速验证PCB缺陷检测可行性、又不想在数据格式转换上反复翻车的人。下面按数据长什么样、格式怎么选、脚本怎么跑、坑在哪一层层拆开。2. 先看清数据1000张PCB图里到底有什么2.1 缺陷类别与图像特点PCB表面缺陷检测的类别划分不同产线口径不完全一样但常见做法是围绕几类高频缺陷建标签短路short、开路/断线open、缺口mousebite、毛刺spur、铜渣spurious copper、针孔pinhole等。1000张图的规模不算大属于小样本验证级别够跑通流程、看趋势但不足以直接上产线。图像来源一般是工业相机在固定工位拍的板面局部分辨率参差有的接近500×500有的上千像素缺陷目标普遍偏小一个缺口可能只占几十个像素。这带来两个直接影响。第一小目标检测对输入分辨率敏感YOLO11默认的640输入会把小缺陷进一步缩小训练时建议把imgsz提到960甚至1280代价是显存和速度。第二类别不均衡很常见短路、开路样本多针孔、铜渣样本少直接训练会让模型偏向多数类。我一般会先统计每类框数量心里有数再决定要不要做重采样或加类别权重。提示拿到数据集第一件事不是开训是统计类别分布和框尺寸分布这两组数字决定了后面所有参数怎么设。2.2 三种标签格式的差异与选择VOC、COCO、YOLO三种格式不是随便给的它们对应不同的下游工具链。VOC是XML一个图一个文件字段直观适合用labelImg这类工具继续改标COCO是单个JSON把所有图、类别、框、分割信息塞在一起适合做多任务或接COCO预训练权重YOLO是每图一个txt每行类别 中心x 中心y 宽 高全部归一化到0~1是Ultralytics训练直接吃的格式。格式文件形态坐标表示典型用途VOC每图一个XML绝对像素 xmin/ymin/xmax/ymax标注修改、传统框架COCO单个JSON绝对像素 [x,y,w,h]多任务、COCO预训练YOLO每图一个txt归一化 cx,cy,w,hUltralytics YOLO训练选哪个取决于你要干什么。只想跑YOLO11直接用YOLO格式省一次转换。想接别的检测框架或做实例分割扩展COCO更通用。想手工核对标注质量VOC的XML最方便逐张看。三种格式并存的价值在于你不用为了换框架重新标一遍。2.3 目录结构怎么摆才不乱数据集目录如果一开始不规划好后面脚本路径会到处报错。我一般按下面这种结构摆训练脚本里所有路径都相对这个根目录pcb_defect/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ ├── annotations_voc/ ├── annotations_coco.json └── data.yamlimages和labels下按train/val分YOLO格式的txt和图片同名同目录层级。VOC的XML单独放annotations_vocCOCO的JSON放根目录。data.yaml是Ultralytics训练入口内容大致是path: ./pcb_defect train: images/train val: images/val nc: 6 names: [short, open, mousebite, spur, spurious_copper, pinhole]nc是类别数names顺序必须和标签里的类别索引严格对应错一位整个训练就废了。这个对应关系是新手最容易翻车的地方后面避坑章节会细说。3. 格式转换VOC/COCO/YOLO互转的脚本与参数3.1 VOC转YOLO归一化坐标怎么算VOC的XML给的是绝对像素的xmin/ymin/xmax/ymaxYOLO要的是归一化的中心点和宽高。转换核心就四行公式但边界处理容易出错。import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, img_w, img_h, class_map): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_map: continue cls_id class_map[cls_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) # 裁剪到图像边界防止标注越界 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) return lines逻辑说明先解析XML拿到每个object的类别名和框坐标用class_map把类别名映射成从0开始的整数索引。裁剪那四行是关键标注时手抖画出图像边界的框如果不裁归一化后会出现负数或大于1的值YOLO训练时直接报错或产生异常梯度。最后按类别 cx cy w h拼行保留6位小数足够精度。参数说明img_w、img_h必须和图片真实尺寸一致不能想当然用固定值PCB图分辨率不统一写死会全错。class_map建议单独维护一个字典和data.yaml里的names顺序对齐改类别时两处一起改。3.2 COCO转YOLO批量处理与类别映射COCO的JSON里images、annotations、categories三个数组靠id关联转换时要先建两个映射image_id到文件名的映射category_id到连续索引的映射。注意COCO的category_id不一定是0、1、2连续可能是1、3、7这种必须重映射否则YOLO的类别索引会跳号。import json def coco_to_yolo(json_path, out_dir, class_map): with open(json_path, r) as f: data json.load(f) img_info {img[id]: img for img in data[images]} # 按图片聚合标注 from collections import defaultdict per_img defaultdict(list) for ann in data[annotations]: per_img[ann[image_id]].append(ann) for img_id, anns in per_img.items(): info img_info[img_id] w, h info[width], info[height] fname os.path.splitext(info[file_name])[0] .txt lines [] for ann in anns: cat_name next(c[name] for c in data[categories] if c[id] ann[category_id]) if cat_name not in class_map: continue cls_id class_map[cat_name] x, y, bw, bh ann[bbox] # COCO是左上角x,y加宽高 cx (x bw / 2) / w cy (y bh / 2) / h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw/w:.6f} {bh/h:.6f}) with open(os.path.join(out_dir, fname), w) as f: f.write(\n.join(lines))逻辑说明COCO的bbox是[左上x, 左上y, 宽, 高]和VOC的[xmin,ymin,xmax,ymax]不一样转换时先加宽高的一半得到中心点。类别名通过遍历categories按id反查再走class_map映射成连续索引。按image_id聚合标注是为了每张图只写一个txt。参数说明out_dir要和图片目录层级对应train的图转出的txt放train的labels下。class_map同样要和data.yaml对齐。如果COCO里带iscrowd字段值为1的标注建议跳过那是密集区域标记不适合当普通目标框训练。3.3 转换后怎么验证没转错转完不验证等于没转。我一般做三件事一是随机抽10张图用脚本把YOLO的归一化坐标还原成像素框画到图上肉眼看框是否贴合缺陷二是统计每类框数量和原始VOC/COCO的统计对比数量对不上说明有类别被漏映射三是检查有没有空txt或坐标越界。import cv2 def draw_yolo_box(img_path, label_path, names): img cv2.imread(img_path) h, w img.shape[:2] with open(label_path) as f: for line in f: cid, cx, cy, bw, bh map(float, line.split()) x1 int((cx - bw/2) * w) y1 int((cy - bh/2) * h) x2 int((cx bw/2) * w) y2 int((cy bh/2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, names[int(cid)], (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.imwrite(check.jpg, img)这段把归一化坐标乘回图像宽高画框加类别名存成check.jpg。抽几张不同类别的图看一眼框歪了、类别串了立刻能发现。这一步花五分钟能省掉训练几小时后发现标签全错的后悔药。4. YOLO11一键训练脚本三平台怎么跑通4.1 环境准备与依赖安装YOLO11走Ultralytics的包安装本身不复杂但三平台差异主要在PyTorch的算力后端。GPU机器装CUDA版torchCPU机器装CPU版Mac装MPS版。常见做法是先建虚拟环境再装避免污染系统Python。# 建环境 python -m venv pcb_env source pcb_env/bin/activate # Windows用 pcb_env\Scripts\activate # 装Ultralytics它会自动拉对应torch pip install ultralytics # 验证装的是哪个后端 python -c import torch; print(torch.cuda.is_available(), torch.backends.mps.is_available())逻辑说明ultralytics包依赖torchpip会自动装但自动装的版本不一定匹配你的CUDA。如果GPU机器上torch.cuda.is_available()返回False说明装成了CPU版要去PyTorch官网按CUDA版本重装。Mac上MPS可用时返回True训练会自动走MPS。参数说明CUDA版本要和显卡驱动匹配驱动太老就升驱动或降CUDA。Mac的MPS在部分算子上还不完整遇到不支持的操作会回退CPU速度会掉这是正常现象。4.2 一键训练脚本的写法与关键参数所谓一键训练本质是把model.train()的参数封装好让不同平台只改一个device参数。下面是一个可直接用的脚本骨架from ultralytics import YOLO import torch def pick_device(): if torch.cuda.is_available(): return 0 # 第一块GPU if torch.backends.mps.is_available(): return mps # Mac return cpu def train(data_yamlpcb_defect/data.yaml): model YOLO(yolo11n.pt) # n版最轻小数据集够用 model.train( datadata_yaml, epochs100, imgsz960, # 小缺陷提高输入分辨率 batch8, # 显存不够就降到4 devicepick_device(), workers4, patience20, # 20轮没提升就早停 projectruns_pcb, nameexp1 ) if __name__ __main__: train()逻辑说明pick_device按优先级自动选GPU、Mac、CPU这样同一份脚本三平台都能跑不用手改。YOLO(yolo11n.pt)加载预训练权重做迁移学习小数据集从零训几乎不可能收敛必须用预训练。imgsz960是针对PCB小缺陷的关键调整默认640会丢细节。参数说明epochs100起步配合patience20早停避免过拟合空跑。batch受显存限制8G显存跑960输入大概能到8不够就降。workers是数据加载线程Windows上设太高有时会卡4比较稳。project和name决定结果存哪方便多次实验对比。4.3 GPU、CPU、Mac三平台的实测差异三平台跑同一个脚本差异主要在速度和显存。GPU上960输入、batch 81000张图一个epoch大概几十秒到一两分钟100轮几小时内能完。CPU上同样配置会慢一个数量级一个epoch可能十几分钟适合验证流程但不适合调参。Mac的MPS介于两者之间比CPU快但不如独显且部分算子回退时速度波动大。平台device值相对速度适用场景NVIDIA GPU0最快正式训练、调参Apple Siliconmps中等本地验证、小规模CPUcpu最慢流程跑通、无卡环境实际经验是调参阶段一定用GPUCPU只用来确认脚本没写错、数据能读进去。Mac适合个人开发者没有独显时做小规模实验但别指望它跑大规模搜索。5. 训练避坑PCB缺陷检测最容易翻车的五件事5.1 类别索引和names顺序错位现象训练能跑起来loss也在降但推理时框的位置对、类别全错或者某类永远检不出。原因标签里的类别索引和data.yaml的names列表顺序不一致比如标签里0是shortyaml里0写成了open。解决转换脚本里的class_map和data.yaml的names用同一份定义生成别手写两遍。训练前跑一遍统计打印每类框数量和预期对比。5.2 小缺陷被默认分辨率吃掉现象模型对大缺陷检出正常针孔、铜渣这类小目标几乎全漏。原因imgsz640下原本几十像素的缺陷被缩到十几像素特征图上下采样几次就没了。解决把imgsz提到960或1280同时batch相应调小防显存溢出。如果还不行考虑切图训练把大图裁成小块分别标。5.3 标注框越界导致训练报错现象训练启动时报坐标超出范围或loss出现nan。原因VOC/COCO转YOLO时没裁剪边界归一化后出现负数或大于1的值。解决转换脚本里加裁剪把坐标限制在[0, img_w]和[0, img_h]内。转完做一次全量校验扫所有txt看有没有越界值。5.4 验证集和训练集图片重叠现象验证指标高得离谱实际推理一塌糊涂。原因train和val的图片有重复模型等于在背答案。解决划分数据集时按图片去重同一块板的不同角度图尽量分到同一侧。PCB数据如果来自连续拍摄相邻帧高度相似随机划分很容易泄漏建议按板号或时间段划分。5.5 CPU训练误以为卡死现象CPU上训练进度条长时间不动以为程序挂了。原因CPU训练本来就慢加上workers设太高导致线程争抢反而更慢。解决CPU上把workers降到2batch降到4耐心等。用verboseTrue看每轮耗时确认是在跑而不是死锁。真要快还是上GPU。6. 把1000张图用出更大价值数据增强与迁移策略1000张图直接训模型容易过拟合尤其小类别。我的习惯是在YOLO11自带增强之外针对PCB缺陷做几项定向增强。Ultralytics训练时默认开了mosaic、翻转、缩放但PCB缺陷有方向性比如开路是沿走线方向的随机旋转可能造出不存在的缺陷形态所以旋转角度要克制一般限制在±10度。颜色方面PCB板面颜色相对固定HSV抖动能模拟不同光照和相机白平衡hsv_h、hsv_s、hsv_v可以适当开大一点。model.train( datapcb_defect/data.yaml, epochs150, imgsz960, batch8, devicepick_device(), hsv_h0.015, hsv_s0.7, hsv_v0.4, # 颜色增强 degrees10.0, # 旋转限制 translate0.1, scale0.5, mosaic1.0, mixup0.1, patience30 )参数上hsv_s0.7比默认的0.7略高模拟不同批次板面的色差degrees10防止旋转造出假缺陷mixup0.1轻度混合增强泛化但别开太大否则小目标被叠没。迁移策略上yolo11n.pt是最轻的预训练权重如果精度不够可以换yolo11s.pt或yolo11m.pt代价是速度和显存。我的做法是先用n版跑通全流程、确认数据和标签没问题再换大模型冲精度这样出问题时能快速定位是数据问题还是模型问题。验证阶段别只看mAP一个数。PCB质检关心的是漏检率漏检一个缺陷比误报几个更严重。所以看混淆矩阵时重点看每类的召回召回低的类别回去补样本或调类别权重。推理时把conf阈值调低一点宁可多报几个让人工复核也别漏。这套流程跑下来1000张图能给你一个可用的基线模型但要上产线样本量和类别覆盖还得继续扩。我自己踩过的最大坑是急着上大模型结果标签里两个类别索引写反白跑一晚上。后来养成习惯任何数据集先画框验证、再统计类别、最后才开训。希望帮到你。本文还有配套的精品资源点击获取
返回列表