
简介面向电力设备巡检、计算机视觉目标检测研究者的输电线路红外过热检测数据集针对输电线路运行中红外过热隐患难以快速定位的问题提供精细标注数据可直接用于目标检测模型的训练、验证与对比研究也适合作为高校电力物联网、智能运维相关课程的实验素材。压缩包共2000个文件以1999个Pascal VOC格式xml标注文件为主并附1个使用说明txt整体33.57MB便于直接接入常见检测框架后按需做格式转换。目前已有120人学习下载。该数据集覆盖多场景下的输电线路红外图像标注内容包括过热区域位置、温度分布等关键信息能够支撑模型学习过热特征与故障规律同时配套说明文档有助于快速理解数据组织方式对红外检测算法研究、设备状态评估项目具有实际参考价值。1. 电力场景输电线路红外过热检测数据集2253张图能解决什么实际问题做电力巡检的人都知道红外热像仪拍输电线路核心看的是耐张线夹、引流板、接续管这些发热点。以前全靠巡检工人在现场一张一张翻图像眼睛看花了也容易漏。这个电力场景输电线路红外过热检测数据集VOCYOLO格式2253张1类别.rar就是把2253张实地拍摄的红外图像按统一规范整理好只标注“过热”这一类目标同时给出VOC的xml和YOLO的txt两套标签省去自己采集、清洗、标注的漫长过程。适合想做红外视觉检测落地的算法工程师也适合用YOLOv8、YOLOv5练手单类别检测的学生。拿到手就能直接接进训练管线不需要从零处理原始热像仪文件。2. 读懂VOC和YOLO两种格式2253张图怎么组织、两类标签怎么用很多第一次拿到这种双格式数据集的人第一反应是问“我到底该用哪个”。这个问题的答案不是“哪个更好”而是“你的工具链吃哪个格式”。先把这个数据集内部的布局讲清楚才能不走弯路。2.1 VOC格式的目录结构与XML标注字段解压这个.rar之后常见的组织方式是VOCdevkit根目录下分Annotations、JPEGImages、ImageSets/Main三个目录。JPEGImages放的是2253张红外图文件名形如00123.jpgAnnotations里是对应的00123.xml每个xml文件描述一张图片里所有目标框。ImageSets/Main下的train.txt、val.txt、test.txt写的是不带后缀的图片名列表每行一个。训练脚本通过这个列表去JPEGImages和Annotations里取对应的成对文件。这里有个容易看漏的细节数据集里如果只有train.txt和val.txt没有单独的test.txt说明作者把测试集合并进了验证集你训练时需要在脚本里留出额外拆分否则最后评估会偏高。XML的核心字段就几个。folder写目录名filename写图片名source和size记录图片宽高深度。重点在object节点name是类别名这个数据集只有一个类别常见写heating或overheatbndbox里是xmin、ymin、xmax、ymax四个整数坐标表示目标框左上角和右下角。annotation folderJPEGImages/folder filename00123.jpg/filename size width640/width height512/height depth3/depth /size object nameheating/name bndbox xmin102/xmin ymin86/ymin xmax158/xmax ymax141/ymax /bndbox /object /annotation这段XML说明图上有且只有一个发热目标框坐标都是像素值没有做过归一化。VOC格式的特点就是人类可读、可视化工具友好你拿LabelImg重新打开这张图能直接看到框和类别标签。2.2 YOLO格式的txt标注与归一化坐标换算YOLO格式完全不同它不依赖xml每张图片对应一个同名的txt文件放在labels目录里。文件名仍是00123.txt里面每一行代表一个目标框格式是class_id x_center y_center width height注意全部是归一化数值范围0到1。class_id从0开始计数因为这个数据集只有1个类别所以每行开头固定是0。后面的四个数字是把VOC的像素坐标换算出来的x_center等于(xminxmax)/2/widthy_center等于(yminymax)/2/height框宽等于(xmax-xmin)/width框高同理。0 0.203125 0.221680 0.087500 0.107422用上一节XML里的数值算一遍x_center是(102158)/2/6400.203125y_center是(86141)/2/512≈0.22168宽度是56/6400.0875高度是55/512≈0.10742。这个txt不需要保留原始图片尺寸因为所有数值都是比例换什么分辨率都通用。yolo_格式的目录安排训练工具直接读images和labels两个同级目录。你拿到手的压缩包如果已经按images/train、labels/train分层放好那就最省事如果平铺在同一个目录里需要先按图片文件名把txt对拷到对应子目录。很多训练脚本的data.yaml文件里会写train: path/to/images/trainval: path/to/images/val它自动去labels目录找同名txt。这个对应关系一旦错位训练时报错信息又含糊后面专门说。2.3 两种格式选哪个训练目标与工具链决定不要“哪个熟用哪个”而要看你的下一步动作。如果你只用Ultralytics YOLO系列训练直接吃YOLO格式零转换成本如果你要做数据增强、用MMDetection、或者用LabelImg重新修改标注VOC格式更顺。常见做法是把一份数据放在VOC结构里训练前用脚本批量转成YOLO这样两头不耽误。数据增强场景优先选VOC比如你用imgaug库做随机裁剪它需要的是像素坐标框如果只有归一化的txt裁剪后还得重新归一化容易算错。反过来如果你要快速跑通一个YOLOv8的完整训练用YOLO格式能少踩“标签路径不对”的坑。选型时还要看显卡显存。YOLO格式配合ultralytics的训练管线能直接在data.yaml里设cache: True把整份数据集预加载到内存减少磁盘IO。VOC格式要先用脚本完成json中间文件转换多一步就多一个出错点。我的习惯是如果没有特殊的数据增强需求一律优先YOLO格式省心。3. 用YOLO格式跑通YOLOv8训练最小命令、参数与验证拿到这份数据集之后大多数人真正想做的事就一句话让模型能识别红外图里的过热区域。这一节给你一条能直接跑的路径先跑通再调参。3.1 安装环境与准备数据目录训练环境建议用Python 3.8到3.10的干净conda环境GPU显存最低6G因为红外图像通道单一但尺寸不小。安装ultralytics库这是目前最常见的YOLOv8训练入口。conda create -n infrared python3.9 conda activate infrared pip install ultralytics安装完成后把数据集解压并按下面的目录结构放好。如果你的压缩包已经分层直接复制过来即可如果平铺就手动创建目录结构。dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml内容如下注意names是列表形式只有一个类别时写[heating]不要写成字典格式。path: /home/user/dataset train: images/train val: images/val names: 0: heating这段配置告诉ultralytics三个信息数据集根目录、训练和验证图片的相对路径、类别名。names列表的索引就是txt里每行的第一个数字。类别名写错不会报错但最后预测结果里的名字是错的回头检查时容易懵。3.2 训练参数设置imgsz、epochs、batch、workers直接跑第一版训练推荐把显存和速度控制在合理范围。下面的命令适合一张12G或24G显卡。yolo detect train \ data/home/user/dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ workers4 \ device0 \ cacheTrue这里每个参数都有实际影响。modelyolov8n.pt是预训练权重虽然红外图和自然图像差距大但预训练带来的底层特征迁移仍然能缩短收敛时间。imgsz640是输入分辨率红外热像仪原始分辨率常见640x512缩到640既能保住小目标细节又不至于撑爆显存。batch16在12G显存下偏稳如果显存32G以上可以加到32。cacheTrue把图片提前加载进内存2253张图全量缓存大约占用内存1.5G左右完全可接受。epochs100是一个相对安全的起点。单类别目标检测收敛速度通常比多类别快50轮左右损失就开始平稳100轮足够看完整曲线。如果时间紧可以先跑50轮观察val/box_loss曲线若还在下降就续跑。训练开始后终端会输出每轮的box_loss、cls_loss、dfl_loss、precision、recall和mAP50。你的第一关注点是mAP50有没有快速超过0.8。红外过热目标通常比较小如果前20轮mAP50还在0.5以下说明anchor或输入尺寸需要调整这个放到避坑章节细说。3.3 验证结果混淆矩阵、热力图与预测输出训练完的模型以best.pt保存在runs/detect/train/weights目录下。用下面的命令在验证集上跑推理生成可视化结果yolo detect predict \ modelruns/detect/train/weights/best.pt \ source/home/user/dataset/images/val \ conf0.25 \ save_txtTrue \ save_confTrueconf0.25是置信度阈值低于这个值的框会被过滤。红外图像的对比度低背景温度梯度也大建议先保持0.25再看结果决定要不要调到0.3或0.2。save_txtTrue会生成预测的标签文件直接用脚本和真实标签做比对能算出每张图的漏检和误检。验证集上Ultralytics会自动生成confusion_matrix.png。单类别模型里这个混淆矩阵是2x2除了对角线之外最需要看的是background被预测为目标的比例那代表误检有多严重。红外场景里绝缘子、金具在白天阳光照射下也可能发热模型容易把边缘温度高的区域框出来这是正常现象需要靠后续的min_iou或回归阈值去抑制。4. VOC格式反向使用与格式互转一份脚本解决标注迁移拿到这份数据集你可能会遇上一种尴尬数据集的VOC部分想用在自己的老项目里但老项目只认自己的中间格式。或者你想把YOLO txt转回VOC来编辑标注发现坐标归一化后图像变了位置。最省事的办法是写一个小脚本在两种格式之间按需互转。4.1 为什么还要用VOC标注工具与数据增强兼容性YOLO格式虽然训练方便但手工校正标注很痛苦。你在LabelImg里打开一张图想调整一个框不可能直接看txt的0.87 0.45这种数字去心算像素坐标。这时候VOC的像素框有绝对优势打开xml看到的就是实际像素坐标想改就改。另外很多经典数据增强管道基于VOC设计。比如用albumentations的BboxParams进行随机平移、旋转时需要输入像素坐标。你如果手里只有YOLO txt就得先恢复出xmin、ymin、xmax、ymax做增强后再重新归一化。跳过这一步直接用归一化坐标做裁剪通常会出现框偏移半张图的问题。还有一点是模型集成。你要用MMDetection系列工具时它虽然支持CocoDataset但如果你从零准备数据VOC格式的voc2coco脚本是最成熟的部分。与其在中间格式上折腾不如直接保留一份VOC原始数据。4.2 Python脚本VOC转YOLO下面这个脚本是VOC转YOLO的标准实现我处理电力红外数据时一直用它。输入是VOC的Annotations目录输出是YOLO的labels目录图片尺寸从xml的size节点读不依赖文件名。import os import xml.etree.ElementTree as ET voc_annotations VOCdevkit/Annotations yolo_labels VOCdevkit/labels class_map {heating: 0} os.makedirs(yolo_labels, exist_okTrue) for xml_file in os.listdir(voc_annotations): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(voc_annotations, xml_file)) root tree.getroot() width int(root.find(size/width).text) height int(root.find(size/height).text) txt_lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_map: continue box obj.find(bndbox) xmin int(box.find(xmin).text) ymin int(box.find(ymin).text) xmax int(box.find(xmax).text) ymax int(box.find(ymax).text) x_center (xmin xmax) / 2.0 / width y_center (ymin ymax) / 2.0 / height w (xmax - xmin) / width h (ymax - ymin) / height txt_lines.append(f{class_map[name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) txt_name xml_file.replace(.xml, .txt) with open(os.path.join(yolo_labels, txt_name), w) as f: f.write(\n.join(txt_lines))逻辑说明先解析xml拿到图片真实宽高再遍历所有object节点。每个目标框先把像素坐标算出中心点和宽高再除以图片宽高得到归一化值。输出写入同名txt.6f保留六位小数足够YOLO训练使用。注意这里的class_map里类别名和数据集里的name字段必须完全一致大小写或空格不同都会导致这一类的目标被丢弃。脚本里continue的逻辑是跳过未知类别如果你只想保留某一类把这个映射表改一下就能过滤。反过来转YOLO到VOC关键是用图片真实宽高把归一化坐标放大回像素值再去构造xml的bndbox节点完成后必须检查输出坐标有没有越界因为有些txt里的框可能超出图像边缘。4.3 脚本中容易翻车的路径与类别映射细节路径问题最常见。脚本里的voc_annotations和yolo_labels如果是相对路径建议在脚本开头打印一次os.getcwd()确认当前工作目录。我实际测试时在项目根目录运行一次能正常转第二次换到子目录运行就提示找不到xml最后定位是相对路径写错了。类别映射的坑到第二轮才暴露。第一版脚本里我把class_map写成{heating: 0, normal: 1}但数据集只有一个类别结果发现xml里有个name写成了Heating首字母大写脚本把它当成未知类别直接跳过那一张图的标签文件内容为空。YOLO训练时空标签文件不会报错但会少一个正样本积累多了模型就退化成“什么框都不出”。所以转格式后一定要做统计校验数一下生成的txt文件数量是否等于xml数量再随机抽查几个txt里是否有非零坐标值。在电力红外数据里一张图往往只有一个目标框如果某个txt文件里只有一行0 0 0 0 0说明源xml的bndbox里出现了全零坐标这种脏数据训练时会持续影响损失需要提前清洗。5. 训练红外过热检测的常见坑3个真实踩坑记录这一份数据集看着简单单类别、标准化格式但实际训练中翻车的地方不少。我把常见的三类问题按现象、原因、解决写出来你不一定全部遇到遇到一个就能少查半小时资料。5.1 标签类别写错导致训练直接报错现象训练脚本启动后刚跑完第一轮迭代就在计算loss时报错提示index 1 is out of bounds for axis 0 with size 1或者干脆报Label shape mismatch。原因txt标注文件里出现了1这个类别索引但data.yaml里的names只定义了一个类别。也就是说数据集的某个或某几个txt文件里写的是别的类别编号可能是作者整理时混入了旧标签也可能是你在转换脚本里定义class_map时把映射关系写反了。解决写一个Python脚本遍历所有labels文件打印出现过的所有类别索引并统计每个索引的框数量。如果发现索引大于len(names)-1直接用脚本把这行的索引改回0并检查对应xml确认是不是标错类别。在电力红外场景里通常只关心过热这一种异常其他类别一律改为0或删除该框。import os label_dir dataset/labels/train bad_files [] for f in os.listdir(label_dir): path os.path.join(label_dir, f) with open(path) as fp: for line in fp: parts line.strip().split() cls_id int(parts[0]) if cls_id ! 0: bad_files.append((f, cls_id)) print(bad_files[:10])这个脚本只有二十行却在多次训练前帮我发现了问题。跑完这一遍再回data.yaml里确认names只有一个值训练立刻恢复正常。5.2 红外图像小目标漏检anchor与imgsz的坑现象训练曲线正常mAP50在验证集上有0.85但实际拿去测试几张红外原图很多明显的发热点没框出来或者框特别大把整个绝缘子串都圈进去了。原因红外图像里过热区域往往是一个小块比如耐张线夹的发热区可能只占整张图的2%到5%。YOLOv8默认的anchor尺寸偏大对这类小目标不敏感。另外imgsz640虽然和原始分辨率匹配但如果原始图片本身是800x600训练时被压缩到640小目标边缘信息丢失很多。解决先把imgsz提高到原始分辨率比如imgsz800或1024其次在data.yaml旁边加一个anchors配置或者直接打开模型的yaml文件把小anchor尺寸修改为[4, 6, 8]这一类更小的值。如果不熟悉anchor调参最省力的办法是改用yolov8s或yolov8m更大的模型对小目标的特征提取更充分。这里还有一层玄学红外图像是单通道温度映射和自然图像的RGB特征分布差异很大。你用预训练权重的时候前几层卷积的统计量是按自然图像算的小目标特征会被背景温度梯度淹没。所以不要省这一步训练之前先把图像数据统计出来看一下目标框面积占全图面积的比例分布如果中位数低于0.03imgsz调高是必须的。5.3 过拟合与类别不平衡2253张单类别的边界现象训练到第60轮开始训练集loss持续下降但验证集loss先降后升val/mAP50在0.8附近波动不再上涨。最终模型在训练集上表现完美在验证集上却有漏检。原因2253张图对于单类别检测来说并不算多尤其当场景高度相似时——同一个变电站、同一批杆塔角度、相近的温度色标模型很容易背下训练集的纹理而不是学到“过热区域”的本质特征。单类别的另一面是负样本很难定义没有“常温”类模型对“什么都不框”这件事天生不敏感。解决首先在训练命令里加正则和增强参数hsv_h0.01、hsv_s0.5、hsv_v0.4、degrees5、translate0.05这些增强能从亮度、轻微旋转上扩充数据。其次把训练轮数从100降到60用早停法在patience15时停止避免后期单纯拟合噪声。最后如果验证集持续不涨去检查训练集和验证集是否来自同一批数据很多数据集作者按文件名随机划分但同一个杆塔的连续帧会同时出现在两边这会导致验证结果虚高解决方法是按场景或拍摄条带分组划分。6. 让模型更抗造验证集划分、模型导出与实拍部署前检查训练好模型只是第一步能不能用起来取决于你把验证和部署环节做得够不够细。这一步不需要大改代码但每次做都能避免现场翻车。先做一次严格的划分检查。用脚本按图片文件名里的拍摄位置或时间戳分组确保同一个过热点的连续帧不会同时出现在训练和验证里。下面的代码按文件名前六位分组把同一组的图片放进同一侧。import os from collections import defaultdict images os.listdir(dataset/images) groups defaultdict(list) for img in images: groups[img[:6]].append(img) train_imgs, val_imgs [], [] for _, imgs in groups.items(): if len(imgs) 1: train_imgs.append(imgs[0]) else: split int(len(imgs) * 0.8) train_imgs imgs[:split] val_imgs imgs[split:]然后导出ONNX。用yolo export指定formatonnx这一步会把Pytorch权重转成通用格式方便在Jetson、OpenVINO或自己的C程序里跑。导出后我用Netron看一遍输入输出节点确认输入尺寸和训练时一致避免部署时把640的图塞进一个要求1920输入的模型。最后看loss曲线。训练结束后在runs/detect/train目录下打开results.png主要看val/box_loss和val/cls_loss是否在最后10轮保持平稳。如果仍有明显的下降趋势说明欠拟合可以加载last.pt续跑如果验证损失一路上扬回到上一章去检查过拟合。我的习惯是每跑完一轮实验把results.png按参数名存一份两周后翻出来对比比自己记住的靠谱得多。红外检测这类项目最大的教训就是别迷信高mAP数字现场照片和你训练集里的色标可能就差几度模型立刻变笨。所以拿到任何数据集第一件事永远是抽10张图人工标注和预测结果做并排比对眼见为实。希望帮到你。本文还有配套的精品资源点击获取