简介面向光伏运维、工业质检与科研场景的光伏板缺陷检测资源整合了标注图像数据集、YOLO模型权重及配套检测代码可直接用于裂纹、脏污、热斑、遮挡、破损等常见缺陷的识别与验证尤其适合无人机巡检图像分析。整个压缩包43.16MB共2000个文件其中359个jpg图像与7个png提供训练/验证样本1626个txt为YOLO格式标注文件3个yaml定义数据集与模型配置2个py脚本实现检测流程2个pt文件为预训练权重1个csv记录训练结果结构清晰便于快速上手。目前已有61人学习下载。通过这份资源读者无需从零构建检测系统可直接基于YOLO开展模型训练、参数调优与效果评估同时可结合csv中的指标分析模型表现适用于光伏电站智能运维、组件质量检验及算法研究等实际场景有助于降低人工巡检成本并提升缺陷发现效率。1. 光伏板缺陷数据集它到底能帮你解决什么问题光伏板缺陷检测这个事做了的人都知道靠人眼在EL图像上一张张看隐裂半小时眼睛就花了漏检率还不低。我刚接手电站巡检项目的时候第一个感觉就是缺一个能直接跑起来的起点——标注好的缺陷数据、训练好的模型权重、能改能跑的检测代码这三样缺一样都得从零开始磨。这份光伏板缺陷数据集含检测代码解决的正是这个问题YOLO格式的缺陷标注数据、可训练的模型配置、以及一套推理脚本覆盖热斑、隐裂、断栅、脏污这几类最常见的缺陷。适合电站运维的算法工程师、做无人机巡检的技术团队、以及刚入门目标检测的研究生。它不是让你从零造轮子而是把从数据到模型的这条最短路径给你铺好接下来你要做的只是把参数调成你自己的场景。2. 缺陷类型与标签体系拿到数据集先看懂这两件事2.1 光伏板缺陷热斑、隐裂、断栅、脏污在现场长什么样光伏板缺陷检测和通用目标检测有个明显差别缺陷的成像模态不统一。日常巡检拍的是可见光照片脏污、玻璃破碎这类表面缺陷直接看得见但隐裂、断栅必须用EL电致发光检测给电池片通电后裂纹位置发光强度会变暗这时候才拍得出特征热斑则要用红外热像仪温度异常区域在热图像里是亮斑。所以拿到数据集第一步先确认图片对应的成像模态这直接决定你后续做预处理的方式。从检测难度看隐裂和断栅属于低对比度的线状目标背景纹理复杂边界不清晰这是最考验模型的类别。热斑相对好检因为温度差异带来的灰度差通常很明显。脏污则要看遮挡面积大小小面积脏污很容易和阴影混淆。你训练出的模型能不能用本质上取决于它在这几类缺陷上的漏检率表现而不是整体准确率有多高。2.2 标签文件格式VOC、YOLO、COCO 之间的取舍拿到数据集后先看标注格式。常见三种格式VOC是XML文件每个目标一个object节点记录类别名和[xmin, ymin, xmax, ymax]坐标YOLO是txt文件每行一条记录格式是class_id x_center y_center width height坐标全部归一化到0~1COCO是JSON文件通过segmentation和bbox字段存储适合做实例分割或多任务训练。我一般建议训练用YOLO格式原因很实际YOLO系模型的训练代码直接读txt不需要额外写解析脚本而且坐标归一化之后不同分辨率图片可以混着训练。如果拿到的是VOC或COCO格式先做一次转换。这里给一段常见的转换脚本把VOC的XML转成YOLO的txtimport os import xml.etree.ElementTree as ET def voc_to_yolo(xml_file, class_names, save_dir): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_names: continue cls_id class_names.index(cls_name) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / 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}) save_path os.path.join(save_dir, os.path.splitext(os.path.basename(xml_file))[0] .txt) with open(save_path, w) as f: f.write(\n.join(lines)) class_names [hot_spot, crack, broken_grid, dirty] # 按数据集的类别文件顺序写 voc_to_yolo(annotations/001.xml, class_names, labels/)这段脚本的逻辑是把VOC的绝对坐标除以图片宽高换算成YOLO要求的归一化中心点和宽高。注意class_names的顺序必须和数据集的data.yaml里的类别顺序完全一致否则类别编号错位训练出来的模型预测结果全是乱的。转换完建议抽样检查随机挑几个txt文件读里面的坐标反算回像素坐标画框看看框和原图目标是否对齐。2.3 数据划分与类别不均衡别让模型变成背景检测器数据划分这件事直接照搬train/valid/test 7:2:1是不够的。光伏板缺陷数据的特殊性在于同一块板子的EL图像背景区域比例极大缺陷区域往往只占几个百分点而且同一个电站拍的图片光照、角度高度相似直接随机划分会导致验证集和训练集分布几乎重叠指标虚高。我的做法是按图片来源先分组再划分。比如同一个电站、同一次巡检序列的图片归到同一组划分时以组为单位避免同一来源的数据同时出现在训练集和验证集。另外对隐裂这种小目标缺陷建议单独统计一下每张图的目标数量如果发现超过一半的图片只有背景没有缺陷训练时考虑用drop_last或重采样策略把负样本无缺陷图片比例压下来。类别不均衡的处理会在后一章的训练参数里具体展开。这里先记住一个原则看训练日志里的loss_cls和loss_box曲线如果背景类别主导了梯度loss_cls会降得很慢且最终值偏高这时候不是加大迭代轮数能解决的要从数据采样角度调整。3. YOLO 训练实战环境、参数与结果评估一条龙3.1 环境搭建Python 版本、CUDA、PyTorch 的搭配方案训练光伏板缺陷检测模型当前最省事的路径是YOLOv8。这个数据集提供的是YOLO格式标签配合Ultralytics的训练框架命令简单改参数也直观。环境方面Python 3.9~3.11是YOLOv8官方验证过的区间PyTorch建议2.0以上CUDA配11.8或12.1。如果你用的是30系或40系显卡装CUDA 11.8的PyTorch兼容性最稳。安装步骤不复杂但版本之间互相锁死是真坑。我习惯先建独立虚拟环境再装PyTorch最后装ultralytics避免conda自动解析依赖时把版本搞乱conda create -n pv-defect python3.10 conda activate pv-defect pip install torch2.1.2 torchvision0.16.2 --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics8.1.0这里指定了CUDA 11.8对应的PyTorch版本和Ultralytics版本。--index-url指向PyTorch官方CUDA编译版本缺了这个参数pip可能装成CPU版。装完跑一句python -c import torch; print(torch.cuda.is_available())输出True说明GPU可用。如果输出False多半是CUDA驱动和PyTorch需求的cu版本不匹配优先更新NVIDIA驱动而不是重装PyTorch。3.2 训练配置数据增强与关键参数怎么设训练开始前先确认数据集目录结构。YOLOv8期望的布局是datasets/下按images/train、images/val、labels/train、labels/val分好再写一份data.yamlpath: /path/to/pv_dataset train: images/train val: images/val nc: 4 names: [hot_spot, crack, broken_grid, dirty]path是数据集根目录的绝对路径train和val填相对path的路径。nc是类别数要和names列表长度一致。然后启动训练yolo detect train \ datapv_defect.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch16 \ device0 \ patience30 \ cacheTrue \ workers4参数说明modelyolov8n.pt表示用nano规模的预训练权重做初始化光伏板缺陷是小目标为主nano模型参数量小、训练快先跑通全流程后续再换yolov8s或yolov8m提精度。imgsz640是输入分辨率如果EL图像的缺陷区域很小可以考虑imgsz960但显存占用和训练时长会明显增加。patience30表示验证集指标连续30轮不提升就早停防止过拟合。数据增强方面Ultralytics默认开启Mosaic和MixUp这两项对小目标检测有正面作用。但如果你的缺陷样本特别少Mosaic合成图里真实目标占比会被稀释这时候在配置文件里把mosaic的启用概率降到0.5mixup关掉反而更稳。我常用的是开启轻微旋转deg10和亮度抖动hsv_v0.3因为电站拍摄时光照变化是常态。3.3 结果评估mAP 高不等于能上线关键还要看 PR 曲线训练结束后runs/detect/train/目录下会生成weights/best.pt和last.pt以及results.png和confusion_matrix.png。评估指标主要看mAP50和mAP50-95前者是IoU阈值0.5下的平均精度后者是0.5~0.95每隔0.05取一次的平均更严格。光伏板缺陷场景mAP50到0.85以上算合格mAP50-95在0.6以上就比较能打。但比mAP更重要的是PR曲线里召回率掉头的点位。缺陷检测业务里漏检的代价远高于误检所以要看曲线在召回率0.7~0.9区间对应的精确率是否撑得住。如果精确率在召回率一上去就急剧下跌说明模型把大量背景当成了缺陷这时候优先检查是不是正负样本不均衡训练导致的而不是盲目加大模型尺寸。验证阶段建议单独跑一遍验证集输出每张图的检测结果肉眼过一遍yolo detect predict \ modelruns/detect/train/weights/best.pt \ sourcedatasets/pv_dataset/images/val \ conf0.25 \ saveTrue \ save_txtFalseconf是置信度阈值刚开始用0.25看多了误检再往上调。把预测图片和标签对比着看重点关注隐裂这类线状目标有没有断成几段、有没有漏检。这一步能暴露很多指标看不出的问题。4. 推理与部署检测代码怎么改才能用在巡检场景4.1 推理脚本从单张图片到批量文件夹训练好的模型最终要跑在真实巡检数据上。最基础的是单图推理Ultralytics命令行已经能完成但如果要嵌入现有的巡检软件流程建议直接写Python脚本加载模型from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict( sourceincoming/el_20250108/panel_001.jpg, conf0.3, iou0.45, imgsz640, devicecuda:0 ) for r in results: boxes r.boxes.xyxy.cpu().numpy() # 边界框格式 [x1, y1, x2, y2] confs r.boxes.conf.cpu().numpy() # 置信度 cls_ids r.boxes.cls.cpu().numpy().astype(int) # 类别编号 names r.names # {0: hot_spot, 1: crack, ...} for box, conf, cls_id in zip(boxes, confs, cls_ids): print(f类别: {names[cls_id]}, 置信度: {conf:.2f}, 坐标: {box.tolist()})source参数既支持单张图片路径也支持文件夹路径或视频文件路径。iou是NMS的IoU阈值默认0.45如果检测目标密集、多个框堆在一起适当调到0.5或0.6如果目标是稀疏的大目标0.4更合适。返回值里r.boxes是核心结果对象注意所有张量都在GPU上需要.cpu().numpy()转成numpy数组再处理。4.2 置信度阈值调整平衡漏检率和误检率推理阶段最容易忽略的是conf参数的业务含义。光伏板检测场景EL图像里一块隐裂漏检意味着这块板子可能带着隐性损伤进入下一道工序损失可能是一整块组件的更换成本。所以阈值不能拍脑袋定要基于验证集上的PR曲线来选。回到第3章的验证结果找到confusion_matrix.png里的false negative分布看漏检集中在哪一类、哪个置信度区间。我一般会在部署前做一次阈值扫描把验证集跑一遍让脚本在conf0.1到conf0.6之间按步长0.05输出每类的精确率和召回率画成表格。然后根据业务诉求选误检可以接受就选召回率最高且不崩的阈值误检零容忍就选精确率高于0.9的最低阈值。这个操作一定要真实数据跑不要凭经验猜——不同成像条件下模型的置信度分布差异很大。4.3 部署到边缘设备TensorRT 与半精度推理巡检场景很多时候跑在无人机机载设备或现场的工业主机上显卡资源和功耗受限。把模型从PyTorch转到TensorRT是当前最成熟的提速方案。先用Ultralytics导出yolo export \ modelruns/detect/train/weights/best.pt \ formatengine \ device0 \ halfTrue \ imgsz640导出成TensorRT的.engine文件后推理速度通常能比PyTorch原始模式快2~4倍。halfTrue启用FP16半精度显存占用减半精度损失在这类缺陷检测任务里基本在1个mAP点以内。如果机载设备的GPU只有4GB显存这是推荐的格式。CPU部署则优先导出ONNX配合OpenVINO或ONNX Runtime跑但速度上限比TensorRT低适合后台离线检测而非实时巡检。5. 光伏板检测避坑五条高频问题的现象与排查5.1 训练Loss不下降、验证指标震荡现象训练前50轮box_loss几乎平着走验证mAP在0.3~0.5之间反复震荡上不去。原因最常见的是标签文件和图片不对应——复制数据集时images和labels目录里的文件名前缀不一致导致相当一部分图片没有对应的标签文件模型把大量无缺陷区域当成了背景。另一个可能是data.yaml里的names顺序和标签文件里的class_id对应不上比如标签tXT里写的是0隐裂但yaml里names[0]是hot_spot。解决先用脚本检查数据集读每张图片确认labels目录下存在同名txt文件且txt里的内容行数0。再随机读一个标签txt的前几个数字比对yaml里names的实际类别含义。验证无误再重新训练。5.2 训练Loss正常但预测时全是误检现象训练日志显示mAP50有0.87但部署到现场数据上玻璃边框、阴影、甚至杂草全被框成缺陷。原因训练集和现场数据的分布差异过大。光伏板缺陷数据集的图片通常来自特定的EL设备和红外设备现场如果是可见光相机拍的成像特征完全不同。另一种可能是现场图片分辨率过高缺陷被放大后纹理特征和训练集不一致。解决先做成像模态对齐——EL模型只能用在EL图像上硬拿去做可见光检测必翻车。如果是分辨率问题推理时把imgsz调整为和训练一致的640同时检查现场图片的光照归一化是否和训练集一致必要时加上灰度均衡预处理。5.3 小目标缺陷大量漏检现象mAP整体尚可但单独统计隐裂类别的召回率只有0.4左右推理结果里细长裂纹被检测成断断续续的小片段。原因YOLO的下采样倍数导致小目标特征丢失。输入640分辨率下模型输出特征图的步长是8/16/32细长裂纹的宽度只有几个像素时下采样后特征几乎消失。另一个因素是训练时的Mosaic增强把小目标进一步缩小了。解决把imgsz提高到960或1280同时开启Ultralytics的scale和close_mosaic参数最后10轮关闭Mosaic让模型适应真实尺度。如果还是不够换用yolov8s或yolov8m提升特征提取能力或者改用分割模型检测线状缺陷。5.4 训练中显存溢出OOM现象batch设为默认值16训练到第3轮直接CUDA out of memory。原因单张EL图像的分辨率可能远高于默认的640Ultralytics内部会先按原始分辨率读取再做resize峰值显存被原始图撑爆。解决不要只调batch先确认imgsz是否和原始分辨率匹配。imgsz640时batch设8~12是4GB显存卡的上限还可以开cacheTrue和workers0减少显存碎片。如果显存实在不够把optimizer换成SGD而不是默认的AdamW后者在部分版本下显存开销更大。5.5 验证集指标虚高、现场表现差现象验证集mAP50达到0.9但把另一批新拍的图片丢进去准确率直接掉到0.6。原因数据集划分时没有按来源分组同一电站同一批次的数据既在训练集又在验证集模型等于开卷考试。解决回到第2章的划分策略按采集批次分组划分。如果没有现成分组信息可以按文件名前缀或拍摄日期聚合。更严格的做法是留出一个完整电站的数据做跨域验证训练和调参过程中完全不碰这批数据。6. 进阶模型量化与裁剪让检测代码跑在低配设备上巡检场景里不是所有设备都带得了高性能GPU。无人机机载的嵌入式计算板显存通常只有2~4GB电站老旧的工控机更是只有CPU。除了前面提到的TensorRT半精度导出还有两条路可以压模型体积和推理开销一是INT8量化二是通道裁剪。INT8量化的核心思路是把权重从FP32映射到INT8的256个离散值。以YOLOv8为例用Ultralytics导出INT8版TensorRT时需要准备一批校准图片from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) model.export( formatengine, imgsz640, int8True, datapv_defect.yaml, calibrateTrue, calib_batch_size16 )calibrateTrue会从pv_defect.yaml标注的训练集里自动抽取图片做校准校准图片的数量和多样性直接影响量化后精度掉点幅度。实测下来光伏板缺陷任务INT8量化后mAP50通常掉2~3个点但推理速度比FP16再快一截显存占用也进一步降低。如果精度掉到不可接受退回到FP16方案。通道裁剪这条路我一般只在模型尺寸大于40MB且精度富余时才做。做法是先对每个通道的权重做L1范数统计剪掉贡献低的部分再用训练集做短周期微调恢复精度。Ultralytics的prune接口目前支持全连接层裁剪对卷积层的剪枝需要自行实现。我更推荐针对线状缺陷场景做另一件事把imgsz从640降到480配合模型降级到yolov8n推理耗时能砍一半以上精度损失往往小于换模型架构的决定性影响。验证量化效果我习惯跑同一批30张典型图片分别用FP32和量化后的模型推理对比每张图的检测框坐标差异和置信度变化。坐标偏差小于2个像素、置信度下降不超过0.15基本可以放心上线。从那以后我每次部署到新设备都强制走一遍这个对比流程——先在开发机上量化再拿到目标设备上跑真实巡检视频确认精度和帧率都达标才收工。这套流程救过我不少次希望帮到你。本文还有配套的精品资源点击获取