简介一份面向变电站继电保护控制柜屏幕检测的计算机视觉数据集包含七百张屏幕图像配套VOC格式标注文件适用于电力智能化、工业视觉方向的研究人员与开发者可用于训练卷积神经网络、YOLO系列等目标检测模型实现电压读数、电流曲线、指示灯等元素的自动识别支撑远程监控、故障诊断与自动化巡检等场景。资源共一千四百五十个文件其中七百二十五幅jpg图像与七百二十五份xml标签一一对应压缩包约32.29MB结构清晰便于直接进行模型训练与验证该数据集采用PASCAL VOC注释标准涵盖对象名称、边界框坐标、遮挡与截断状态等关键信息可配合主流目标检测框架使用。目前已有1301人学习下载数据规模适中、标注规范适合开展屏幕检测算法实验、迁移学习调优以及语义分割等进阶研究通过该数据集电力行业有望加速实现自动化、实时的变电站监控与故障预测提升供电系统的稳定性与安全性。1. 变电站屏幕检测数据集700张VOC图能不能直接训出能用的模型变电站的继电保护屏上跳动着频率、电压、开关位置和告警报文巡检员一天要看几十面柜子靠人眼盯屏既费人力也容易漏。做屏幕检测的第一步是拿到一套带标签的工业图像数据集比如这套700张图像、VOC标签的变电站继电保护控制柜屏幕数据。先说清楚这里的“屏幕检测”定位的是屏幕区域本身不是去OCR屏幕里的每一个字符。坐标框住的是液晶屏、指示灯面板和保护装置的人机交互界面。VOC标签意味着每个XML文件里记录了目标类别和边界框能直接喂给目标检测训练流程。适合读这篇笔记的人是刚入手第一个工业视觉数据集的算法工程师或者是做电力智能巡检落地、正为训练数据发愁的实施人员。700张不算多但按正确流程处理足够训练出第一个可上验证台的检测模型。2. 先用脚本读懂VOC标签坐标、类别分布与屏幕画面构成2.1 拿到700张图先别进训练脚本先看清拍到的是什么画面很多工业数据集的坑不在模型训练阶段而在你根本不了解图像内容。我第一次拿到类似数据集时直接跑转换脚本结果训练到一半发现一半图像是过曝的另一半是柜门半开的废图。正确做法是先做目录拓扑和图像尺寸的抽样检查确认这批图的采集来源、分辨率和拍摄视角。# 先摸清数据集的目录结构与图像尺寸 find . -type f \( -name *.jpg -o -name *.png -o -name *.xml \) | head -20 python3 - PY import glob from PIL import Image imgs sorted(glob.glob(images/*.jpg) glob.glob(images/*.png)) print(图像总数:, len(imgs)) for p in imgs[:8]: im Image.open(p) print(p, im.size, im.mode) PY这段脚本做了两件事第一条命令列出数据集里的图片和XML文件的前20个路径让你看清图像文件与标签文件是否一一对应Python片段统计图像总数并打印前8张的分辨率与色彩模式。为什么要看这些因为工业相机和手机拍摄的图混在一起时分辨率差异会直接影响后续归一化坐标的准确性PIL读出来尺寸若与XML中记录的width不一致就是标签污染的源头。抽样检查建议按等间隔抽20张不用随机抽。随机抽容易集中在同一个时段等间隔能看到拍摄时间推进过程中光照、屏幕亮度和柜门状态的变化。人工过一遍重点确认三件事屏幕在画面中的占比是否稳定是否存在一个画面里出现两三块屏幕的情况以及有没有大量连续帧高度相似——如果700张里有200张几乎是同一秒拍的训练集的有效信息量就会缩水。2.2 把VOC的XML解析成统计表类别、数量、框面积分布VOC标签的XML结构很固定根节点annotation下是filename、size每个object节点里有name和bndboxbndbox里是xmin、ymin、xmax、ymax四个整数坐标。这个格式人类可读但机器处理不方便。我一般先把所有XML解析成一张CSV表后续的格式转换、类别统计、框面积分析都基于这张表。import xml.etree.ElementTree as ET import glob, os, csv rows [] for xml_path in sorted(glob.glob(labels/*.xml)): root ET.parse(xml_path).getroot() img_name root.find(filename).text for obj in root.iter(object): name obj.find(name).text 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) rows.append([os.path.basename(img_name), name, xmin, ymin, xmax, ymax, xmax - xmin, ymax - ymin]) with open(label_summary.csv, w, newline) as f: writer csv.writer(f) writer.writerow([image, class, xmin, ymin, xmax, ymax, w, h]) writer.writerows(rows)这段代码遍历所有XML把每个目标的类别、边界框坐标和宽高展开成一行。用ET解析而不是正则去抓文本是因为XML属性顺序偶尔会变基于标签名取值更稳妥。落成CSV后用Excel透视表或pandas看一眼类别分布。正常情况下这类数据集的类别名通常就是screen或者display不会太复杂。如果类别超过三种就要警惕是不是把“指示灯亮起”“按键面板”“屏幕内容区域”都单独标了类。对屏幕检测任务来说类别粒度越粗越好细分类别会让同类样本之间的差异变大模型学到的特征不够稳定。2.3 先跑一遍标签合法性自检越界、空框、张冠李戴标签合法性自检是训练前最值得花时间的步骤。工业数据集的标签往往是人工标注或半自动标注产物漏标、错标、坐标越界非常常见。脏标签直接进入训练流程loss曲线会忽高忽低模型精度上不去时你根本分不清是网络结构问题还是数据问题。import xml.etree.ElementTree as ET import glob from PIL import Image import os bad [] for xml_path in sorted(glob.glob(labels/*.xml)): root ET.parse(xml_path).getroot() img_rel os.path.join(images, root.find(filename).text) if not os.path.exists(img_rel): bad.append((xml_path, missing image, root.find(filename).text)) continue with Image.open(img_rel) as im: W, H im.size for obj in root.iter(object): 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) if xmin xmax or ymin ymax: bad.append((xml_path, zero area box, (xmin, ymin, xmax, ymax))) if xmin 0 or ymin 0 or xmax W or ymax H: bad.append((xml_path, out of bound, (xmin, ymin, xmax, ymax, W, H))) for item in bad[:30]: print(item) print(total bad:, len(bad))这个自检脚本输出三类问题图像文件缺失、框面积为零、框越界。面积为零的框通常来自标注工具误操作越界框则常出现在标注后裁剪了原图的场景。面对越界框不要一律删除——轻微越界可以用clip修正也就是把坐标截断到图像范围内面积为零的框没有任何信息量直接删除。这样清洗后的标签才配进入训练管线。我见过的项目里这类数据集直接训练出现的“翻车”十有八九是坏标签没清干净而不是模型不行。3. 把VOC转成YOLO训练输入格式换算与训练参数的选择3.1 为什么我从VOC转YOLO一句理由加一条换算公式现在主流检测训练流程无论是YOLOv5、YOLOv8还是MMDetection下的YOLO系列都偏好使用一个图像对应一个txt标签文件、每行“类别ID 归一化中心坐标 归一化宽高”的格式。VOC的像素级绝对坐标直观但不同框架对坐标系的起点定义不一致有的从左上角0开始有的从左上角1开始直接硬喂容易出边界误差。换算公式很简单x_center (xmin xmax) / 2 / W y_center (ymin ymax) / 2 / H w (xmax - xmin) / W h (ymax - ymin) / H所有坐标都除以图像真实宽高得到0到1之间的相对值。注意这里用的是XML里记录的坐标和图像的真实像素尺寸不是标注工具预览图里的缩放尺寸。转换时用错宽高比会导致检测框整体偏移这种错误在人工抽查单张图时很难发现但模型训练时就是系统性噪声。有人会问如果用的框架原生支持VOC何必多此一举我的习惯是统一转成YOLO文本格式因为工业项目里大概率会在训练中途换模型骨架换成YOLO格式后yolov5、yolov8、rtdetr等模型都能零成本切换不必再为格式适配浪费时间。3.2 转换脚本把XML和图像落成训练目录import xml.etree.ElementTree as ET import glob, os, shutil from PIL import Image # 推荐目录结构: datasets/screen_detect/{images,labels}/{train,val} os.makedirs(datasets/screen_detect/images/train, exist_okTrue) os.makedirs(datasets/screen_detect/images/val, exist_okTrue) os.makedirs(datasets/screen_detect/labels/train, exist_okTrue) os.makedirs(datasets/screen_detect/labels/val, exist_okTrue) # 预先把要进验证集的图像文件名写进 val_imgs.txt val_set set(l.strip() for l in open(val_imgs.txt)) class_names [screen] def convert_voc_to_yolo(xml_path, split): root ET.parse(xml_path).getroot() img_name root.find(filename).text if folder in {c.tag for c in root}: pass with Image.open(os.path.join(images, img_name)) as im: W, H im.size out_lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue box obj.find(bndbox) xmin max(float(box.find(xmin).text), 0) ymin max(float(box.find(ymin).text), 0) xmax min(float(box.find(xmax).text), W) ymax min(float(box.find(ymax).text), H) if xmax - xmin 3 or ymax - ymin 3: continue x_center (xmin xmax) / 2 / W y_center (ymin ymax) / 2 / H w (xmax - xmin) / W h (ymax - ymin) / H out_lines.append(f0 {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) img_src os.path.join(images, img_name) dst_img_dir fdatasets/screen_detect/images/{split} dst_lbl_dir fdatasets/screen_detect/labels/{split} shutil.copy(img_src, os.path.join(dst_img_dir, img_name)) label_name os.path.splitext(img_name)[0] .txt with open(os.path.join(dst_lbl_dir, label_name), w) as f: f.write(\n.join(out_lines)) for xml_path in glob.glob(labels/*.xml): img_name ET.parse(xml_path).getroot().find(filename).text split val if img_name in val_set else train convert_voc_to_yolo(xml_path, split)这个脚本有几个值得解释的设计。一是宽高小于3像素的框直接丢弃这类框通常来自标注手抖对训练只有噪声贡献。二是clip操作把越界坐标先拉回图像边界再判断是否值得保留。三是val_imgs.txt由你预先决定这样训练集和验证集的划分可以反复调整不需要改脚本。宽度值和height值保留六位小数避免归一化精度不足导致的小目标框抖动。转换完成后检查一下labels/train里有没有空文件。如果一个txt内容为空说明该图像的标注框全被过滤掉了对应图像应该从训练集里移走否则模型会拿一张无目标图做负样本造成误检。3.3 数据划分按拍摄场景分组别随机打散700张图的数据集最常见的错误是随机划分训练集和验证集。屏幕检测图像有一个特点同一面柜子连续拍摄的几十帧背景、光照、屏幕状态高度相似。随机划分时第3帧进训练集、第4帧进验证集验证结果会虚高因为模型几乎“见过”同一场景。现场部署时换个角度、换个柜门状态精度立刻掉下来。我一般会先按文件名中的时间戳或柜体编号分组同一组的连续帧要么全进训练集要么全进验证集。如果文件名里没有明显分组标志就按时间顺序每连续30帧作为一个分组单位做按组的随机划分。import glob, random imgs sorted(glob.glob(images/*.jpg)) # 每30帧为一个组保证连续帧不跨集合 groups [imgs[i:i30] for i in range(0, len(imgs), 30)] random.seed(42) random.shuffle(groups) val_cnt int(len(groups) * 0.2) val_groups groups[:val_cnt] val_set set() for g in val_groups: for path in g: val_set.add(os.path.basename(path)) with open(val_imgs.txt, w) as f: for name in sorted(val_set): f.write(name \n)这段代码的作用和理由是什么它把拍摄时序相近的图像捆在一起验证集不再和训练集共享同场景画面评估结果更接近“新现场”的表现。seed固定为42保证每次运行划分一致这是模型实验可复现的前提。如果验证集图像数量偏少可以把val比例降到15%但不要低于10%否则指标波动太大小改动就看不出效果了。3.4 训练命令与三个最不该乱动的参数划分完成后就可以跑第一个训练。以YOLOv8为例一条最直接的训练命令yolo detect train \ datadatasets/screen_detect/data.yaml \ modelyolov8s.pt \ imgsz640 \ batch16 \ epochs150 \ patience20 \ mosaic1.0 \ projectruns/screen_detect先解释data.yaml它指向训练/验证图像目录、类别名和类别数量YOLO框架会依据目录自动寻找对应labels下的txt文件。imgsz640是屏幕检测任务里性价比最高的起手式屏幕区域通常是画面中的中等目标640分辨率能保留边框细节又不会让显存爆炸。batch16取决于显卡显存12GB显存跑yolov8s batch16没问题。mosaic1.0的增强方式会同时拼接4张图训练对小目标检测确实有好处但这个参数配合imgsz一起动时模型表现变化很难归因——你改了分辨率又改了拼接强度指标掉了都不知道该怪谁。我的习惯是先把mosaic固定为0.5到1.0之间的经验值只调imgsz或只调batch保持单一变量。训练过程中真正值得盯的是验证集mAP50曲线和loss曲线。工业屏幕检测不要求指标突破天际mAP50能稳定在0.95以上且验证集和训练集差距小于3%就是一个可以接受的第一版模型。如果训练集mAP一路走高但验证集徘徊不前先回头查数据划分多半是同一场景的画面泄漏到了两个集合里。4. 屏幕检测避坑反光、画面刷新与标注污染4.1 反光把屏幕框“藏”起来先查验证集里有多少高光样本现场拍照最直观的坑就是反光。变电站控制柜表面通常是亮面金属或玻璃指示灯、屏幕、柜体边框混在一起阳光或LED灯直射时屏幕区域白茫茫一片纹理几乎消失。现象检出的屏幕框不稳定或者框到旁边的高光柜面上。原因训练集里高光样本占比低模型学到的屏幕特征偏向“有规则字符内容的矩形区域”一旦屏幕内容被反光吞掉特征就不存在了。解决先统计验证集里高光样本的比例低于30%就需要专门补充或做数据增强。训练时打开HSV增强的亮度抖动把亮度范围L从默认值扩展让模型见过“更亮”和“更暗”的屏幕。如果条件允许在现场调整相机偏振镜或遮光罩直接物理消除反光这比任何模型手段都有效。4.2 同一个屏幕亮屏和黑屏标签口径却不统一保护装置的屏幕有两种状态很容易让人标注时精神分裂亮屏时内容清晰屏幕玻璃边缘和显示区域边界明显灭屏或待机时整个屏发黑标注员只能靠玻璃轮廓和边框定位。现象XML里同一块屏幕有的框标的是显示区域有的框标的是整个玻璃外沿两种标签混在一起训出来的模型在亮屏和灭屏切换时会出现框的大小跳变。原因标注规范没有定义清楚“屏幕”的边界。解决定一个硬性约定——屏幕检测的目标是“屏幕组件的外接矩形框”以玻璃面板的物理边界为准不跟随显示内容缩放。这个规则从第一张图就要定死中途改标注规则等于整个数据集作废一半。如果这类数据集是别人标好的先抽样看10张灭屏样本的框位置确认口径一致再进入训练。4.3 XML坐标越界且类别为空转换时不能直接报错退出标签校验时发现越界框和空类别处理方法不是让转换脚本报错退出而是要建立一套明确的清洗规则。我见过最头疼的情况是一个XML里只有filename和size节点object节点全部丢失对应图像是纯背景图。这种图在训练中会被当作负样本如果数量很少影响有限但如果占了一成以上模型会变得过度保守屏幕上真有告警时反而检不出来。现象YOLO训练时loss出现NaN或者验证集精度归零。原因转换脚本遇到空标签直接写了空文件模型读到空标签后梯度爆炸。解决转换脚本里对空标签文件统一打标记训练配置里用超参数跳过空标签图像或者直接把这类图像移到exclude目录不让它进训练目录。清洗原则是宁可删掉10个坏框也不要让一个坏框污染训练集。坏框让模型学到错误的位置先验后面调再多的增强参数都补不回来。4.4 验证集mAP高现场却识别不到位姿和背景泛化问题这是屏幕检测类项目最典型的翻车现场。训练时看着每张测试图都框得完美mAP50刷到0.97拿到变电站现场一测同一个柜子隔了两米远或者换了个仰视角度模型就开始漏检。现象现场识别率掉一半检测框在屏幕上抖来抖去。原因700张工业图像数据集的采集工况通常很单一可能是同一台相机、固定机位、固定焦距拍出来的模型把“固定拍摄条件”当成了特征。解决把现场部署当作冷启动第一周先采集现场视频按每秒抽一帧的频率抽几百张图用已训练好的模型做预标注人工确认后加入训练集。这一步的核心思路是数据集的价值不在于700张这个数字而在于它是否覆盖了现场可能的位姿变化和光照变化。与其纠结训练参数不如尽快让模型见到“真正的现场”。5. 从700张到能上线的最小闭环指标、增量与模型反哺数据5.1 先定验收指标mAP之外还要盯漏报率屏幕检测在工业现场的验收逻辑和学术竞赛不一样。做保护屏巡检辅助时漏掉一块屏幕比多框一块屏幕严重得多。漏检意味着告警信息没有被采集到直接关系到设备状态判断所以不能只看mAP。指标参考值说明正常光照漏检率小于1%屏幕内容清晰时不允许漏检高反光/低亮度漏检率小于5%恶劣光照下允许小幅下降单屏误检率小于1%把柜体、指示灯误认为屏幕单帧推理耗时小于100ms640分辨率GPU或边缘盒子这个表是参考值具体阈值要和现场的巡检制度挂钩。如果屏幕检测模块是巡检机器人的前置环节后面还要接告警识别那漏检率还要再压一个量级。算法侧满足指标还不够最终要看连续跑一周的现场视频里的表现。我习惯在交付前留一天专门做“对抗测试”人为制造反光、遮挡、斜视、半屏亮度变化看模型哪个场景先崩当天补数据当天重训。5.2 把700张当成母库而不是训练仓库做这类工业图像数据集最容易犯的错是把它当作一次性的训练物料用完就丢。正确的做法是把它当成母库原始图像和原始XML永远不动另建工作库和镜像库。工作库存放清洗后用于训练的数据镜像库存放每次清洗动作前后的快照相当于后悔药——哪天发现某次清洗规则删错了样本还能从镜像库恢复。增量流程固定为五步新图像进母库跑标签合法性自检人工抽检标注质量转换为YOLO格式合并到工作库后重训。这个过程看起来繁琐但比每次拿到新数据就全员重标、反复调参要省时得多。迭代到第二个月时母库里的图像可能已经超过3000张但训练工作库只需要保持平衡的类别分布和场景覆盖不必把所有数据都灌进训练。5.3 用模型反哺数据集主动抽取难样本最后一个技巧是让训练好的模型帮你找数据。用当前模型在未标注的视频帧上跑预测把置信度落在0.3到0.6之间的检测框抽出来人工看这些框到底对不对。置信度很低说明模型很犹豫这些画面往往是新增光照、新增角度、新增遮挡正是当前训练集的短板。置信度很高且框准确的样本可以自动加入训练集置信度高但框偏的样本则说明存在相似干扰物需要人工确认后决定要不要标注成负样本。我在早期做这类屏幕检测项目时贪省事跳过清洗结果后续所有模型精度都上不去排查了两天才发现是坏标签在捣乱。后来凡是新数据集进入训练前都强制跑一遍标签体检这个习惯让后续所有模型都稳定了。拿到这套700张的VOC数据集顺序应该是解析统计、清洗校验、分组划分、转换训练最后带上现场数据做增量。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
给AI Agent写项目文档:PROJECT.md实战指南 1. 从一次科研翻车说起:为什么我开始给 AI Agent 写项目文档去年冬天,我在做一个材料计算方向的文献复现项目。当时手头同时开着三个 AI Agent 会话:一个用 Codex 帮我重构数据清洗脚本,一个用 Claude Code 帮我梳理实验流程&… · 2026/9/26 3:45:18
无畏契约Vanguard启动报错全解析:从服务到驱动的排查与修复指南 1. 先搞清楚Vanguard到底在干什么很多人一看到无畏契约启动报错,第一反应就是“游戏坏了”,然后开始重装游戏、重装系统,折腾一整天问题还在。实际上,无畏契约的启动链路比大多数游戏复杂得多,它不是一个单纯的游戏客户… · 2026/9/26 7:56:35
iOS国密改造实战:OpenSSL集成SM2/SM4与避坑指南 简介:面向iOS平台国密算法开发者的实践参考,内容围绕SM2加密在iOS侧的落地展开,基于GmSSL改造整理,弥补了网上iOS端缺少可直接参考国密示例的空白。作者在C语言基础较弱、现有实现代码杂乱且缺少注释的条件下反复踩坑,… · 2026/9/26 7:56:35
手写SQL解析器:词法分析、AST与生产级选型实践 简介:基于Flex与Bison这两款开源编译器工具构建的SQL解析器完整工程,面向数据库内核研发和编译器技术学习者,提供从SQL语句输入到词法切分、语法检查、抽象语法树构建再到中间表示输出的完整实现参考。压缩包共包含11个文件,以四个… · 2026/9/26 7:56:29
金融技术服务项目启动前提与内容规范 我无法根据当前输入生成符合要求的博文。原因如下:项目标题为"financial-services",这是一个高度泛化的行业术语,本身不构成具体可操作、可拆解的项目或技术主题;项目正文为空,未提供任何实质性描述、功能定… · 2026/9/26 7:56:29
LabVIEW中DAQ驱动安装全攻略:NI-DAQmx版本匹配与排错实战 搞数据采集这行,几乎绕不开LabVIEW。不管你是做测试测量、设备监控还是科研实验,LabVIEW加NI的DAQ硬件都是最常见的组合。但很多人第一关就卡住了——LabVIEW装好了,DAQ板卡也插上了,结果程序里找不到设备,一查才知道是… · 2026/9/26 7:56:29
System Idle Process占用90%别慌,教你读懂任务管理器CPU闲忙判断 很多朋友第一次打开任务管理器,看到“System Idle Process”占了百分之八九十的CPU,第一反应都是“我这电脑是不是坏了,什么程序在偷跑?”或者“这进程能不能结束掉,看着太碍眼了”。我当年第一次接触Windows的时候也是… · 2026/9/26 7:56:29
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46