资讯详情

资讯详情

基于YOLOv8的光伏电池缺陷检测实战:从数据标注到部署

简介本资源为基于YOLOv8的光伏电池缺陷检测项目源码包面向具备一定深度学习基础的目标检测学习者与工业质检开发者用于解决划痕、污渍、裂纹等光伏电池表面缺陷的自动识别问题。压缩包共1111个文件约31.97MB以159个Python脚本、68个YAML配置、220个TXT说明及267张PNG效果图为主另含少量权重文件、Dockerfile与Jupyter笔记覆盖训练、推理与部署环节。项目核心提供train.py与predict.py两个脚本分别负责数据集加载、参数配置、训练与权重保存以及在测试图像上输出边界框和类别并涉及数据增强、学习率调度等策略。目前已有557人学习下载读者可借此掌握YOLOv8单阶段检测流程、缺陷数据集标注思路与GPU环境部署细节并理解模型迭代优化方向。1. 光伏电池缺陷检测为什么值得用 YOLOv8 重做一遍光伏组件出厂前的 EL 和电致发光成像检测长期依赖人工目检和传统视觉算法。人工看片一天几千张漏检率随疲劳度飙升传统 OpenCV 方案靠阈值和形态学遇到隐裂、断栅、黑斑这类低对比度缺陷就频繁翻车。YOLOv8 把检测框回归和分类头解耦配合 CSPDarknet 主干和 PAN-FPN 颈部在小目标密集排列的电池片场景里天然占优。这个项目要解决的核心问题是把光伏电池片图像里的隐裂、断栅、黑斑、混片、缺角等缺陷自动框出来并分类替代人工复检。适合有 Python 基础、想跑通工业缺陷检测全流程的工程师也适合手里有产线图像但不知道怎么标注和训练的人。读完你能拿到一套从数据标注、训练调参到推理部署的完整路径以及几个我踩过的坑。2. 光伏电池缺陷检测的数据集怎么建才不白干2.1 缺陷类别定义与标注粒度光伏电池缺陷检测的类别定义直接决定模型上限。我一般把类别控制在 5 到 7 类太细会导致类间样本极度不平衡太粗又失去分拣价值。常见做法是分成隐裂micro-crack、断栅finger break、黑斑black spot、混片mixed cell、缺角edge chip、焊带偏移ribbon shift。标注粒度上有个血泪经验隐裂在 EL 图像里往往是一条细线用矩形框标注时框会很大但目标像素极少建议隐裂单独用分割标注或者放大框后做后处理裁剪否则 YOLOv8 的检测头学到的特征被背景稀释。标注工具用 LabelImg 或 X-AnyLabeling 都行导出 YOLO 格式的 txt。每张图对应一个 txt每行格式是class_id x_center y_center width height全部归一化到 0 到 1。这里有个容易忽略的点光伏电池片图像通常是高分辨率整版图直接缩放到 640 会让隐裂消失。我的做法是先切图把整版按电池片网格切成单片的图再送标注。import cv2 import os # 将整版 EL 图像按 6x10 网格切成单片电池片 img cv2.imread(panel_el.png) h, w img.shape[:2] rows, cols 6, 10 cell_h, cell_w h // rows, w // cols os.makedirs(cells, exist_okTrue) for r in range(rows): for c in range(cols): cell img[r*cell_h:(r1)*cell_h, c*cell_w:(c1)*cell_w] cv2.imwrite(fcells/cell_{r}_{c}.png, cell)这段代码把整版图按行列切分。rows和cols要根据你的组件版型改常见 60 片版型是 6×1072 片是 6×12。切完后每张单片图分辨率大概 300 到 500 像素隐裂至少占几个像素缩放后还能保留。切图时注意边缘留 2 到 3 像素重叠避免缺陷正好落在切割线上被切碎。2.2 数据增强与类别不平衡处理光伏缺陷检测的类别不平衡非常严重正常片远多于缺陷片隐裂又远少于黑斑。YOLOv8 自带 mosaic、mixup、随机翻转等增强但默认配置对工业图像不够。我一般会做三件事第一对缺陷样本做离线过采样把隐裂样本复制 3 到 5 倍第二在data.yaml里不设fraction让全部数据参与第三训练时用copy_paste增强把缺陷区域抠出来贴到正常片上这个对隐裂特别有效。# data.yaml path: ./pv_dataset train: images/train val: images/val nc: 6 names: 0: micro_crack 1: finger_break 2: black_spot 3: mixed_cell 4: edge_chip 5: ribbon_shiftnc是类别数必须和 names 数量一致。path用相对路径时是相对于 ultralytics 的运行目录建议写绝对路径避免找不到。train 和 val 分别指向图像目录YOLOv8 会自动找同名的 labels 目录下的 txt。如果验证集里某些类别样本太少mAP 会剧烈波动建议每类至少留 50 个验证样本。提示切图后一定要检查有没有把缺陷切到两张图各一半的情况这种样本标注框会跨图训练时直接报错或者学出奇怪特征。3. YOLOv8 训练光伏缺陷模型的参数怎么设3.1 环境配置与预训练权重选择环境配置是新手第一道坎。我一般用 conda 建一个干净环境Python 3.9 到 3.10 都稳3.11 在某些 CUDA 版本上会出玄学问题。装 ultralytics 直接用 pip不要手动装 torch 再装 ultralytics让它自己解析依赖。conda create -n pv_yolo python3.10 -y conda activate pv_yolo pip install ultralytics # 验证 GPU 是否可用 python -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))如果输出True和你的显卡型号说明环境通了。GTX 1660 Ti 跑 YOLOv8n 或 YOLOv8s 完全够用6GB 显存把batch设到 8 到 12imgsz设 640。预训练权重选yolov8s.pt比较平衡n 版精度对隐裂偏低m 版在 1660 Ti 上训练慢到怀疑人生。下载权重时注意放在项目根目录训练命令里直接写文件名。3.2 训练命令与关键参数含义训练命令看起来简单但参数设错就是几小时白跑。我常用的命令如下yolo detect train \ modelyolov8s.pt \ data./data.yaml \ epochs200 \ imgsz640 \ batch8 \ lr00.01 \ lrf0.01 \ patience30 \ workers4 \ device0 \ projectpv_runs \ nameexp1epochs200是上限实际靠patience30早停30 轮验证 mAP 不升就停。lr00.01是初始学习率光伏数据量小的时候可以降到 0.005否则前期 loss 震荡。lrf0.01是最终学习率因子余弦退火到初始的 1%。workers4是数据加载线程Windows 上设太高会卡死Linux 可以到 8。device0指定第一块 GPUCPU 训练把 device 设成cpu但速度没法看。训练过程中重点看三个指标box_loss和cls_loss是否稳定下降mAP50是否在涨。如果cls_loss不降反升大概率是类别标注有错或者学习率太大。如果mAP50卡在 0.5 左右不动检查验证集里是不是有大量未标注缺陷。3.3 损失曲线与训练过程可视化YOLOv8 训练完会在project/name下生成results.csv里面记录了每轮的 loss 和 mAP。画损失函数曲线图是排查训练问题的基本手段。import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(pv_runs/exp1/results.csv) df.columns df.columns.str.strip() # 列名可能带空格 fig, axes plt.subplots(1, 2, figsize(12, 4)) axes[0].plot(df[epoch], df[train/box_loss], labelbox_loss) axes[0].plot(df[epoch], df[train/cls_loss], labelcls_loss) axes[0].set_xlabel(epoch); axes[0].set_ylabel(loss); axes[0].legend() axes[1].plot(df[epoch], df[metrics/mAP50(B)], labelmAP50) axes[1].plot(df[epoch], df[metrics/mAP50-95(B)], labelmAP50-95) axes[1].set_xlabel(epoch); axes[1].set_ylabel(mAP); axes[1].legend() plt.tight_layout(); plt.savefig(train_curve.png, dpi150)results.csv的列名在不同 ultralytics 版本里可能略有差异用strip()去空格是保险做法。左图看 loss 是否收敛右图看 mAP 是否过拟合。如果训练 loss 一直降但验证 mAP 早早就平了说明过拟合加增强或者减模型容量。如果两条 loss 都剧烈震荡把lr0减半再跑。4. 光伏缺陷检测的避坑与排查记录4.1 隐裂漏检严重mAP 只有 0.3现象训练完黑斑和断栅 mAP 都在 0.8 以上隐裂只有 0.3 左右。原因隐裂在 640 输入下像素太少YOLOv8 的 P3 特征图 stride 是 8隐裂特征在浅层就被池化掉了。解决把imgsz提到 1024或者改用yolov8s-seg做分割再或者把隐裂样本单独放大裁剪后训练。我最后是把 imgsz 设 1024 加隐裂过采样mAP 拉到 0.65。4.2 验证集 mAP 很高但实际推理全是误检现象验证集 mAP50 到 0.9拿产线新图推理正常片被框出一堆缺陷。原因训练集和验证集来自同一批图像分布太像模型学到了批次相关的特征比如光照和背景纹理。解决按时间或产线批次划分训练验证集验证集必须来自不同批次。另外推理时把conf从默认 0.25 提到 0.5iou设 0.5 做 NMS能压掉大部分低置信误检。4.3 训练到一半 loss 变成 nan现象前 50 轮正常突然 loss 变 nan训练中断。原因光伏图像里有些样本标注框宽高为 0或者归一化后超出 0 到 1 范围计算 loss 时除零。解决训练前跑一遍标注检查脚本过滤掉宽高小于 2 像素的框把坐标 clip 到 0 到 1。另外把amp关掉ampFalse能避免混合精度下的数值溢出代价是显存多占一点。4.4 推理速度在产线上跟不上现象模型 mAP 达标但单张推理 200ms产线节拍要求 50ms。原因默认 PyTorch 推理没做优化而且 imgsz 设了 1024。解决导出 ONNX 或 TensorRT用yolo export modelbest.pt formatengine halfTrue生成 FP16 引擎1660 Ti 上能压到 30ms 以内。如果还要更快考虑 RK3588 部署用 RKNN 工具链量化成 INT8但要注意量化后隐裂精度会掉需要拿几百张图做量化校准。4.5 热力图可视化发现模型看错地方现象用 Grad-CAM 画热力图发现模型关注的是电池片边缘而不是缺陷区域。原因数据集中缺陷大多在边缘模型学到了位置先验而不是缺陷特征。解决做随机裁剪增强把缺陷位置打乱或者用 copy_paste 把缺陷贴到图像中心区域。这个坑很隐蔽mAP 看不出来但换一批布局不同的组件就崩。5. 从训练到部署光伏缺陷检测的进阶技巧模型训完只是开始真正落地要考虑推理封装和持续迭代。我一般会把推理封装成一个带后处理的类把检测框映射回整版图坐标再按电池片网格聚合结果。这样输出的是「第几行第几列哪片电池有什么缺陷」而不是一堆散框产线分拣系统直接能用。from ultralytics import YOLO import numpy as np class PVPredictor: def __init__(self, weights, conf0.5, iou0.5, imgsz1024): self.model YOLO(weights) self.conf, self.iou, self.imgsz conf, iou, imgsz def predict_cell(self, cell_img): # 单片电池推理返回缺陷列表 results self.model.predict(cell_img, confself.conf, iouself.iou, imgszself.imgsz, verboseFalse) defects [] for box in results[0].boxes: cls_id int(box.cls[0]) defects.append({ class: self.model.names[cls_id], conf: float(box.conf[0]), xyxy: box.xyxy[0].tolist() }) return defects def predict_panel(self, panel_img, rows6, cols10): # 整版切分后逐片推理返回带网格坐标的结果 h, w panel_img.shape[:2] ch, cw h // rows, w // cols panel_result [] for r in range(rows): for c in range(cols): cell panel_img[r*ch:(r1)*ch, c*cw:(c1)*cw] defects self.predict_cell(cell) if defects: panel_result.append({row: r, col: c, defects: defects}) return panel_resultconf和iou是推理时最该调的两个参数产线宁可漏检不可误检时把 conf 提到 0.6 以上。predict_panel里的 rows 和 cols 要和切图时一致否则网格对不上。这个封装的好处是推理逻辑和业务逻辑分离换模型只改 weights 路径。验证模型有没有真正学到缺陷特征除了看 mAP我还会做两个测试一是拿正常片推理看误检数量正常片误检超过 5% 就不能上线二是拿缺陷片做遮挡测试把缺陷区域遮住再推理如果模型还能框出来说明它看的是背景不是缺陷。这两个测试比 mAP 更能反映真实能力。最后说个习惯每次训练完把data.yaml、训练命令、results.csv和best.pt一起归档到带日期的目录产线出问题要回溯时能快速复现。我吃过亏半年前的模型效果掉了结果找不到当时用的哪版数据只能重训。光伏缺陷检测这个方向数据质量比模型结构重要得多把标注和切图做扎实YOLOv8 默认参数就能出可用的结果。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →