
简介这份资源面向光伏运维、工业质检与AI算法学习者提供光伏板缺陷检测的完整数据集与配套模型覆盖裂纹、脏污、热斑、遮挡、破损等常见缺陷类型可直接对接YOLO等主流检测框架用于训练、验证与无人机巡检图像分析。压缩包为7z格式共2000个文件约43.16MB其中1626个txt标注文件、359张jpg与7张png图像构成训练与验证样本另有3个yaml配置、2个py脚本、2个pt权重及1个csv训练日志兼顾数据、代码与模型权重。已有64人学习下载。读者可借助现成标注数据与权重快速复现缺陷检测流程结合训练曲线与预测可视化图排查模型效果省去从零采集与标注的成本适合作为课程设计、科研实验或电站智能巡检方案的基础素材。1. 光伏板缺陷检测数据集与模型从“能用”到“好用”的落地拆解光伏板缺陷检测这个方向这两年从实验室走向产线的速度比很多人预想的快。我接触过的几个做电站巡检的团队早期靠人工拿热成像仪扫一天下来眼睛都快看瞎漏检率还压不住。后来大家开始上视觉方案核心就两件事一是有一份标注靠谱的缺陷数据集二是有一个能跑起来、精度够用的检测模型。这次拆的这个资源包标题写得很直白——光伏板缺陷数据集、模型还带检测代码。它解决的就是从零搭一套缺陷检测流程时最耗时间的那段找图、标图、训模型、写推理脚本。适合谁做新能源巡检的算法工程师、想拿光伏缺陷检测当毕设或练手项目的学生、以及需要快速验证产线视觉方案可行性的技术负责人。Python 和 YOLO 是这套东西的主轴下面我按实际复现的顺序把数据、训练、推理和坑点一层层拆开。2. 数据集结构与 YOLO 格式转换别让标注拖后腿2.1 光伏板缺陷的典型类别与数据组织先搞清楚这份数据集里有什么。光伏板缺陷常见的有几类隐裂、断栅、热斑、脏污、二极管故障。不同来源的数据集类别定义会有差异有的把隐裂和断栅合并成“内部缺陷”有的把热斑单独拎出来。拿到资源包后第一件事不是急着跑代码而是打开标注文件看一眼类别索引。YOLO 格式的标注是每张图对应一个.txt每行class_id x_center y_center width height坐标全部归一化到 0 到 1 之间。如果资源包里给的是 VOC 的 XML 或者 COCO 的 JSON就得先转。我一般会先统计一下每个类别的框数量类别极度不均衡的话后面训练策略要提前调整。数据目录的常见组织方式是这样的dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamldata.yaml是 YOLO 训练时的入口配置文件里面写清楚训练集、验证集路径和类别名称。这个文件看着简单但路径写错、类别数和标注对不上是新手翻车最多的地方。2.2 从 VOC/COCO 转 YOLO 的脚本与参数说明如果资源包里是 XML 格式用下面这个脚本转。我习惯把转换和校验放在一起做转完立刻检查有没有越界框和空标注。import os import xml.etree.ElementTree as ET from PIL import Image # 类别映射必须和 data.yaml 里的 names 顺序一致 CLASS_MAP {crack: 0, broken: 1, hotspot: 2, dirty: 3} def voc_to_yolo(xml_dir, img_dir, out_dir): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() # 图片尺寸从原图读取不要信 XML 里的 size有些标注工具会写错 img_name root.find(filename).text img_path os.path.join(img_dir, img_name) with Image.open(img_path) as im: w, h im.size lines [] for obj in root.iter(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) x1 float(bbox.find(xmin).text) y1 float(bbox.find(ymin).text) x2 float(bbox.find(xmax).text) y2 float(bbox.find(ymax).text) # 裁剪到图像边界防止越界框导致训练报错 x1, y1 max(0, x1), max(0, y1) x2, y2 min(w, x2), min(h, y2) if x2 x1 or y2 y1: continue xc (x1 x2) / 2.0 / w yc (y1 y2) / 2.0 / h bw (x2 - x1) / w bh (y2 - y1) / h lines.append(f{cls_id} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) out_path os.path.join(out_dir, xml_file.replace(.xml, .txt)) with open(out_path, w) as f: f.write(\n.join(lines)) voc_to_yolo(annotations/xmls, images/all, labels/all)这段代码里几个关键点CLASS_MAP的顺序必须和data.yaml里的names完全一致否则模型学出来的类别是错位的图片尺寸从原图读而不是从 XML 读是因为部分标注工具导出的size字段和实际图片对不上越界框直接裁掉而不是丢弃能保留部分有效信息。转完之后跑一个校验脚本统计每个类别的框数、宽高分布宽或高小于 0.001 的框基本是标注噪声建议清掉。2.3 数据增强策略与划分比例光伏板图像有个特点背景相对固定但缺陷尺度差异大。隐裂可能只占几十个像素脏污可能覆盖大半个板面。所以增强不能无脑上。我一般用 Mosaic 加随机缩放但会把缩放范围控制在 0.5 到 1.5 之间太大容易把隐裂这种小目标缩没。HSV 抖动可以开但饱和度别调太狠热斑的颜色特征比较敏感。翻转要看情况水平翻转一般没问题垂直翻转要谨慎因为光伏板的栅线方向有语义。训练集、验证集、测试集按 7:2:1 分。如果总图量少于 2000 张验证集可以再小一点把更多图留给训练。划分的时候要保证每个类别在三个集合里都有出现别出现某个类别只在训练集里有、验证集里一个都没有的情况那样验证指标会失真。3. YOLO 模型训练参数怎么设、日志怎么看3.1 环境准备与依赖版本资源包里的检测代码大概率是基于 Ultralytics 的 YOLOv5 或 YOLOv8。这两个版本 API 有差异先看requirements.txt或者代码里的 import 语句确认。我一般用 conda 建一个干净环境Python 3.8 到 3.10 都行PyTorch 版本跟着 CUDA 走。如果机器上没有 GPUCPU 也能跑但训练时间会拉长很多建议至少拿一张 8G 显存的卡做验证。conda create -n pv_defect python3.9 -y conda activate pv_defect pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics opencv-python pillow pyyaml装完之后跑一句python -c import torch; print(torch.cuda.is_available())返回 True 才说明 GPU 可用。这一步没过后面训练会默认走 CPU速度差一个数量级。3.2 训练命令与关键参数解读假设用的是 YOLOv8训练命令大概长这样yolo detect train \ datadataset/data.yaml \ modelyolov8s.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience30 \ device0 \ projectruns/pv \ nameexp1逐个说model选yolov8s还是yolov8m看你的显存和精度要求光伏缺陷检测里小目标多s版本在 640 分辨率下对小目标的召回有时候不够可以试试m或者把imgsz提到 1024。batch设 16 是 8G 卡的保守值显存够可以往上加。lr0初始学习率 0.01 是默认值如果 loss 震荡厉害降到 0.005 试试。patience设 30 表示 30 轮验证指标不提升就早停防止过拟合。lrf是最终学习率因子和lr0配合做余弦退火。训练日志里重点看三个东西box_loss、cls_loss和mAP50。box_loss降不下去说明框回归有问题检查标注质量cls_loss高可能是类别不均衡或者类别定义模糊mAP50是主要指标光伏缺陷检测里能到 0.85 以上就算可用0.9 以上算不错。如果训练集 mAP 很高但验证集低过拟合了加增强或者减模型容量。3.3 训练过程监控与中断恢复训练跑起来之后runs/pv/exp1/下面会有weights、results.csv和几张可视化图。results.csv可以用 pandas 读出来画曲线比盯着终端刷屏直观。如果训练中途断了用resumeTrue接着跑yolo detect train resume modelruns/pv/exp1/weights/last.pt这里有个坑resume依赖last.pt里保存的优化器状态和 epoch 信息如果手动改过data.yaml或者换了数据集路径resume 可能会报错。稳妥做法是中断前把整个exp1目录备份一份。4. 推理与部署从权重文件到可用接口4.1 单图推理与批量推理脚本训练完拿到best.pt先跑单图看看效果from ultralytics import YOLO model YOLO(runs/pv/exp1/weights/best.pt) results model.predict( sourcetest_images/, conf0.25, # 置信度阈值低于这个值的框不输出 iou0.45, # NMS 的 IoU 阈值重叠框合并 imgsz640, saveTrue, save_txtTrue # 同时输出 YOLO 格式的预测结果 )conf设 0.25 是通用起点光伏缺陷里如果误检多提到 0.4 试试如果漏检多降到 0.15。iou控制重叠框的合并程度缺陷密集的场景可以适当调低避免把相邻缺陷合并成一个。save_txtTrue输出的预测结果可以用来做后续的统计和对比。4.2 推理结果可视化与误检分析预测完在runs/detect/predict/下会有带框的图。我习惯把误检和漏检的图单独挑出来看误检通常是背景纹理被当成缺陷漏检多半是小目标或者低对比度缺陷。针对误检可以在训练集里加一些纯背景的负样本针对漏检把imgsz提上去或者用切片推理SAHI对小目标做专门处理。4.3 导出 ONNX 与推理加速如果要在产线部署PyTorch 权重直接跑效率一般导出 ONNX 再用 ONNXRuntime 或者 TensorRT 推理会快不少yolo export modelruns/pv/exp1/weights/best.pt formatonnx opset12 simplifyTrueopset12兼容性比较好simplifyTrue会做一层图优化。导出之后用onnxruntime加载跑一遍确认输出和 PyTorch 一致。注意导出时的imgsz要和训练时一致否则精度会掉。5. 避坑与常见问题排查5.1 标注类别与 data.yaml 不一致导致训练崩溃现象训练启动几轮后报IndexError或者AssertionError提示类别索引越界。原因标注文件里的class_id超过了data.yaml里names的长度或者顺序对不上。解决跑一个统计脚本把所有标注里的class_id最大值找出来和names长度对比不一致就重新映射。5.2 图片路径含中文或空格导致读取失败现象训练时提示找不到图片或者cv2.imread返回 None。原因数据集路径里有中文、空格或特殊字符OpenCV 和部分数据加载库处理不了。解决把数据集放到纯英文、无空格的路径下比如/data/pv_defect/别放在桌面或者带中文的文件夹里。5.3 显存不足导致 batch 调不下去现象训练一开始就 OOM或者跑几轮后显存爆掉。原因batch设太大或者imgsz太高。解决先把batch降到 8 甚至 4同时开ampTrue混合精度训练如果还不行把imgsz从 640 降到 512但要注意小目标召回会受影响。5.4 验证集 mAP 虚高但实际推理效果差现象训练日志里mAP50很高但拿新图推理时漏检严重。原因训练集和验证集划分时没有按场景分验证集里的图和训练集太像指标虚高。解决重新划分数据集确保验证集里的图来自不同电站、不同拍摄条件别让模型“背题”。5.5 导出 ONNX 后精度下降明显现象PyTorch 推理正常ONNX 推理结果差很多。原因导出时的opset版本、imgsz和预处理方式不一致。解决导出时显式指定imgsz和opset推理时用同样的归一化和通道顺序别一边 BGR 一边 RGB。6. 进阶技巧用切片推理把隐裂小目标召回拉上来隐裂这类小目标在 640 分辨率下经常只有几个像素直接整图推理召回率上不去。我试过的一个有效办法是切片推理把原图切成有重叠的小块每块单独推理再合并结果。SAHI 这个库就是干这个的和 YOLO 配合用from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction detection_model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/pv/exp1/weights/best.pt, confidence_threshold0.25, devicecuda:0 ) result get_sliced_prediction( test_images/crack_01.jpg, detection_model, slice_height320, slice_width320, overlap_height_ratio0.2, overlap_width_ratio0.2 ) result.export_visuals(export_dirsahi_out/)slice_height和slice_width设 320相当于把 640 的图切成四块每块里的目标相对变大。overlap设 0.2 是为了避免目标正好落在切片边界被切断。这个方法的代价是推理时间成倍增加产线部署要权衡。我一般只在离线巡检分析里用实时检测还是走整图。验证切片推理有没有效果别只看 mAP把同一批测试图分别用整图和切片跑一遍统计小目标框面积小于 32x32 像素的召回率变化。如果提升不到 5 个百分点说明你的小目标占比没那么高不值得上切片。从那以后我每次调完推理参数都强制走一遍分场景的召回统计不再只看一个总 mAP 就下结论。希望帮到你。本文还有配套的精品资源点击获取