资讯动态

无人机光伏板热成像缺陷检测数据集:VOC/YOLO双格式实战解析

发布时间:2026/10/17 7:22:47 来源:尧图企业网站定制
去年给一个地面电站做巡检方案的时候我们原以为最难的部分是飞无人机、采集热像图结果真正卡住整个团队的反而是数据侧无人机拍回来的热像图一大堆但没有任何一张带标注目标检测模型根本无从下手。后来我们把整个数据链路走通才意识到一个像“无人机视角太阳能光伏板热成像红外图像缺陷检测数据集VOCYOLO格式1229张5类别”这样的数据资产价值不只是能喂给YOLO跑一轮训练而是背后从采集规范、缺陷定义、标注边界到格式转换的整套方法论。这篇就围绕这样一个1229张、5个类别、同时提供VOC与YOLO标注的数据集把整个使用链路拆开聊清楚。适合拿到类似数据准备训练检测模型的算法工程师、做光伏电站智能运维的团队以及准备自己采集热成像数据做缺陷检测的研究者参考。1. 无人机热成像巡检为什么能一眼看出光伏板故障1.1 热斑、二极管和接线盒发热源背后的物理原因光伏组件正常工作时电池片将光能转化为电能自身温度虽然会升高但整体分布相对均匀。一旦某片电池片出现裂纹、旁路二极管被击穿、接线盒接触电阻变大或者被人为脏污、植物阴影遮挡电流会被迫从高阻区流过局部迅速升温热像仪上就会出现明显的异常区域专业上叫热斑。热斑的温度往往比正常区域高出20到40摄氏度在红外图像里表现为一个高亮团块。这就是热成像缺陷检测最基础的物理依据。不过这里有个容易忽略的点热成像拍的其实是温度分布不是“缺陷照片”。缺陷和温度异常之间是强相关关系但不是绝对一一对应比如组件的隐裂在组件刚出厂时用EL检测很清晰在热像图上却未必有温差表现。所以做这类数据集时类别定义一定是从“热像图上能不能被稳定辨认”出发而不是从实验室定义出发。无人机加挂热成像相机还有一个优势是手持红外仪完全比不了的工作高度固定、航线可规划、机身姿态稳定拍出来的热像图视角统一、比例一致做目标检测时目标尺度不会忽大忽小。正射航拍下一块组件的热异常区域基本是矩形或椭圆形标注框的形状也相对规整。1.2 1229张图的数据集长什么样标题里给出的关键信息可以拆成四块无人机视角、热成像红外图像、缺陷检测、VOC与YOLO格式。组合起来这就是一套典型的“巡检数据资产”。1229张图对于深度学习目标检测来说属于中小规模数据集但考虑到热成像无人机巡检的单次任务成本1229张覆盖一个电站的多个区域、多种天气条件已经有一定代表性。VOC和YOLO双格式意味着这套数据既能接入基于PASCAL VOC规范的老牌检测框架也能直接用YOLO系列跑起来。5个类别则对应着热成像缺陷检测里最常见的故障类型下一节展开说。一个标准的热成像缺陷检测数据集目录结构通常是这样的pv_thermal_dataset/ ├── images/ │ ├── train/ # 约980张 │ ├── val/ # 约180张 │ └── test/ # 约120张 ├── annotations/ │ ├── train/ # VOC XML标注 │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ # YOLO txt标注 │ ├── val/ │ └── test/ ├── classes.txt └── data.yamltrain和val的划分比例通常在8比1到9比1之间关键是验证集尽量来自不同航线或不同时段而不是从同一组照片里随机抽否则验证集和训练集高度相似模型评估虚高。2. 5个缺陷类别怎么定经典方案与标注边界2.1 热成像缺陷五分类的常见组合数据集标题只说“5类别”没有给出每类的具体名字。在实际的光伏电站热成像缺陷检测中最常见的五分类组合是热斑、二极管故障、接线盒过热、阴影遮挡、隐裂或断栅。下面这个表格是按这类数据集的通用来拆解的每类缺陷的成因和热像表现都不同。类别缺陷成因热像图表现标注要点hotspot热斑电池片隐裂、电阻异常组件内部出现高亮圆形或条状发热区只框住明显过热区域不包整个组件diode二极管故障旁路二极管击穿或反向漏电组件侧边条带整体发亮沿发热条带拉矩形框包含两端junction_box接线盒过热接线端子松动、接触电阻大组件背面接线盒位置高温亮斑框住接线盒区域注意和热斑区分shadow阴影遮挡植物、鸟粪、灰尘堆积遮挡区域因电流不均产生局部过热框出过热区域不是框遮挡物本身crack隐裂/断栅电池片裂片、栅线断裂细条状温度异常部分区域偏暗框住温度异常区宁可略大不要过小如果你手上的数据类别定义不同也正常比如有的数据集会把“接线盒过热”和“二极管故障”合并或者单独拆出“组件整体过热”。关键是每一类在热像图上都必须有肉眼可分辨的统一视觉特征这是标注一致性的基础。2.2 标注框的边界几何别把温度梯度全包进去所有做过热成像标注的人都会遇到一个共同困扰缺陷区域的边缘在哪。热斑不是从20度突然跳到60度的温度是从中心向外逐步衰减的如果按“比周围区域亮”来框很容易把整片组件都框进去因为组件边缘本来就有温度梯度。我的经验是定三条硬规则框的边界取“温度梯度最陡”的位置而不是等温线的最外圈。当一个热斑旁边有几根栅线也异常发热时合并成一个框不拆成多个小框。拆成多个小框会造成模型训练时同一个缺陷的多个相同实例互相干扰。对检测置信度影响最大的是标注框的中心位置而不是边缘的微小偏差。宁可框稍微大一圈也不能让中心偏离缺陷区域。另外热像仪有自动量程功能同一片组件在不同帧里因为全局温度范围不同缺陷的对比度会不一样。标注时一定基于每一帧的当前温度映射去判断不要拿上一帧的视觉标准往下一帧套。标注完最好把所有标签反向画回原图扫一遍看到框的中心点全落在发热区上再进入格式转换步骤。3. VOC与YOLO双格式一份能直接跑的转换流水线3.1 目录结构、类别映射与两个格式的差别VOC格式和YOLO格式是深度学习检测领域的两套基础标注规范。VOC格式是每个图像对应一个XML文件里面记录图片尺寸和每个目标的类别名、边界框坐标坐标单位是像素。YOLO格式则是每个图像对应一个txt文件每行记录类别ID和归一化后的中心点坐标、宽高。两者本质是同一个信息的两种表达方式但在工程上转换很容易出问题。主流的检测训练框架这边YOLO系列直接用txt格式原生加载而MMDetection、部分老版本的Faster R-CNN项目更习惯VOC XML目录。所以数据集同时提供VOC和YOLO可以理解为给不同工具链都做好了准备。类别映射表放在classes.txt里顺序必须和训练配置中的names完全一致0 hotspot 1 diode 2 junction_box 3 shadow 4 crack转换前先核对类别名大小写Hotspot和hotspot在程序里是两个东西这种低级错误会让整个验证集类别对不上。3.2 转换脚本的实现与边界处理VOC转YOLO的核心逻辑其实不复杂解析XML里的size标签拿到图像宽高然后把bndbox里的像素坐标除以宽高得到归一化坐标。容易出现坑的地方有三个XML里没有size标签、边界框超出图像边界、类别名不在映射表里。下面这个脚本是我实际用来批量转换的版本做了基本的防御性处理import os import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, class_dict, output_dir): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) if img_w 0 or img_h 0: print(f[跳过] {xml_path} 尺寸无效) return out_lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_dict: print(f[警告] {xml_path} 含未知类别 {name}) continue cls_id class_dict[name] bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 边界保护避免超出图幅的框 xmin max(0, xmin) ymin max(0, ymin) xmax min(img_w, xmax) ymax min(img_h, ymax) w xmax - xmin h ymax - ymin if w 1 or h 1: continue cx (xmin xmax) / 2 / img_w cy (ymin ymax) / 2 / img_h nw w / img_w nh h / img_h out_lines.append(f{cls_id} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}) save_name os.path.basename(xml_path).replace(.xml, .txt) with open(os.path.join(output_dir, save_name), w) as f: f.write(\n.join(out_lines))几个处理细节值得说清楚。第一个是归一化坐标保留6位小数足够保持精度。第二个是类别名匹配我用了精确匹配因为热成像数据集的类别定义一旦出现同义词混用比如junction_box和junctionbox模型训练的时候验证集标注和训练集标注就成了两类损失会一直降不下去。第三个是过滤掉面积小于等于1像素的框这种框在后续数据增强里容易变成无效标签。3.3 转换后的校验反向解析和空标签排查格式转换最怕的就是“看起来转换成功了训起来全是问题”。我通常做三层校验每一层都能拦住一类问题。第一层检查每个txt文件是否都对应一张真实存在的图片。用Python做一次os.listdir比对缺图或缺标注的单独输出这一步能挡住文件名后缀不一致、大小写不一致的问题。第二层把转换生成的txt再反向解析成矩形框画回原图上人眼抽查。这一步的目的是确认坐标没有整体偏移、归一化顺序没有搞反。YOLO的归一化顺序是cx cy w h曾经有团队把顺序记成xmin ymin w h训练了50轮才发现。第三层统计每个类别的实例数量分布。如果5个类别里有两个类别只有十几二十个实例说明类别极端不平衡后面训练时需要考虑权重调整或样本扩充。校验无误后data.yaml里names的顺序就是classes.txt的顺序train和val路径指向images目录模型训练时框架会自动按同样的stem名去labels目录里找txt标注。4. 1229张热成像图喂进YOLO预处理、训练与实测4.1 单通道红外图像的处理为什么很多人复制成三通道热成像相机直接输出的是一张温度矩阵为了让人眼看得舒服设备会把温度值映射成灰度图或者伪彩图。很多工程师拿到手的是伪彩图JPEG直接当成普通三通道图拿来训练也能跑但有个问题伪彩色映射是设备预设的比如黑热、白热、彩虹三种模式同样的缺陷在不同模式下色彩完全不同。我的建议是优先转成灰度图使用如果原始是伪彩图也先用OpenCV转回灰度或者从原始16bit温度数据直接归一化到0到255。灰度图的像素强度和温度单调对应模型学到的就是纯粹的温差模式换一台热像仪或者换一个色板时迁移效果更好。那为什么要复制成三通道纯粹是为了加载预训练权重。YOLOv8这类模型默认输入是三通道预训练权重是在三通道的彩色数据集上训练的。如果把单通道图直接输入第一层卷积的输入通道数不匹配要么改模型定义要么丢弃预训练权重从头训练。更省事的做法是把灰度图用np.repeat复制三次构成三通道图import cv2 import numpy as np img_gray cv2.imread(ir_001.png, cv2.IMREAD_GRAYSCALE) img_rgb cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)灰度复制成三通道不会增加信息量但能完整复用预训练权重对1229张这种中小规模数据集来说预训练权重的收益非常明显值得做这个操作。4.2 小目标检测思路与关键参数无人机在正常巡检高度下一块组件在图里大概占几百个像素热斑往往只有几十到一百像素。这在目标检测里属于典型的小目标问题。训练参数要从这个现实出发。全局分辨率这一项imgsz我建议设在640到800之间不是越大越好因为放大后热成像的低分辨率会突出模糊模型容易学到模糊纹理。类别数量只有5个模型选择上yolov8n或者yolov8s就够用s参数量的收益在这样一个数据规模上已经开始变小。小目标问题更有效的解法是切片推理。高分辨率热像图在训练时按640切块推理时也切块跑再把所有窗口的结果拼回原图坐标。这个思路和SAHI等工具的做法一致。只改输入分辨率而不切块小目标的比例还是太低模型很难专门为小目标分配足够多的anchor。训练命令可以参考下面这个示例yolo detect train \ modelyolov8n.pt \ datapv_thermal.yaml \ epochs150 \ imgsz640 \ batch16 \ close_mosaic10close_mosaic10的用意是最后10个epoch关闭马赛克增强让模型逐步从高难度样本过渡到正常分布避免因为增强太猛导致最后一轮验证分数振荡。这个参数在中大型数据集上影响不大在小数据集上能明显稳住收敛曲线。4.3 实测效果和调优顺序一个1229张、5类别的热成像光伏缺陷数据集用默认的YOLOv8n加上预训练权重跑150轮比较合理的结果是mAP50稳定在0.8上下mAP50-95大约0.55到0.6。这个数字看起来不高不低但在热成像领域已经具备实用价值因为巡检业务的评价指标本来就不是纯竞赛mAP。调优的顺序我建议是先看验证集的漏检和误报不看总指标。对电站巡检来说漏检的代价远大于误报。热斑漏掉了这块组件后续可能引发火灾误报了最多让人工复检时多看一眼。所以置信度阈值不要用默认的0.25实际部署可以放到0.15到0.2让模型多输出一些候选框靠人工过滤。如果发现某个类别比如diode的召回率明显低于其他类别第一反应不是调loss权重而是去数一下训练样本里diode的数量和标注质量。很多情况下不是模型问题而是这个类别的样本只集中在少数几帧里模型看到的变化太少学不充分。训练过程中的另一个常见问题是验证集loss下降但mAP震荡先不要急着加trick去检查验证集里是不是混入了和训练集同一条航线的相邻帧。这种样本泄漏会让验证分虚高调任何参数都没有意义。5. 数据集的短板类别不平衡、域迁移和漏报代价5.1 千张级数据集的三个绕不开的问题1229张图能支撑一个初版检测服务跑起来但要说成熟还差得远。第一个短板是样本量。一个类别如果只有30到50个实例模型基本只能记住见过的那几种形态新增电站的组件型号一变泛化就崩。这不是算法能完全解决的只能靠持续补数据。第二个短板是类别不平衡。热斑出现频率最高二极管故障和接线盒过热相对较少而且这两类在热像图上有视觉相似性都是侧边或接线盒位置的发热。如果训练集里其中一类只有另一类的五分之一模型会把两类混成一个。解决思路有两种一类是用过采样复制少数类图像来参与训练但不是简单复制而是要配合几何增强旋转、翻转让同一张图产生多个变体另一类是直接用热像图检索扩充把同电站其他航次拍到的同类缺陷也挑出来补标。第三个短板是域迁移。热成像对时间、天气、组件温度非常敏感。同一个电站在冬天早上和夏天中午拍出来的热像图温度分布差很多模型在早上数据上训练完后到中午数据上推理mAP掉十几个点是常事。处理手段是用温差归一化在输入前减去当前帧的背景温度均值让模型学到的是相对温差而不是绝对灰阶。这个操作做对了跨场景的稳定性会明显提升。5.2 把数据集用进巡检闭环先预筛后复检真正在电站里落地时这套数据集的最佳角色是“缺陷预筛”。具体流程是无人机飞完一个区域后单帧单帧地跑模型推理把所有疑似缺陷都标出来然后由人工在平台上逐帧确认。这样模型的目标不是替代人工而是把巡检员从几千张图里解放出来只需要盯住可能有缺陷的几十个候选框。这个流程对数据集的另一个好处是人工复检的每一条确认结果都会成为新增训练样本。缺陷被人工标了“确认”或“误报”就把这张图归入对应的正负样本库每周增量补一次标注。1229张的初始数据集经过两三个月的闭环运行就能长成七八千张的有效数据集。数据回流时注意要把新增样本和原始训练集合并重训而不是只在旧权重上继续小批量微调否则模型会出现灾难性遗忘旧电站的缺陷反而不会检测了。5.3 从5类到故障等级数据集的下一个形态单一缺陷类别只能回答“哪里有缺陷”运维团队真正关心的是“这个缺陷严不严重”。同样的热斑缺陷温度差30度和10度的处置优先级完全不同。下一阶段的数据集可以在5个缺陷类别之上为每个目标增加一个温度等级属性比如正常、轻微异常、严重过热。标注时直接在热像图软件里读取缺陷中心温度换算成温差等级写入标注。这个升级不需要改变模型结构可以把检测和分级拆成两个阶段先用现有5类检测模型定位缺陷再用缺陷中心小图训练一个温度分类模型。相较于直接预测量级回归分类的稳定性更高因为热像图的绝对温度受环境和自动量程影响巨大但离散的等级判断相对稳健。做这个升级时不要漏掉一个细节温度读取要从原始16bit温度数据解析不要从8bit灰度图反推。8bit图已经丢失了量程信息从里面读出来的温度值是锁死的到另一个环境温度下就不对了。我做数据处理这些年最深的体感是标注数据和训练模型的难度几乎不在一个量级上。模型最多花几个小时重训标注规范定错一次返工量可能是几周。无论你是用这个1229张的数据集还是准备自己采一批无人机热像图拿到图之后的第一件事永远是把类别定义、标注边界、格式规范这三样钉死然后再谈调参。这套流程走顺了数据集才会越用越值钱而不是越用越乱。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑