ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

无人机风机叶片缺陷检测:YOLOv8与DeepSeek诊断落地实践

无人机风机叶片缺陷检测:YOLOv8与DeepSeek诊断落地实践 无人机飞一圈风机叶片上的裂纹、砂眼、蒙皮脱落在高清镜头下看得清清楚楚——但现场运维人员要的不只是一张照片而是一句能落地的判断这个缺陷严不严重要不要安排人上塔处理该补胶还是该换片。过去两年我一直在做无人机风机巡检的视觉系统最早只跑了一个YOLOv8目标检测后来把DeepSeek接进去做诊断分析整套系统才算真正能交付给风电场的运维团队。今天把这条链路拆开讲一遍从数据采集、标注、模型改进到DeepSeek API接入、边缘端部署再到现场踩过的各种坑。无论你是刚入门深度学习目标检测还是已经在做无人机巡检项目希望这篇能帮你少走点弯路。1. 风机表面缺陷检测为什么不能只靠一个目标检测模型1.1 传统人工巡检的痛点决定了必须上无人机视觉风机叶片是高空旋转部件常年暴露在风沙、盐雾、雷击和温差环境下表面会出现前缘腐蚀、裂纹、砂眼、蒙皮鼓包、雷击烧蚀等缺陷。过去主要靠人工吊篮或者蜘蛛人攀爬检查一个机位少说要半天而且人在高空能看到的范围和精度都有限记录全靠拍照和手写回来还要人工整理缺陷台账。无人机巡检把这步变成自动化的“数据采集AI识别”。飞手按航线绕塔身和叶片飞一圈用高倍变焦镜头拍下叶片正反面AI模型把疑似缺陷的位置框出来。但这里有个很现实的问题框出来之后运维人员并不知道这个缺陷到底要不要修什么时候修。一个几毫米的微小裂纹和一个已经贯穿的裂口在检测框里可能看起来差不多需要的处置方式却完全不同。1.2 检测与诊断两段式的整体架构所以我的方案是“检测诊断”两段式第一段用改进的YOLOv8做目标检测输出缺陷框的类别、位置、置信度第二段把检测结果以结构化JSON喂给DeepSeek大模型让模型结合缺陷类型、尺寸、位置、叶片编号和历史运维知识自动生成缺陷诊断报告、严重性分级和维修建议。这套架构的核心思路是把“看见问题”和“理解问题”分开。目标检测模型擅长在图像中找到异常区域但它不理解“雷击损伤后期会导致叶片失速”“前缘腐蚀在翼展方向超阈值就需要灌缝修复”这类领域知识。大模型擅长推理和生成文本但直接拿原始图像让大模型识别小尺寸缺陷既费钱又容易漏检。两段式的好处是各司其职推理成本也低得多。2. 改进YOLOv8数据、网络结构与训练调优2.1 数据采集与标注LabelMe标注和数据集清洗做检测模型第一头疼的就是数据。风机缺陷数据集不像COCO那样在网上随便下载很多风电场的缺陷照片是涉密生产数据你拿到的往往只是几十张现场照片加一堆维修记录。我最初拿到的原始数据只有426张有效图片其中包含裂纹的有200多张砂眼和雷击损伤各不到150张还有一批没有缺陷的负样本。标注工具我用的是LabelMe因为它可以在浏览器里用支持多人协作导出的JSON格式也好处理。这里有个关键选择缺陷是框还是多边形。小裂纹和砂眼用矩形框标注就够了但叶片轮廓、前缘腐蚀这类区域用多边形标注更准确。我的建议是如果后续计划升级做实例分割就统一用多边形标注一次性把掩码数据也攒下来如果只做检测矩形框更快一个熟练工一天能标300到400个实例。标注完成后不能直接丢给训练脚本必须先做清洗和统计。我用一个Python脚本遍历所有JSON输出每张图的标注数量、框面积占比、类别分布然后把明显的错误标注揪出来比如把叶片上的污渍标成裂纹把塔筒阴影标成缺陷这种情况在多人标注时经常出现。数据清洗比调模型参数重要得多我不止一次因为脏数据把模型的mAP拉低了3到5个点。数据增强方面除了Ultralytics YOLO自带的Mosaic、RandomAffine我额外加了两种针对性增强。一种是模糊增强模拟无人机运动导致的图像模糊把高斯模糊核大小设为3到7像素随机。另一种是低对比度增强模拟阴天、逆光和远距离拍摄的条件。这两种增强对我的场景帮助很大因为现场照片和训练照片的成像质量差距往往比不同缺陷之间的特征差距还要大。2.2 网络结构改进注意力模块和小目标检测头我在标准YOLOv8s基础上做了三处改进这也是“改进YOLOv8”的核心内容。第一在Backbone的C2f模块后面插入坐标注意力模块。风机叶片细长缺陷往往出现在狭长形状的区域内坐标注意力能把水平方向和垂直方向的位置信息编码进注意力权重比单纯的SE注意力更适合我这个长条目标场景。实际测试下来插入两层坐标注意力后mAP50-95大约提升了1.8个点推理速度只慢了不到9%。第二增加一个P2检测头专门处理小目标。缺陷框普遍小于32×32像素标准YOLOv8的最小检测头基于P3特征图8倍下采样对细小裂纹容易漏检。增加P2头意味着模型要在4倍下采样的特征图上做检测计算量上去了但小目标的召回率提升非常明显。我对比过加了P2头之后裂纹的召回率从0.74提高到0.85代价是训练和推理时间都增加了20%左右但叶片巡检任务对实时性要求没那么极端这个代价完全能接受。第三损失函数从CIoU换成SIoU。标准YOLOv8默认的CIoU收敛已经很稳但对旋转框不友好。叶片表面缺陷虽然是水平矩形框但很多裂纹是有角度的SIoU在计算损失时考虑了预测框与真实框的方向差异收敛更快最终mAP也略高。这里要提醒一句不是所有改进都是正向的。我试过在Neck里加BiFPN结构结果mAP没提升训练时间翻了快一倍果断放弃。模型结构的选择永远是精度、速度、复杂度的平衡不要为了改进而改进。2.3 训练环境Ubuntu 20.04 CPU能跑GTX 1660 Ti也能练训练环境这块我见过很多新手卡在环境搭建上。照我的经验最省事的方式是Ubuntu 20.04上直接用Ultralytics官方镜像或pip安装ultralytics包Python版本3.9到3.11都可以。如果你只有CPU也能跑通但速度会让人怀疑人生CPU上用640×640输入跑一遍验证集几百张图可能要跑一个多小时。所以纯CPU环境只适合做代码连通性测试不适合真正训练。我实际训练用的是GTX 1660 Ti6GB显存比上不足比下有余。这套卡跑YOLOv8s输入分辨率设成960×960batch size只能开到6到8混合精度训练开着显存勉强够用。如果你的卡显存只有4GB那就把输入分辨率降到640或者直接用YOLOv8n。别逞强显存溢出一次就要重跑浪费的时间比什么都贵。训练命令很简单但有几个参数值得注意yolo train datawind_turbine.yaml modelyolov8s.pt epochs150 imgsz960 batch8 ampTrue device0 patience30 seed42patience参数是早停我设30个epoch如果连续30轮验证集指标不涨就自动停防止过拟合。amp混合精度一定要开显存省一半训练速度快30%以上。我试过不开AMP同样的epoch数量loss曲线一直抖得厉害后来发现不开AMP在小显存卡上反而更容易梯度爆炸。2.4 训练过程的损失曲线和过拟合排查训练完第一件事是看runs/detect/val/box_loss.png和cls_loss.png。损失曲线持续下降最后平稳就是正常如果验证集损失下降到一定程度开始反弹那就是过拟合。这时候优先增加数据增强而不是加正则化因为风机缺陷样本本来就少你更需要泛化而不是让模型更强地记忆。第二件事是跑验证集并打印每类的PR曲线重点看类别之间的mAP差距。我最初训练的模型砂眼mAP 0.91裂纹只有0.76差距太大原因是裂纹样本里粗细差异太大细裂纹经常只有2到3像素宽。后来我把细裂纹样本单独挑出来做了两次过采样又额外标注了120张细裂纹图像效果立刻好起来。类别不平衡的问题在缺陷检测里比通用目标检测更严重。我的办法是设置cls_pw为类别权重的平方根让模型给少数类别更高的分类损失权重。但别加太猛权重超过2就会导致多数类别的误检增多。3. DeepSeek接入从检测框到诊断报告3.1 DeepSeek API调用方式和模型选择检测模型输出的是坐标和类别要变成运维人员能看懂的报告需要DeepSeek这类大模型来补全“为什么严重”和“怎么处理”。目前DeepSeek的API兼容OpenAI接口格式我用Python的openai库直接调用只是把base_url换掉非常省事。from openai import OpenAI client OpenAI( api_keysk-your-key, base_urlhttps://api.deepseek.com ) resp client.chat.completions.create( modeldeepseek-chat, max_tokens2000, temperature0.3, messages[ {role: system, content: 你是风机运维诊断专家根据缺陷检测结果输出诊断报告。}, {role: user, content: diagnostic_prompt_text} ] ) print(resp.choices[0].message.content)模型我用的是deepseek-chat不是deepseek-reasoner。后者是推理增强模型会先输出长思维链再给结论适合复杂诊断但响应时间慢费用也偏高。我的场景里缺陷诊断规则相对固定用普通chat模型加结构化prompt就够。如果遇到那种需要权衡“是否立即停机检修”的紧急缺陷再手动切到reasoner模式也不迟。3.2 Prompt设计给大模型喂什么样的上下文这是整个DeepSeek集成里最值得打磨的地方。我踩过的坑是一开始直接喂“风机叶片有裂纹请分析”模型回答全是套话毫无参考价值。后来我改成了高度结构化的JSON上下文效果立刻不一样。实际诊断时我先在Python端把检测结果聚合只保留置信度大于0.35的检测框并过滤掉明显重叠的框用NMS阈值0.5生成如下格式{ turbine_id: WT-07, blade_id: BL-A2, surface: 吸力面, detections: [ {type: 前缘腐蚀, bbox: [1245, 320, 1328, 355], confidence: 0.86, area_ratio: 0.012, region: 叶片前缘中段}, {type: 雷击烧蚀, bbox: [2234, 876, 2250, 893], confidence: 0.92, area_ratio: 0.001, region: 叶尖附近} ], wind_condition: 6级阵风, last_maintenance: 2025-03-01 }然后我把这段JSON拼进prompt让模型输出一个固定模板的诊断报告。我要求模型必须包含四个部分缺陷现象描述、严重性等级低/中/高/紧急、建议维修窗口、具体处置方式。并且明确告诉模型“如果信息不足必须标注‘无法判断’不要臆测”。为什么要这么严格因为在现场模型输出是要进入工单系统的如果格式乱下游系统没法解析自动生成的维修任务就会出错。让大模型“自由发挥”的代价比想象的更大。3.3 生成报告与维修建议的落地闭环诊断报告生成后我让系统自动写入两个地方一个是数据库的检测记录表另一个是生成Word巡检报告文档。这里有个细节大模型偶尔会把叶片编号编造出来比如我传的是“BL-A2”它可能回“BL-2A”。这个不是模型不聪明而是文本生成过程本身就可能出错。所以我在系统里做了二次校验把报告中的叶片编号、日期、缺陷坐标都回跟原始JSON比对一遍不一致就把该字段留空并打回重生成不允许直接下发。维修建议的规则我总结出来最好用的prompt写法不是问“怎么修”而是给几个固定选项让模型选。比如“对于前缘腐蚀可选方案为A. 打磨补胶修复 B. 注入树脂修复 C. 更换叶片”模型根据缺陷面积和位置限选一项并给出理由。这样既发挥了模型的推理能力又不至于生成出工段上根本做不了的方案。4. 无人机巡检与模型部署从实验室到风机现场4.1 巡检航线和图像采集的质量要求模型训练得再好无人机拍回来的图不合格一切白搭。风机巡检的航线规划核心是“离得够近、拍得够全”。我用的多旋翼无人机带RTK定位设置好塔基坐标和塔高规划环绕航线先在塔身外绕一圈再飞到轮毂中心高度对每个叶片逐一从叶根到叶尖拍两遍正面一遍、背面一遍。拍摄高度通常控制在30到50米镜头用30倍光学变焦确保叶片宽度在画面里占1/3以上。这种情况下单个缺陷像素尺寸能到50到150像素检测模型很轻松如果为了省时间飞太高叶片宽度只占画面五分之一缺陷尺寸跌到20像素以下再强的模型也容易漏。航线规划还要考虑太阳角度。顺光拍摄叶片表面细节最清晰逆光时叶片边缘会出现强烈反光人眼都看不清模型更不行。我在航线里固定了“顺光航点优先”并且要求云台稳定减少运动模糊。做了这些之后模型的漏检率直接降了一半因为输入质量上来了。4.2 模型轻量化与RK3588边缘端部署无人机不能背着几十公斤的GPU服务器飞边缘端才是落地赛道。我测试了两条路线一条是NVIDIA Jetson Orin系列部署简单用TensorRT加速另一条是瑞芯微RK3588功耗低、成本低国内供应链稳定很多行业无人机吊舱里都有类似SoC。RK3588部署YOLOv8的流程是先把PyTorch模型导出为ONNX再用瑞芯微的rknn-toolkit2转换成RKNN格式最后做int8量化。这里有个容易踩的坑就是torch.onnx.export时要把opset设为12并且输入固定为batch_size1否则后面转RKNN会报一堆兼容性错误。模型量化后精度掉多少是大家最关心的。我实测YOLOv8s在RK3588的NPU上fp16推理大约每帧55msint8量化后大约38ms精度mAP50从0.92掉到0.87损失还在可接受范围。但缺陷检测场景对极端小目标敏感int8量化可能把某些灰度接近的裂纹细节吞掉所以我最后选择fp16模型在生产环境跑int8只用来做快速预览。4.3 端云协同边缘段跑检测云上跑诊断最终交付的架构是端云协同。无人机或地面站的边缘设备实时跑YOLOv8把所有检测框结果打包上传云端服务器跑DeepSeek诊断并结合历史数据进行综合判断。为什么不让边缘端直接跑大模型很简单纯推理侧部署大模型到RK3588会遇到资源和成本的双重瓶颈而且诊断业务并不需要实时边端先把“缺陷在哪里”算出来云端再回答“这个问题怎么办”任务自然分工。端云协同还要考虑通信链路。海上风电场和山区风电场的网络环境都不好我加了一个离线缓存机制边缘端检测结果先写本地SQLite网络恢复后再批量同步避免巡检中途断网导致数据丢失。很多项目死就死在“闪断一下整趟巡检白飞”这种问题上。5. 落地过程中的常见问题与排查记录5.1 误检和漏检数据迭代不能停最常见的问题是蓝天被识别成“裂纹”塔筒阴影被识别成“砂眼”。在实验室测mAP看不出来一到现场背景环境一变模型立刻露馅。我的诊断思路是把误检的图按类别聚类找出模型的“学习误区”。如果大量误检是天空背景说明模型学的是纹理对比边缘而不是缺陷本身。解决方法还是靠数据迭代。我把现场误检图每两周回收一次人工确认后加入训练集模型就越训越稳。另外我在训练时混入了20%的纯背景负样本让模型明白“没有缺陷时只能输出置信度0.2以下的框”这个操作非常有效。5.2 无人机图像模糊、反光、雾化的补救高倍变焦拍摄对震动极其敏感就算开了防抖远距离拍高速旋转叶片偶尔还是有糊的图。我的三条补救措施第一拍摄时开启连拍模式同一位置拍3到5帧检测服务选清晰度最高的那帧处理第二在训练数据里加入运动模糊增强模型会自带抗模糊能力第三检测服务增加一个“清晰度评分”前置模块用拉普拉斯方差判断图片是否过糊低于阈值就自动触发重飞不让垃圾图进入模型。5.3 DeepSeek API的限流、超时与成本接DeepSeek API之后我最头疼的是调用超时和限流。巡检一次有几百个检测框如果一张图一次调用高峰期很容易打满限额。我的优化是“检测结果聚合后按叶片聚合”一个叶片只调用一次大模型显著降低调用次数和成本。代码里必须加超时和重试机制。我的做法是用tenacity库设置3次重试每次的指数退避基数为1.5秒超过5秒直接跳过该叶片并标记待人工复核。这样不会因为一个接口抖动卡住整条流水线。另外max_tokens设2000足够设太大不仅有浪费还可能接近模型的单次上下文上限。5.4 长尾缺陷和未知缺陷的兜底策略风机缺陷种类远比训练集里那四类多一定会有模型没见过的形态。我在系统里加了一道兜底逻辑所有置信度在0.2到0.35之间的检测框不直接丢弃而是进“待确认池”由人工远程看一眼每周统一纠偏一轮。这个半自动方式看着“土”但确实是把漏检率压住最有效的办法。如果你想把“识别未知缺陷”的能力也做成自动化的下一步可以引入视觉多模态模型把缺陷框裁剪图直接发给DeepSeek的视觉模型做开放集合识别。我目前只在特定客户项目上做了实验成本和性能还在磨合但方向是对的。最后补一句个人心得这类系统能真正跑起来不在于把YOLOv8的mAP刷高几个点也不在于DeepSeek prompt写得多花哨而在于整条链路——数据标注规范、现场图像质量、接口异常兜底、报告格式校验——每一环都稳得住。把一次真实巡检的数据完整跑通比在训练集上刷多项榜单更有价值。毕竟风机在现场运行等不起你又一次“离线调试”。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进