简介面向电子制造质检与计算机视觉方向的开发者、学生及算法工程师这份PCD表面元器件缺陷检测数据集用于训练和验证PCB表面元器件缺陷识别模型覆盖Miss、mask defect、defect等7类常见缺陷适合目标检测入门到进阶的实战练习。资源包共1219个文件包含608张jpg图像、609个txt标注文件以及1个py可视化脚本和1个png说明图压缩包约57.41MB已统一处理为YOLO格式并完成数据增强可直接用于YOLO全系列网络训练同时划分了训练集与验证集。配套的show脚本能将预测或标注的边界框绘制在图像上便于直观核对缺陷位置、调试模型与评估检测效果。class文件清晰列出全部类别方便按需调整训练配置。目前已有391人学习下载可作为缺陷检测项目的数据基础与流程参考。1. PCD表面元器件缺陷检测数据集600张图能撑起一条产线质检模型吗PCB 表面贴装元器件的缺陷检测是电子制造里最典型的视觉质检场景之一。缺件、偏移、立碑、极性反、锡珠、虚焊这些缺陷在一条 SMT 产线上每天都会出现靠人眼在放大镜下盯板子既慢又容易漏。PCD表面元器件缺陷检测数据集超过 600 张图片和对应标签就是冲着这个场景来的——它把工业相机拍到的板面图像和缺陷位置框标注好让你能直接拿去训练目标检测模型。600 张这个量级说多不多说少也不少关键看你怎么用。如果你手上正好有一台贴片机、一条小产线或者正在做 AOI 设备的算法预研这个数据集能帮你把从标注格式到模型训练再到推理验证的整条链路先跑通一遍。它适合两类人一类是想入门工业缺陷检测但拿不到真实产线数据的算法工程师另一类是手里有数据但不知道怎么组织成 YOLO 可训练格式的现场工艺人员。下面我按自己踩过的路把这个数据集从拆包到出模型讲清楚。2. 数据集拆开看600张图里到底有什么、标注怎么读2.1 图片与标签的目录结构长什么样拿到一个目标检测数据集第一件事不是急着写训练脚本而是先把目录翻一遍。PCD 表面元器件缺陷检测数据集常见的组织方式是按图像和标签分开放图像一般是 JPG 或 PNG标签是 YOLO 格式的 txt 或者 Pascal VOC 的 xml。600 多张图如果按缺陷类别分文件夹你就要留意每个类别下的样本数是否均衡。我一般会先跑一段统计脚本把图片尺寸、通道数、标签文件数量、每个类别的框数全部列出来。这一步花不了五分钟但能帮你避开后面训练时“某个类别一个框都没有”的翻车现场。import os import cv2 from collections import Counter img_dir images lbl_dir labels img_files [f for f in os.listdir(img_dir) if f.endswith((.jpg, .png))] lbl_files [f for f in os.listdir(lbl_dir) if f.endswith(.txt)] print(f图片数量: {len(img_files)}) print(f标签数量: {len(lbl_files)}) # 检查图片和标签是否一一对应 img_stems {os.path.splitext(f)[0] for f in img_files} lbl_stems {os.path.splitext(f)[0] for f in lbl_files} print(f有图无标签: {img_stems - lbl_stems}) print(f有标签无图: {lbl_stems - img_stems}) # 统计每个类别的框数 cls_counter Counter() for lf in lbl_files: with open(os.path.join(lbl_dir, lf)) as f: for line in f: parts line.strip().split() if parts: cls_counter[int(parts[0])] 1 print(类别分布:, dict(cls_counter)) # 抽查图片尺寸 sizes Counter() for f in img_files[:50]: img cv2.imread(os.path.join(img_dir, f)) if img is not None: sizes[img.shape[:2]] 1 print(前50张图片尺寸分布:, sizes.most_common(5))这段脚本做了四件事数图片和标签数量、检查文件名是否一一对应、统计每个类别的标注框数量、抽查图片分辨率。参数上img_dir和lbl_dir换成你解压后的实际路径即可。重点看两个输出如果“有图无标签”不是空集说明数据组织有问题训练时会报找不到标签如果类别分布严重倾斜比如某个缺陷只有十几个框那训练时就要考虑过采样或者数据增强。图片尺寸分布也很关键如果尺寸五花八门后面统一 resize 的时候就要注意长宽比失真。2.2 YOLO 标签格式的每一列代表什么YOLO 格式的标签文件里每一行对应一个目标框格式是class_id x_center y_center width height后四个值都是归一化到 0 到 1 之间的浮点数。很多人第一次看这种标签会懵因为不是像素坐标。举个例子一张 640×480 的图里有个框在左上角像素坐标是 (100, 80) 到 (200, 160)那么中心点像素是 (150, 120)归一化后 x_center150/640≈0.234y_center120/4800.25width(200-100)/640≈0.156height(160-80)/480≈0.167。标签行就是0 0.234 0.25 0.156 0.167。如果你拿到的标签是 VOC 的 xml里面是绝对像素坐标那就需要转换。转换脚本网上一搜一大把但坑在于 xml 里的xmin/ymin/xmax/ymax有时候会超出图片边界转换前要 clamp 一下否则归一化后会出现负数或大于 1 的值训练时直接报错。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 max(0, float(bbox.find(xmin).text)) ymin max(0, float(bbox.find(ymin).text)) xmax min(img_w, float(bbox.find(xmax).text)) ymax min(img_h, float(bbox.find(ymax).text)) x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) return lines这个转换函数里class_map是你自己定义的类别名到 id 的映射比如{missing: 0, offset: 1, tombstone: 2}。max(0, ...)和min(img_w, ...)就是做边界裁剪防止标注框超出图片范围。转换完记得抽查几个文件把归一化坐标反算回像素坐标画到原图上看看框的位置对不对。这一步是血泪经验我曾经因为 xml 里 y 轴坐标写反了训练出来的模型把所有缺陷都框在板子外面。2.3 600张图够不够从缺陷类别数和框密度倒推600 张图够不够训练一个可用的缺陷检测模型不能只看图片数量要看缺陷类别的数量和每张图里的框密度。如果只有 3 到 5 类缺陷每张图平均 2 到 3 个框那 600 张图大概有 1500 到 2000 个标注框用 YOLOv8n 或 YOLOv11n 这种轻量模型配合强数据增强是能训出一个 baseline 的。但如果缺陷类别超过 10 类或者某些类别只有几十个框那 600 张图就捉襟见肘了。我一般会按类别算一个“最少框数”阈值每个类别至少要有 100 到 150 个框低于这个数的类别要么合并要么用复制粘贴增强补到 100 以上。另外PCD 表面元器件缺陷检测这个场景有个特点缺陷目标通常很小立碑的元件可能只有十几个像素宽所以输入分辨率不能太低640 可能不够建议用 1024 或 1280 训练推理时再根据产线节拍调整。3. 从零跑通训练YOLOv8/YOLOv11 的配置与参数3.1 环境安装与数据配置文件写法训练之前先把环境搭好。我一般用 conda 建一个干净的环境Python 3.9 或 3.10 都行PyTorch 按显卡驱动版本选。YOLOv8 和 YOLOv11 都通过 ultralytics 这个包来调用安装命令就一行。装完之后在数据集根目录下建一个data.yaml这是告诉训练器去哪里找图片和标签的关键文件。conda create -n pcd_defect python3.10 -y conda activate pcd_defect pip install ultralytics opencv-python# data.yaml path: /home/user/pcd_defect_dataset train: images/train val: images/val test: images/test nc: 5 names: 0: missing 1: offset 2: tombstone 3: polarity_reverse 4: solder_ballpath是数据集根目录train/val/test是相对于path的子目录。nc是类别数names是类别名和 id 的对应关系顺序必须和标签里的 class_id 一致。这里有个容易翻车的地方如果你的标签文件放在labels/train而图片在images/trainultralytics 会自动把images替换成labels去找标签所以目录结构要保持一致。划分训练集和验证集的时候600 张图我一般按 8:1:1 分也就是 480 张训练、60 张验证、60 张测试。如果某些类别样本少划分时要保证每个类别在训练集和验证集里都有出现不能随机分完发现验证集里没有“立碑”这一类。3.2 训练命令与关键参数怎么调数据配置写好之后训练命令其实很短但参数怎么设决定了模型能不能收敛。下面这条命令是我在 PCD 缺陷数据集上常用的起点。yolo detect train \ datadata.yaml \ modelyolov8s.pt \ epochs150 \ imgsz1024 \ batch8 \ lr00.01 \ lrf0.01 \ patience30 \ augmentTrue \ mosaic1.0 \ mixup0.1 \ degrees10 \ translate0.1 \ scale0.5 \ fliplr0.5 \ flipud0.0 \ device0 \ projectruns/pcd_defect \ nameexp01逐项说modelyolov8s.pt是预训练权重小模型在 600 张图上比大模型更不容易过拟合imgsz1024是因为缺陷目标小分辨率太低会丢特征batch8是显存不够时的保守值8G 显存跑 1024 大概就这个数lr00.01是初始学习率lrf0.01是最终学习率系数余弦退火到 0.0001patience30是 30 轮没提升就早停防止过拟合mosaic1.0和mixup0.1是强增强小数据集必备degrees10是随机旋转但注意元器件缺陷有方向性旋转角度别太大否则立碑和偏移的视觉特征会乱flipud0.0是因为 PCB 图像上下翻转不符合实际产线视角开了反而引入噪声。训练过程中重点看mAP50和mAP50-95两个指标如果mAP50在 0.6 以下先别急着调模型回去检查标签质量和类别分布。3.3 训练日志里该盯哪几个数训练跑起来之后控制台会刷一堆指标新手容易看花眼。我一般只盯四个box_loss、cls_loss、mAP50、mAP50-95。box_loss下降说明框的位置在变准cls_loss下降说明分类在变对。如果box_loss一直震荡不降大概率是学习率太大或者标注框有问题如果cls_loss降不下去可能是类别不平衡或者某些类别的特征太像。mAP50是 IoU 阈值 0.5 时的平均精度工业缺陷检测里这个值到 0.85 以上才算能用mAP50-95更严格能到 0.5 以上就不错了。另外注意看验证集的 loss 有没有回升如果训练 loss 降但验证 loss 升就是过拟合了要么加数据增强要么减模型复杂度。我习惯在训练结束后用results.png把几条曲线叠在一起看比盯数字直观。4. 避坑与排查标注、划分、显存、过拟合的五个真实翻车点4.1 标签文件里有空行或空格分隔符不统一现象是训练启动后报IndexError或者ValueError: not enough values to unpack。原因通常是标签文件里混入了空行或者有的行用空格分隔、有的用制表符甚至有的行只有 class_id 没有坐标。解决方法是写一个清洗脚本逐行读入跳过空行用split()统一按空白字符切分检查每行是否有 5 个字段坐标值是否在 0 到 1 之间。清洗完再统计一遍每个类别的框数确认没有异常。4.2 训练集和验证集划分后类别分布严重偏移现象是训练时mAP50看着还行但一跑测试集就崩某些类别完全检测不到。原因是随机划分时把某个类别的样本全分到了训练集验证集里一个都没有。解决办法是按类别分层抽样保证每个类别在训练集、验证集、测试集里的比例大致一致。如果某个类别总样本数少于 30那就要考虑把它合并到相似类别或者用数据增强补样本而不是硬分。4.3 显存不够导致 batch size 被迫降到 1现象是训练命令一跑就CUDA out of memory只能把batch改成 1但 batch 太小导致 BN 层统计不稳定loss 震荡。解决办法有三个一是用imgsz640先跑通再逐步升到 1024二是开混合精度训练在命令里加ampTrue三是用梯度累积虽然 ultralytics 没有直接暴露这个参数但可以通过减小 batch 并增加accumulate来模拟不过更简单的做法是换一张显存更大的卡或者用yolov8n这种更小的模型。4.4 数据增强把缺陷特征增强没了现象是训练时指标很好但推理时模型把正常元件也框成缺陷。原因是mosaic和mixup太强把不同图片的元件拼在一起模型学到了错误的上下文关系。解决办法是降低mosaic概率到 0.5 以下mixup关掉或降到 0.05同时加copy_paste增强来补充小目标。另外旋转和缩放的范围也要控制degrees不超过 15scale不超过 0.5否则元器件的形状会失真。4.5 推理时置信度阈值设太高导致漏检现象是模型在验证集上mAP50有 0.9但实际跑图时很多缺陷框不出来。原因是推理时默认conf0.25对于小目标缺陷置信度普遍偏低0.25 就把它们滤掉了。解决办法是把conf降到 0.1 甚至 0.05同时把iou阈值从 0.7 降到 0.5让更多候选框参与 NMS。但注意conf太低会引入误检所以要在验证集上画 PR 曲线找一个漏检和误检的平衡点。我一般会保存推理结果图人工看一遍再决定最终的阈值。5. 小数据集提效技巧用 600 张图把 mAP 再往上推一截600 张图训出来的 baselinemAP50大概在 0.75 到 0.85 之间想再往上推靠调模型结构不如靠数据策略。我常用的一个技巧是“离线增强 在线增强”组合先用脚本把训练集里的每张图做旋转、亮度变化、加噪声生成 2 到 3 倍的副本存成新的图片和标签扩充训练集然后在训练时再开mosaic和mixup做在线增强。这样相当于把 480 张训练图变成了 1500 张左右对小数据集提升很明显。离线增强的脚本可以用 OpenCV 写旋转的时候注意同步旋转标注框的四个角点再重新计算外接矩形。import cv2 import numpy as np import os def rotate_image_and_boxes(img, boxes, angle): h, w img.shape[:2] center (w / 2, h / 2) M cv2.getRotationMatrix2D(center, angle, 1.0) rotated cv2.warpAffine(img, M, (w, h)) new_boxes [] for box in boxes: cls_id, xc, yc, bw, bh box # 转成四个角点 x1, y1 (xc - bw/2) * w, (yc - bh/2) * h x2, y2 (xc bw/2) * w, (yc bh/2) * h corners np.array([[x1, y1], [x2, y1], [x2, y2], [x1, y2]]) ones np.ones((4, 1)) corners_h np.hstack([corners, ones]) rotated_corners corners_h M.T rx1, ry1 rotated_corners[:, 0].min(), rotated_corners[:, 1].min() rx2, ry2 rotated_corners[:, 0].max(), rotated_corners[:, 1].max() # 裁剪到图片范围内 rx1, ry1 max(0, rx1), max(0, ry1) rx2, ry2 min(w, rx2), min(h, ry2) if rx2 - rx1 2 or ry2 - ry1 2: continue new_xc (rx1 rx2) / 2 / w new_yc (ry1 ry2) / 2 / h new_bw (rx2 - rx1) / w new_bh (ry2 - ry1) / h new_boxes.append((cls_id, new_xc, new_yc, new_bw, new_bh)) return rotated, new_boxes这个函数里angle建议取 -15 到 15 度之间太大就会像前面说的那样破坏缺陷特征。boxes是解析后的标签列表每个元素是(class_id, x_center, y_center, width, height)。旋转后重新计算外接矩形如果框太小就丢弃避免生成无效标注。离线增强做完之后把新图片和标签按同样的命名规则存到images/train和labels/train下再跑一次训练对比mAP50的变化。我自己的经验是600 张图经过 3 倍离线增强mAP50能涨 3 到 5 个点尤其是对小目标缺陷提升明显。最后提醒一句离线增强只对训练集做验证集和测试集保持原样否则指标会虚高。希望这些步骤能帮你把 PCD 表面元器件缺陷检测这个方向先跑通后面再根据自己产线的实际缺陷类型去补数据、调阈值。本文还有配套的精品资源点击获取