远看一根好好的铁塔,无人机飞近绕到背面才发现绝缘子串上挂着一个鸟巢,再拉近一点,塔材的锈蚀和销钉缺失都藏在阴影和线缆交错里。这类场景我盯过太多次,真正的问题从来不是“看不看得到”,而是“人能不能在几千张图里始终保持这种眼力”。无人机电力杆塔巡检、杆塔头部缺陷识别数据集、输电线路安全监测,这几个词在项目里其实是一件事:把人工巡线的“眼力”交给模型,让缺陷在第一现场就被框出来。这篇内容是我做完一套电力杆塔智能巡检缺陷识别数据集的完整复盘,覆盖了数据采集、标注体系、模型训练、端侧部署和数据迭代的整个过程。如果你正在做电力巡检类的视觉识别项目,或者是刚接触工业场景数据集建设,这篇应该能帮你少走不少弯路。
1. 为什么我放弃纯人工看图:巡检数据量的账算不过来了
1.1 一个杆塔的“体检”到底要盯多少张图
先说数据量。我之前做过一个模拟项目X,给某电力公司做输电线路杆塔巡检的试点,一条220kV线路大约40基塔,无人机按航线飞下来,每基塔少则200多张图,多则400张出头。为什么差这么多?杆塔高度、绝缘子串数量、塔材复杂程度、场地限制导致需要补拍的位置不同,都会直接影响最终拍摄张数。40基塔完全巡检下来,大概稳定产出8000到12000张可见光照片。
这批图拿回办公室,人工逐张检查,按平均每人每天认真看1500张来算,八小时做这件事,一个人要四五天才能全部看完。而且看清之后还要截图、标注位置、写缺陷记录、填检修工单,整套动作下来,单基塔的平均处理时间至少半小时。一个巡检周期跑一个月,光看图就吃掉两个专职人力。
纯人工看图在规模小的时候还撑得住,线路一旦超过100公里,无人机采集效率高、人工消化效率低这个矛盾就彻底暴露了。所以我做这个项目的第一件事不是选模型,而是把“多少数据让机器先看一遍,再让人聚焦看可疑框”这件事想清楚。
1.2 人工看图的三宗罪:漏检、疲劳、缺陷不可追溯
漏检是人工看图绕不过去的坎。我做过对比测试,让同一位有三年经验的巡检员分三天看同一批500张图,三次标出的缺陷数量并不一致,差异最大的一次差了近六分之一。这不是责任心问题,是视觉疲劳导致注意力骤降的自然结果。而且密集塔材区域里小缺陷只有十几个像素,人眼在缩放浏览时极易略过。
第二个问题是疲劳,这个很好理解,但我更在意的是第三个问题——不可追溯。人工记录大多写“第3号塔横担处疑似锈蚀”,等检修人员带着工单过去,现场情况可能已经变了,到底是锈蚀、污闪还是异物附着,没有统一的图像证据链。而模型自动检测可以在产生告警的同时保存缺陷截图和坐标,检修人员拿到的是可核验的原始依据,这个差别在隐患闭环管理里非常关键。
1.3 为什么标题强调“杆塔头部”:缺陷密度分布太集中了
做数据采集前我让团队统计过缺陷实际出现的部位分布。结果很直接:绝缘子串、防震锤、线夹、销钉这些“杆塔头部”区域的缺陷数量,占到了总量的七成以上。塔身中下部的缺陷相对简单,主要是锈蚀和藤蔓异物,误检率低、类别也少。真正让检测系统头疼的,全部集中在杆塔头部——部件种类多、互相遮挡严重、背景有天空有大地也有远处塔身,光照变化又极端。
这就是为什么数据集必须针对杆塔头部重点采样。把采集分辨率、拍摄角度、标注精细化程度都往头部区域倾斜,模型才能在最困难的区域积累足够多的正样本。这个问题你要是只按等间距采集所有部位,模型大概率会在塔头部位反复漏检,因为那里缺陷类型多样且尺寸变化极大。后面我在标注和训练里做的很多调整,出发点都是为了解决头部区域的小目标检测难题。
2. 数据集的“骨架”:杆塔各部位缺陷标注怎么做才不返工
2.1 采集侧的三个硬约束:分辨率、重叠率、光照一致性
数据集的源头是采集,采集侧如果出问题,后面标注和训练全是在劣质数据上盖房子。我在最初设计采集方案的时候定了三个硬约束,后来都证明是值得坚持的。
第一个是拍摄分辨率。杆塔头部的缺陷目标普遍很小,比如销钉缺失可能只有30×30像素。这个尺寸在4K原图上还能辨认,但如果你为了节省存储把图缩到1080P再标注,那训练出来的模型基本告别了远距离识别。我定了一个基线:塔头区域拍摄分辨率不低于5472×3648,并且单张原图里塔头区域占比不得低于三分之一。
第二个是重叠率。无人机巡检航线必须保证相邻两张照片有至少70%的重叠率。道理很简单,缺陷是三维的,一个鸟巢从左侧看和从正面看完全是两个形态。多视角覆盖能帮模型学到更鲁棒的特征,同时训练时还能拿同一个缺陷的不同视角做数据扩充。
第三个是光照一致性,这是最容易忽略的。同样是背光面和顺光面,绝缘子串的纹理细节完全不一样。如果整个数据集里80%的图都是晴天上午十点拍的,模型遇到阴天或下午逆光场景就会大量漏检。所以采集最好安排在上午9点到11点、下午2点到4点半两个窗口,并且每个塔至少补拍一组背光方向的照片。这些约束看着麻烦,但做数据集如果不在采集期把关,后面所有环节都在替采集期买单。
2.2 缺陷类别体系怎么定才不打架
分类体系是标注之前必须拍板的事。类目太粗,模型分不清锈蚀和污秽;类目太细,标注一致性会崩,训练样本量也被摊薄。我最终定下来的一级类别以常见可识别缺陷为准,包括:鸟巢、锈蚀、异物悬挂、绝缘子破损/自爆、销钉缺失、防震锤移位/脱落、线夹异常、塔材变形,以及一个“其他疑似缺陷”做兜底。
这里有一个关键的取舍:“锈蚀”与“污秽”必须合并还是分开。我一开始是分开的,结果标注员频繁争论某块区域到底是锈蚀还是污垢。在无人机距离下,这两类从视觉上经常无法严格区分,最后的做法是把它们合并成“锈蚀/污秽”类,只在描述字段里备注程度。这不丢信息,却有效降低了标注方差。
另一个容易出问题的类目是“异物悬挂”。鸟巢其实属于异物的一种,但如果把所有异物都塞进一个类,鸟巢这种高优先级缺陷的检出又会受影响。所以我把鸟巢单独拎出来,其他编织物、塑料袋、风筝线等统称异物悬挂。这个拆分逻辑后来被证明是对的:鸟巢类别的单独识别成功率明显高于合并时期。
2.3 标注环节最容易翻车的地方:框怎么打、难例怎么定
标注环节我不是直接丢给标注员就完事,而是定了一套明确到像素级的规范。我要求所有目标框用矩形框,采用“贴合目标外轮廓、可包含10%以内的背景”原则。对销钉缺失这种极小目标,允许框略大以包含周围参考结构,但必须在备注里写明。对遮挡超过50%的目标,不标注;被线缆完全覆盖无法判断的,同样不标注。这些规则看起来细,但它们是保证训练标签干净的基础。
每批标注完成之后,我会抽检10%的图做二次校验。统计Kappa系数,低于0.7的批次直接退回重标。这里需要提一句质量控制的现实:标注员对“销钉缺失”的理解会漂移,昨天觉得这个算、今天觉得那个不算。所以我每周会开一次统一标注意见的短会,把本周产生争议的难例截图拿来一起定标准。每次定完标准,标注准确率都会有明显回升。
难例库是这个阶段最容易被低估的产出。我把所有标注争议大的、多次漏检的、模型频繁误报的图单独存放,和训练集分开。这个难例库在后面每一轮模型迭代里都会反复被拉出来验证,相当于给模型立了一面镜子——哪里不行,它一眼就能告诉你。
3. 模型选型与训练调参:小目标缺陷的检测实录
3.1 为什么先试单阶段检测器,后来又被我换成两阶段路线之外的选择
模型选型上,我的做法是先把单阶段检测器跑通基线,再根据缺陷尺寸分布决定要不要换更重的结构。第一次跑实验用的是当时比较成熟的YOLOv8m,输入尺寸640×640,训练了150个epoch。结果是mAP50约0.72,看起来不差,但仔细看类别明细,销钉缺失的AP只有0.21,鸟巢的AP 0.68,方差很大。这意味着大目标好检,小目标几乎没学出来。
我尝试过升分辨率重新训练。把输入尺寸从640提升到1280,销钉缺失的AP从0.21涨到0.43,涨了一倍多,但是训练显存和推理耗时也几乎涨了三倍。在边缘设备上完全不可行。后来采用了变通方案:检测阶段用640的尺寸跑全局粗筛,对疑似缺陷的局部区域再裁剪放大做二次精检。这个两级检测策略在后来的部署里证明是性价比最高的路径。
另外一个小细节:类别之间不平衡极其严重。锈蚀的样本量可能是销钉缺失的二十倍。我在训练时给每个类别加了基于类别频率的权重,让少样本类别在损失函数里被“放大”一些。同时针对性做采样,每次epoch里销钉缺失样本按比例多抽一遍。调完这两处,少样本类别的AP提升很明显。
3.2 数据增强真正有用的只有三招
数据增强我用过一长串:Mosaic、MixUp、HSV变换、随机翻转、马赛克裁剪、随机擦除。实际跑下来真正有效果的是三招。
第一招是把Mosaic做一些改造。原始Mosaic把四张图拼在一起,但对电力巡检图这种背景单一、目标小的场景,整图拼接容易把本来就很小的目标进一步缩小。我改成在拼接时对每一块做随机缩放和随机裁剪,保证每个子区域的目标尺寸不低于原图的2/3。这个改动让小目标增强不再起反作用。
第二招是CopyPaste。把标注出来的销钉、防震锤、鸟巢这类小目标从一张图“抠”下来,随机粘贴到另一张塔材图上。这招对小目标检测特别有效,等于在不增加采集量的情况下丰富了背景多样性。
第三招是随机擦除,也就是模拟遮挡。随机把矩形区域用灰色色块覆盖掉,强迫模型不要只依赖某一个局部特征来判断缺陷。鸟巢有时候被塔材挡住一半,擦除增强能模拟这种遮挡情况。
对比下来,大量测试后发现色彩抖动、高斯噪声这类增强对工业图像的收益不明显,甚至可以忽略。数据增强不是越花哨越好,真正决策点是“增强后的样本分布是否符合真实部署时的退化场景”。
3.3 训练监控不能只看总mAP,要拆开看每一类的PR曲线
训练过程中最容易犯的错误是只看总mAP的上升趋势。我吃过这个亏:总体mAP一直在涨,但漏检的全是小目标类。后来我固定了一套复盘流程,每次实验结束不仅看mAP和F1,还要拉出每个类别的PR曲线,重点观察召回率在什么置信度阈值下开始崩溃。对杆塔巡检来说,漏检的代价远高于误报,所以我更关注高召回率区间下的精确率表现。
置信度阈值这个超参数也被我调了很多轮。默认的0.25在很多开源任务里表现不错,但到了电力塔场景,各种疑似缺陷的噪声太多,0.25的阈值下全图能弹出上百个框。我最终把全局置信度阈值调到0.5,并针对个别类目做了单独阈值——鸟巢这类高价值缺陷用0.35,销钉缺失这种难例用0.3。这套“类别自适应阈值”的思路,比统一调参实用得多。
还有一个值得说的点是NMS的处理。塔头区域的缺陷框经常重叠严重,尤其是绝缘子串自爆和锈蚀同时出现时,两个类别在空间上高度重合,标准NMS会把其中一个框吞掉。我把NMS的IoU阈值从默认的0.45放宽到0.6,同时启用soft-NMS做降权而不是直接删除。效果是临近缺陷的召回率提了4个百分点,代价仅仅是推理时间多了十几毫秒。
4. 从测试集到无人机实飞:误报率是怎么压下来的
4.1 一个晴天上午的崩溃现场:继电器板误报成鸟巢
模型在测试集上F1到了0.83,我觉得差不多了,就兴冲冲上真机跑实飞。结果第一轮测试就把我按在地上摩擦。晴天上午,阳光斜照,绝缘子串旁边的继电器板在特定角度下形成了一个黑色的、带纹路的三角形区域,模型自信地把它标成了“鸟巢”,置信度0.78。整个测试飞了4基塔,误报列表里这种“阴影+结构板件”的情况占了四成。
这就是典型的模拟环境与真实环境之间的gap。测试集里确实有各种光照的图,但真正飞行时的塔型、塔材新旧程度、锈蚀痕迹、绑扎线、标识牌、反光条等大量“陌生”视觉元素,都会触发模型的好奇心。我必须接受一个现实:模型在训练集上的指标不能直接等价于部署效果,必须设计一整套后处理机制来兜底。
4.2 后处理三板斧:时序滤波、空间互斥和场景锚点
第一板斧是时序滤波。无人机对同一位置会拍摄多帧连续照片,单帧的误报如果只是偶然出现,那么在连续几帧里会表现得极不稳定。我实现了一个简单的帧间确认机制:同一个目标位置在至少2帧里都被检出且中心点位移不大,才进入告警候选。这个机制简单粗暴,却能一次性砍掉大量偶发误报。
第二板斧是空间互斥规则。有些位置天生不可能是某些缺陷,比如绝缘子串中间区域不可能出现“异物悬挂”,那是实心的陶瓷/玻璃结构。这类知识用规则的代价远低于让模型去从数据里悟。我在后处理里维护了一张“区域-类别互斥表”,把塔身分割成若干语义区域,检测框的类别如果和所在区域冲突,直接降置信度。
第三板斧是场景锚点。我把巡检航线固定化,每一基塔的拍摄位置和云台角度相对固定,这意味着画面里的铁塔结构是稳定的。利用这一点可以做背景差分——在几乎没有变化的两个巡检周期之间,把未变化区域的背景剥掉,只保留变化区域做检测。这样能把模型注意力集中到真正“新增”的目标上,类似防震锤移位这种本来就是“位置不对”的缺陷,也能用这个方法强化识别。
4.3 端侧推理优化:帧率、规格、算子三件套
部署目标我选的是某款边缘计算盒子,算力大概在几十TOPS级别。检测模型首先得从PyTorch导出成TensorRT引擎,这一步就把推理速度从300多毫秒压到90毫秒左右。接下来是输入尺寸的控制:整图推理用1280×1280,太慢了,落到640×640全局粗检,再由局部裁剪做二次精检。最终整图加二次精检的平均耗时控制在160毫秒以内。
还有几个算子级优化点。第一个是把检测头的输出直接在后处理里截断,提前丢掉低于阈值的框,避免把所有框都送去NMS。第二个是把NMS的代码从Python换成CUDA实现,小批量推理下也能省几十毫秒。第三个是开启半精度FP16推理,算力损失几乎可忽略,但显存占用减半。
这些优化做完,一轮完整的周边检查才是真正能在无人机平台上跑起来的方案。用我同事的话说,如果模型在实飞现场回传的画面里能把鸟巢从农田背景中抓出来,测试集再漂亮都不算数。
5. 数据集的持续迭代:这个坑位为什么永远填不满
5.1 一次飞行的新图回流,9周后为什么又漏检了
模型上线九周后,我收到一条漏检反馈:某基塔的鸟巢被模型漏了,而且置信度低于0.1。我拉出那张图对比训练集,发现了一个很扎心的事实——这基塔的塔材上长满了爬山虎,整片区域呈现出训练集里完全没有的绿色纹理特征,鸟巢藏在藤蔓和叶片之间,模型把它当成背景了。
这类问题在数据领域里叫“分布漂移”。电力杆塔巡检的视觉环境受季节变化影响太大:夏天有爬山虎、春天有筑巢高峰、冬天塔材表面有霜冻反光。训练集再大,也不可能覆盖所有自然变化,唯一可行的办法是建立数据回流闭环。
5.2 数据合入的纪律:重复清洗、类别重校验、回归测试
数据回流不是把新图直接塞进训练集那么简单。我踩过一个坑:把新采集的图合并进去后,模型在新一轮测试上反而变差了。查下来发现新图里有一批模糊的、过度曝光的图混进来了,它们作为训练样本迫使模型学到了“模糊=无缺陷”的错误关联。
从那之后我定了三条合入纪律。第一,所有回流图必须经过清晰度筛选,结构相似度指标低于阈值的直接弃掉。第二,新图标注完成不代表能用,必须随机抽20%做人工复核,复核通过率低于85%的整批打回。第三,每轮合并后跑一次回归测试,用之前积累的难例库加上固定验证集,保证新数据只增不退。
5.3 向“少样本”要效率:硬负样本挖掘与半自动标注
数据迭代里另一个重要手段是硬负样本挖掘。我定期从实飞数据里挑出那些被模型误报成缺陷的样本,单独标注成“负样本”类别,重新加入训练。这些难负样本逼着模型学习“这些不是缺陷”,误报率就是这么一轮一轮刷下来的。这个思路和学术里的难例挖掘一致,但在工业项目里,效果比加更多正样本还明显。
半自动标注则是另一条提效路径。模型稳定之后,我用当前版本模型对新增图跑一遍预测,生成伪标注,再让标注员只修改模型标错的地方。理想状况下,标注成本能降一半以上。但这里有个前提:只对模型高置信度输出的区域自动生成标签,低置信度的区域必须保留人工重判,否则会把模型的错误当成正确答案循环学进去,形成自我强化偏差。
最后说一句关于“第10567期”这个编号。它本质上是数据集和模型持续迭代到当前版本的标记。真实做项目时,我见过太多团队把“数据集做完”当终点,然后模型部署完就撒手不管了。但电塔缺陷监测这个场景,环境和缺陷形态始终在变,数据工程永远没有真正“完成”的那一天。把回流、复标、回归测试当作例行动作去做,模型才会越用越顺手。这也是我觉得这套方法最值得分享的地方。