资讯详情

deepPCB数据集详解:PCB缺陷检测的VOC/YOLO双格式训练实战

📅 2026/10/19 4:02:06 | 华诺云谱 👁 阅读
deepPCB数据集详解:PCB缺陷检测的VOC/YOLO双格式训练实战
做PCB缺陷检测的同行应该都对deepPCB这套公开数据集不陌生。它算是工业视觉里最容易被拿来做算法验证的资源之一1500张640×640的裸板图像标注了缺孔、鼠咬、开路、短路、毛刺、余铜6类典型缺陷覆盖了蚀刻、钻孔、沉铜这些工序常见的异常形态。标题里的VOCYOLO格式1500张6类别是说这份数据集已经把原始标注加工成了Pascal VOC的XML和YOLO的txt两套格式省去了自己写转换脚本的流程。我之前在负责的质检项目里也倒腾过这套数据从最开始手动解析txt到后来直接用转换好的版本训YOLO中间踩过的坑不算少。这篇文章就把这套数据的底细、拿到手之后的验证方法、三种格式之间的换算逻辑以及实际训练时的参数和坑位都梳理一遍给正在做工业缺陷检测或者刚接触YOLO目标检测的朋友做个参考。1. deepPCB数据集来龙去脉1500张裸板图里的6类致命缺陷1.1 为什么PCB缺陷检测是工业视觉绕不开的考题电路板是几乎所有电子设备的基础骨架铜箔线路经过蚀刻、钻孔、电镀这些工序之后一旦出现断路、短路、缺口轻则功能异常重则整块板报废。以前很多产线靠人工在放大镜下目检一个人盯几个小时眼睛疲劳之后小缺陷的漏检率直线上升而且不同人之间的判定标准还不统一。AOI自动光学检测设备就是在这个背景下把相机、光源和检测算法组合起来用图像方式替代一部分人工目检。这里面的核心难度就两个字找小。PCB裸板上的缺陷尺寸非常小很多只有十几到几十个像素同时铜箔在光照下反光颜色和背景接近对比度并不高。所以这个场景天然适合考察一个检测模型的极限能力而不只是能不能框住一个大目标。deepPCB被大家反复使用原因也在这里它是从真实采集环境里来的拍摄条件相对统一标注也经过了人工整理拿来验证算法、横向对比模型非常方便。1.2 六类缺陷对照名字、成因与检测难度不同发布版本对类别顺序的处理可能不一样但六类缺陷的名字基本是固定的。为了方便对照我把每个类别的中文叫法、直观表现和检测难点列成一张表类别名中文叫法直观表现检测难点missing_hole缺孔焊盘或过孔位置没有钻出孔与正常焊盘差异小需要看中心区域mouse_bite鼠咬铜线边缘出现凹坑、缺口目标小像噪声边界不规则open_circuit开路铜线断裂导电路径中断断缝可能只有几个像素宽short短路两条本不该相连的线路搭在一起搭接点形态多变颜色近似spur毛刺线路边缘多出细长铜刺长宽比畸形容易和正常走线混淆copper余铜板面残留的铜块、铜渣位置随机形状不一反光强训练时最重要的一件事就是先确认你手里的类别id顺序和这六类名字一一对应。有的转换版本会把类别按字母序重新编号也有人按原始txt里的出现顺序来编顺序错了后面全乱。1.3 1500张图的规模到底够干什么1500张对深度学习目标检测来说不算多但也不算少。deepPCB里大部分图像包含多个缺陷框有效标注框的数量是远超1500的所以拿来训练一个单类别多尺度的检测器完全够用但如果你想训出一个直接部署到产线的模型这个量级通常只是起点。我的建议是把这套数据集当作三件事来用。第一做算法选型的试验场快速对比不同尺寸的YOLO模型在小目标加类别不平衡场景下的表现第二当迁移学习的底料先在deepPCB上把检测头训稳再用自己产线攒的几百张图做微调第三当数据质量的教科书通过它养成拿到数据先验证再训练的习惯这个习惯能让你以后处理任何数据集都少踩坑。2. 拿到VOCYOLO双格式数据集后先做这三步核验有人觉得数据集到手就能直接开训我劝你慢一点。标注错误有时候比模型结构错误更致命而且这套数据被反复转换过格式任何一个环节坐标系理解错了框就会整体错位。拿到手先花半小时做下面三件事能省下后面好几个小时的排错时间。2.1 先看目录和文件数量把三种格式对账正常的双格式版本目录结构大概是这样的deepPCB_voc_yolo/ ├─ VOC/ │ ├─ JPEGImages/ # 1500张jpg │ ├─ Annotations/ # 1500个xml │ └─ ImageSets/ │ └─ Main/ │ ├─ train.txt │ └─ val.txt └─ YOLO/ ├─ images/ │ ├─ train/ │ └─ val/ └─ labels/ ├─ train/ └─ val/对账的方法就是数数JPEGImages下应该正好是1500张jpgAnnotations下是1500个xmlYOLO的train和val加起来也应该是1500。ImageSets里的train.txt、val.txt文件名要能和图片一一对上YOLO目录里的划分通常和VOC的划分保持一致。任何一个数字对不上宁可花时间重新整理也不要带着残缺的数据集直接开训。2.2 画框可视化最容易暴露坐标系问题的环节格式转换最大的坑是坐标系。原始标注的坐标原点在左上角还是左下角、转换时y轴有没有翻转、XML里存的是整数还是浮点数这些细节一旦错训练出来的模型指标会很奇怪loss看起来正常但预测框要么上下颠倒要么整体偏移。我每次拿到新标注都会先跑一个画框脚本随机抽10到20张图把XML或YOLO标注直接画在图上人工确认框有没有贴着缺陷边缘。这一步没什么技术含量但价值极高。给你一段能直接跑的OpenCV脚本import os, random import cv2 import xml.etree.ElementTree as ET img_dir deepPCB_voc_yolo/VOC/JPEGImages ann_dir deepPCB_voc_yolo/VOC/Annotations out_dir check_vis os.makedirs(out_dir, exist_okTrue) for img_name in random.sample(os.listdir(img_dir), 20): xml_path os.path.join(ann_dir, img_name.replace(.jpg, .xml)) img cv2.imread(os.path.join(img_dir, img_name)) tree ET.parse(xml_path) for obj in tree.getroot().findall(object): name obj.find(name).text bbox obj.find(bndbox) xmin int(float(bbox.find(xmin).text)) ymin int(float(bbox.find(ymin).text)) xmax int(float(bbox.find(xmax).text)) ymax int(float(bbox.find(ymax).text)) cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2) cv2.putText(img, name, (xmin, max(ymin - 5, 15)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(os.path.join(out_dir, img_name), img)如果框的位置都合理再随机抽20个YOLO的txt标注按第3节的公式转回左上角、右下角坐标同样画一轮。两边都确认过训练前最大的隐患就排除了。2.3 标注统计三件套类别数量、框面积、越界空文件可视化确认了方向对还得确认分布正常。我习惯写一个统计脚本一次性输出几个关键数字import glob from collections import Counter cls_counter Counter() empty_files [] area_ratios [] bad_lines 0 for label_path in glob.glob(deepPCB_voc_yolo/YOLO/labels/train/*.txt): lines [ln.strip() for ln in open(label_path) if ln.strip() and not ln.startswith(#)] if not lines: empty_files.append(label_path) for ln in lines: parts ln.split() if len(parts) ! 5: bad_lines 1 continue cls_id int(parts[0]) xc, yc, bw, bh map(float, parts[1:]) if not (0.0 xc 1.0 and 0.0 yc 1.0 and 0.0 bw 1.0 and 0.0 bh 1.0): bad_lines 1 cls_counter[cls_id] 1 area_ratios.append(bw * bh) print(类别数量:, cls_counter) print(空标注文件:, len(empty_files)) print(标注行异常数:, bad_lines) print(平均框面积占比:, sum(area_ratios) / len(area_ratios))这几个数字分别回答了三类问题类别是否齐全、类别是否极度不平衡有没有图片漏标注有没有把坐标写到[0,1]范围之外的坏数据。deepPCB的标注质量整体是靠谱的但转换过程偶尔会产生一行被截断、类名被替换之类的低级错误统计一遍心里才有底。3. 三种标注格式深度拆解坐标系与归一化的换算关系如果你打算把这份数据集的格式逻辑吃透或者以后自己手里也有原始txt标注需要转换这一节建议仔细看。三种格式改来改去核心就一个东西怎么用一个矩形框去描述一个缺陷以及这个矩形框在不同格式里的描述方式有什么不同。3.1 原始TXT解析先搞清楚坐标系的约定deepPCB原始标注一般是txt文本每一行对应一个缺陷框常见写法是short 165 320 188 342 open_circuit 400 210 430 225前一个字符串是类别名后面四个数字是矩形框的坐标。麻烦在于不同发布版本对坐标原点的约定并不完全统一有的以图像左上角为原点x向右增大y向下增大有的论文表述里习惯用左下角为原点。把y轴方向搞反是格式转换里最典型的错误。所以不管是拿到别人的txt还是自己写解析器第一件事永远是拿一张图出来画框验证。我做转换脚本的时候会故意画一遍原坐标、再画一遍y轴翻转后的坐标对比哪一组跟缺陷边缘吻合确定坐标约定之后才继续往下走。3.2 VOC XML的字段结构bndbox是核心Pascal VOC是目标检测领域的老牌格式XML文件里记录图像路径、尺寸、通道数以及每个目标框的类别和坐标。一份典型的标注长这样annotation folderJPEGImages/folder filenameimg_0123.jpg/filename size width640/width height640/height depth3/depth /size object nameshort/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin165/xmin ymin320/ymin xmax188/xmax ymax342/ymax /bndbox /object /annotationbndbox里这四个值用的是绝对像素坐标左上角xmin、ymin和右下角xmax、ymax要求xmin小于xmax、ymin小于ymax。VOC格式的优势是人和机器都能读而且单个文件里自带图像尺寸换机器迁移也方便。缺点就是冗余字段多读起来费劲训练框架通常不直接吃XML。3.3 YOLO五元组归一化中心点加宽高YOLO系列使用的txt标注只有一行五个数类别id、归一化中心点x、归一化中心点y、归一化宽度、归一化高度。换算公式很简单x_center (xmin xmax) / 2 / width y_center (ymin ymax) / 2 / height box_w (xmax - xmin) / width box_h (ymax - ymin) / height反过来从YOLO坐标还原成像素坐标xmin (x_center - box_w / 2) * width ymin (y_center - box_h / 2) * height xmax (x_center box_w / 2) * width ymax (y_center box_h / 2) * height为什么要归一化因为不同分辨率的图可以用同一套标注通用模型训练时做的尺寸缩放、多尺度训练都不用跟着改标签。这也是YOLO系训练框架只认这种txt、不认XML的原因。3.4 同一条标注在三种格式间的等价性验证转换脚本写完不能只跑一遍了事。我习惯抽几十条标注做一次三角验证从原始txt读坐标转成XML再从XML转回YOLO最后对比两条YOLO五元组误差应该几乎为零。如果误差明显多半是转换中用了int截断或者归一化时除错了尺寸。这个验证逻辑可以写成一个函数def verify_roundtrip(yolo_line, img_w640, img_h640): cls_id, xc, yc, bw, bh map(float, yolo_line.split()) # 还原绝对坐标 xmin (xc - bw / 2) * img_w ymin (yc - bh / 2) * img_h xmax (xc bw / 2) * img_w ymax (yc bh / 2) * img_h # 再转回归一化 xc2 (xmin xmax) / 2 / img_w yc2 (ymin ymax) / 2 / img_h bw2 (xmax - xmin) / img_w bh2 (ymax - ymin) / img_h return (abs(xc - xc2) 1e-6 and abs(yc - yc2) 1e-6 and abs(bw - bw2) 1e-6 and abs(bh - bh2) 1e-6)这段代码本身很简单但把三种格式的数学关系吃透了。对格式转换比较纠结的同行我的建议是格式只是载体坐标的数学关系才是根本。只要脑子里有左上角/右下角、绝对/归一化、宽高/中心点这几个维度任何格式之间切换都不会出错。4. 直接开跑YOLO训练配置与关键参数解读前面把数据验证和格式逻辑都过完了现在可以真正开训了。用YOLO官方Python库训练时需要准备一个data.yaml、一个合理的目录组织方式以及几个关键超参数的选择。4.1 目录落地与data.yaml类别顺序错一个字符就全乱YOLO训练库默认的目录约定是images与labels同级同名的jpg和txt一一对应。你拿到手的双格式数据集里YOLO目录本身就应该符合这个约定直接确认train和val的划分是否合理就行。假设数据放在/data/deepPCB_yolo配一个data.yamlpath: /data/deepPCB_yolo train: images/train val: images/val nc: 6 names: 0: missing_hole 1: mouse_bite 2: open_circuit 3: short 4: spur 5: copper这里最需要注意的就是names的顺序必须和txt标注里的类别id完全一致。很多转换版本喜欢把类别重新编号如果你习惯按字母序理解类别很容易把short和spur搞混。启动训练的第一时间训练库会扫描标注文件并打印每个类别的图片数和标签数留意那几行日志如果发现某个类别数量为0或者和预期相差巨大说明data.yaml的names顺序有问题赶紧停下来改。4.2 训练命令与超参数为什么这么设训练命令可以这样写pip install ultralytics yolo train data/data/deepPCB_yolo/data.yaml \ modelyolo11n.pt \ epochs120 \ batch16 \ imgsz640 \ device0 \ workers8几个参数的逻辑说一下。imgsz设成640因为数据集原生分辨率就是640×640不需要额外缩放避免了小缺陷在降采样之后直接消失。model用预训练权重而不是从零开始是因为检测骨干网络在COCO这种大规模数据上学到的纹理和边缘特征对小目标识别帮助很大尤其在你只有1500张图的情况下迁移学习几乎是必须的。batch大小主要看显存16是一个常见起点如果显存不够可以降到8影响不会太大。epochs我习惯给到120并开启早停训练库默认会在验证指标连续多轮不涨时自动停下来不用一直空跑。用Python方式也是一样的from ultralytics import YOLO model YOLO(yolo11n.pt) model.train(data/data/deepPCB_yolo/data.yaml, epochs120, batch16, imgsz640, workers8, patience20)4.3 训练日志和指标怎么读别只盯mAP50训练结束后训练库会在runs/detect/xxx目录下输出一堆结果文件。我一般按这个顺序看先看results.png里的loss曲线如果box_loss和cls_loss稳步下降验证loss没有在后期大幅反弹说明训练过程健康然后看confusion_matrix.png混淆矩阵重点观察短路被判成余铜开路被判成鼠咬这类容易互相混淆的类别对接着看PR曲线里每个类别的AP值尤其是少数类的AP是不是明显偏低。mAP50和mAP50-95要一起看。mAP50只要求预测框和真实框的IOU超过0.5就算命中对小缺陷来说标准比较宽松mAP50-95对框的位置精度要求高得多更能反映模型在实际使用中框得准不准。deepPCB这类数据上训练得当的轻量模型mAP50可以到0.9上下mAP50-95通常在0.55到0.7之间这个区间供你对照参考。指标提不上去的时候先去翻失败样本图而不是急着换更大的模型这个习惯能省很多时间。5. 实测避坑清单这6类缺陷为什么容易互相混淆用这套数据训练我相信第一步大家都会遇到类似的问题明明训练正常val的mAP也不低但推理到真实PCB图片上缺陷就是会漏。下面四类问题是我自己实测遇到的按发生频率从高到低排列。5.1 小目标怎么数框面积比例与漏检的直接关系deepPCB里缺陷框的尺寸普遍很小。拿短路举例两条线之间的搭接往往只有几十个像素见方开路的断缝更极端可能只有几个像素宽。假如一张640×640的图里有一个20×20的缺陷框它占整张图的面积只有0.1%左右。模型在多次降采样的特征图上这个小目标可能只剩几个像素检测分支根本看不见它。针对这个问题的实操手段有三个一是保持imgsz不小于640不要为了加速把训练尺寸降到416二是打开mosaic增强让模型在拼接图里接触大量不同尺度的小目标三是如果框架支持多层检测头优先选带浅层高分辨率特征图的配置小目标召回会明显提升。这些方向上nano级别的轻量模型就已经能跑出不错的效果不一定要上大模型。5.2 类别不均衡的实操对策上采样和离线增强六类缺陷在数据里并不是均匀分布的。开路和短路通常数量多毛刺、鼠咬这类相对少一些。类别不均衡会导致模型对少数类的学习不充分表现为毛刺、鼠咬的AP明显低于开路、短路。处理办法我试下来最有效的有两种。一种是离线复制粘贴增强把鼠咬、毛刺这类小目标从原图里抠出来按规则贴到空白区域或正常板图上同时补齐标注把少数类的样本量补上去另一种是训练时做多尺度随机裁剪采样让模型每次迭代看到不同数量的框避免少数类样本被大批量重复。直接改损失函数权重在部分YOLO版本里支持得不太好框架不支持的话建议优先走离线增强路线。5.3 鼠咬与开路、毛刺与余铜边界模糊类别的取舍这四类缺陷之间的边界本来就不清晰。鼠咬是线路边缘的凹坑凹坑深到一定程度线路就断了从检测角度看就是一个开路毛刺是线路边缘多出来的铜刺铜刺脱落或残留成大块就成了余铜。标注人员对同一张图的理解不同框出来的类别就可能不同这种标注噪声会直接压低AP的上限。如果你最终的目标是产线缺陷拦截而不是发论文刷指标我建议把业务上可以合并的类别合并掉比如把鼠咬和开路统一成线路异常把毛刺和余铜统一成多余铜。类别少了边界清晰了模型判断会更稳定业务上更容易解释。反过来如果你需要细粒度分类来做返修工艺指导那就要接受一部分混淆误判并用人工复核兜底。5.4 空图与背景图防误检的另一半功课deepPCB这套数据几乎每张图都有缺陷框训练出来的模型在无缺陷的干净板子上反而容易瞎报。在真实产线上绝大多数板子是良品模型误检率哪怕只有百分之几放大到每天几万块板子都是灾难。我后来在自己项目里做了一个改动从产线采集大量无缺陷板图作为负样本混进训练集并把它们处理成空标注。YOLO框架对没有标注文件的图片也可以训练会把它当作纯背景来抑制误检。如果你手头有自己产线的正常板图强烈建议在deepPCB数据之外补一批负样本这个操作对降低误检的作用比换任何更大的模型都直接。6. 从mAP到漏检率产线部署前还要跨过的三道坎拿到转换好的数据集也训出了不错的模型这离产线真正能用还有一段距离。这一段主要说推理时的参数、模型的导出以及实验室指标和产线指标之间的真实差距。6.1 增强配方旋转必须跟着标注转颜色扰动模拟不同光源训练阶段的增强直接影响模型的泛化能力。deepPCB的图像是在相对统一的光源下拍的而产线不同机台、不同批次的板子光源色温和角度都会有差异。我建议用HSV颜色增强来模拟这种差异饱和度、明度各做20%左右的随机扰动色调也做小幅扰动让模型学会无视颜色波动。旋转增强要特别小心。PCB缺陷在裸板上的形态和方向有一定随机性90度、180度、270度的旋转是安全的因为这相当于换了一个拍摄朝向但任意的15度、30度旋转会让框变成倾斜训练框架只能按外接正框处理反而引入噪声。凡是做旋转增强一定要确认标注框同步旋转否则模型学到的就是错位框。6.2 推理设置与模型导出速度与精度的平衡训练完的模型通常要导出成ONNX之类的中性格式再转换到推理引擎部署。导出时注意几个点输入分辨率固定成640避免动态尺寸在边缘设备上带来性能波动推理的置信度阈值我一般从0.25起步在产线场景里挑一个误检率可接受、漏检率最低的平衡点NMS的IoU阈值保持0.45左右不必为了框更多而调高PCB缺陷本身尺寸小框多了反而难判。如果对速度有要求可以试试半精度或整型量化。轻量模型在量化和不量化之间的精度差距通常不大但速度能提升好几倍。我实测中跑640分辨率量化后的单张推理时间能压到几毫秒配合多机台并行完全够用。6.3 实验室指标和产线指标mAP不是业务指标最后聊一个容易被忽略的问题。实验室里看mAP产线上看的是每千块板的漏检数和误判数。mAP到了0.9看起来很高但如果缺陷平均一块板上只有0.1个千块板里漏掉几十块都是完全可能的。业务方给你的验收指标往往不是mAP而是指定误检率下的漏检率上限。所以我的建议是模型训练完之后不要急着看指标收工而是从验收集里专门挑一批难样本——不同批次板材、不同光源条件、不同缺陷形态的图——做一次人工复核。把模型判断错误的图按漏检和误检两类分别存放每隔一段时间回灌到训练集做增量微调。这个过程是循环的数据集、模型、业务指标三者形成闭环之后才能真正谈上线。最后分享一个自己的习惯。每次拿到任何标注数据不管是公开的还是自己标定的我都先跑一遍统计脚本和可视化脚本把类别分布、框的位置、坐标合法性都看一眼再进训练流程。这个习惯帮我避开了好几次训了一整天才发现标注坐标系错了的惨剧。deepPCB这套双格式数据集本身质量不错但再好的数据在进入你的训练流程之前都值得花半小时验证一遍。格式转换的脚本我也会留着以后采集了自己的PCB数据同样走一遍转换、核验、训练的流程这套流水线确实越用越顺手。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑