风力涡轮机叶片缺陷实例分割数据集:从像素级标注到产线落地全解析
发布时间:2026/10/2 14:50:37来源:尧图网络
简介本资源为风力涡轮机叶片缺陷实例分割数据集面向能源行业运维工程师、计算机视觉算法开发者及可再生能源检测方向的研究人员用于构建叶片缺陷自动识别与定位模型支撑预防性维护与故障预警。数据集共1162张图像按训练集1017张、验证集97张、测试集48张划分覆盖裂纹、侵蚀、正常、机械损伤、油漆脱落、划痕六类状态采用YOLO多边形点坐标标注可直接适配YOLOv8等主流框架的实例分割任务。压缩包共2000个文件以1162个txt标注文件、836个jpg图像为主另含1个yaml配置文件与1份docx说明文档整体约37.56MB目录结构清晰便于快速接入训练流程。目前已有428人学习下载。数据源自真实风力涡轮机叶片巡检场景多类别缺陷覆盖与高精度边界标注可提升模型在工业运维中的泛化能力适合用于算法验证、技能培训与学术研究。1. 风力涡轮机叶片缺陷实例分割数据集从像素级标注到产线落地的第一手拆解如果你正在做风电巡检方向的视觉项目大概率绕不开一个尴尬目标检测框只能告诉你“这里有缺陷”但运维方真正想知道的是“裂纹有多长、砂眼占多大面积、腐蚀区域边界在哪”。这就是实例分割要解决的问题。我手里这份风力涡轮机叶片缺陷实例分割数据集核心价值就在于它提供的是像素级 mask 标注而不是简单的矩形框。它适合三类人一是做工业缺陷检测的算法工程师想验证 Mask R-CNN、YOLOv8-seg 这类实例分割模型在真实工业场景的表现二是风电运维方向的研究生需要一份带行业属性的数据集写论文或做毕设三是想从目标检测进阶到实例分割的开发者拿它练手比用 COCO 更贴近实际业务。数据集覆盖的缺陷类型通常包括裂纹、砂眼、剥落、腐蚀等叶片常见损伤标注格式以多边形点集为主可直接转 COCO 或 YOLO 分割格式。下面我从数据组织、格式转换、训练配置到踩坑排查把这份资源完整拆一遍。2. 数据集结构与标注格式先搞清楚你拿到的是什么2.1 目录组织与文件构成拿到压缩包解压后常见的目录结构是这样的不同版本可能略有差异但逻辑一致wind_turbine_blade_defect/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── annotations/ │ ├── instances_train.json │ ├── instances_val.json │ └── instances_test.json └── README.mdimages 下按 train/val/test 划分每张图对应一个 JSON 标注文件。annotations 里的 JSON 遵循 COCO 格式包含 images、annotations、categories 三个顶层字段。categories 里定义了缺陷类别比如 crack、pitting、spalling、corrosion 等。annotations 里每条记录包含 image_id、category_id、segmentation多边形点集、area、bbox、iscrowd。segmentation 是实例分割的核心它是一个列表的列表每个子列表是一串 [x1, y1, x2, y2, ...] 的坐标点首尾自动闭合。这里有个容易忽略的点COCO 的 segmentation 多边形点集必须是浮点数且点数至少为 3 个才能构成有效区域。如果标注时只点了两个点这条标注在训练时会被跳过或报错。我一般会先跑一遍完整性检查确认每条 segmentation 的点数和面积都合法。2.2 标注格式转换COCO 转 YOLO 分割格式YOLOv8-seg 和 YOLO11-seg 用的是归一化后的多边形坐标每行格式为class_id x1 y1 x2 y2 ... xn yn坐标值在 0 到 1 之间。转换脚本如下import json import os from pathlib import Path def coco_to_yolo_seg(coco_json, output_dir, img_width, img_height): 将 COCO 实例分割标注转为 YOLO 分割格式 coco_json: COCO 格式 JSON 路径 output_dir: 输出 txt 目录 img_width/img_height: 图像尺寸需与标注时一致 with open(coco_json, r, encodingutf-8) as f: data json.load(f) # 建立 image_id 到文件名的映射 img_id_to_name {img[id]: img[file_name] for img in data[images]} # 建立 category_id 到连续索引的映射YOLO 要求从 0 开始 cat_id_to_idx {cat[id]: idx for idx, cat in enumerate(data[categories])} os.makedirs(output_dir, exist_okTrue) for ann in data[annotations]: img_id ann[image_id] img_name img_id_to_name[img_id] txt_name Path(img_name).stem .txt txt_path os.path.join(output_dir, txt_name) cat_idx cat_id_to_idx[ann[category_id]] seg ann[segmentation] # segmentation 可能是列表的列表取第一个多边形 if isinstance(seg, list) and len(seg) 0: polygon seg[0] else: continue # 归一化坐标 normalized [] for i in range(0, len(polygon), 2): x polygon[i] / img_width y polygon[i 1] / img_height # 裁剪到 [0, 1] 防止越界 x max(0.0, min(1.0, x)) y max(0.0, min(1.0, y)) normalized.extend([x, y]) line f{cat_idx} .join(f{v:.6f} for v in normalized) \n with open(txt_path, a, encodingutf-8) as f: f.write(line) print(f转换完成输出目录{output_dir}) # 调用示例 coco_to_yolo_seg( coco_jsonannotations/instances_train.json, output_dirlabels/train, img_width1920, img_height1080 )逻辑说明脚本先读取 COCO JSON建立 image_id 到文件名的映射和 category_id 到连续索引的映射。然后遍历每条 annotation提取 segmentation 的第一个多边形将绝对坐标除以图像宽高做归一化最后按 YOLO 格式写入 txt。参数方面img_width 和 img_height 必须与标注时的图像尺寸一致否则归一化坐标会偏移。如果图像尺寸不统一需要先读取每张图的实际尺寸再转换。常见做法是用 PIL 或 OpenCV 批量读取图像尺寸存成字典后再传入。注意YOLO 分割格式要求每个多边形至少 3 个点且坐标值在 0 到 1 之间。如果原始标注中有自相交多边形训练时可能报错建议先用 shapely 做一次有效性校验。3. 训练配置与参数调优从 Mask R-CNN 到 YOLOv8-seg3.1 模型选型两阶段还是单阶段实例分割模型主要分两派两阶段的 Mask R-CNN 和单阶段的 YOLOv8-seg / YOLO11-seg。选哪个取决于你的部署场景和精度要求。对比维度Mask R-CNNYOLOv8-seg推理速度较慢通常 5-15 FPS较快可达 30-60 FPS小目标分割精度较高中等需调参训练显存需求高建议 12GB中等8GB 可跑部署复杂度较高依赖 Detectron2低Ultralytics 一行命令适合场景离线质检、精度优先边缘部署、实时巡检如果做风电叶片巡检的无人机端侧部署YOLOv8-seg 更合适如果做离线高精度缺陷分析Mask R-CNN 配合 Detectron2 更稳。我一般会先用 YOLOv8-seg 快速跑一版 baseline看 mAP50-95 和 mask mAP 是否满足要求再决定要不要上两阶段模型。3.2 YOLOv8-seg 训练配置与参数说明用 Ultralytics 训练 YOLOv8-seg 的配置文件如下# wind_blade_seg.yaml path: ./wind_turbine_blade_defect train: images/train val: images/val test: images/test names: 0: crack 1: pitting 2: spalling 3: corrosion训练命令yolo segment train \ datawind_blade_seg.yaml \ modelyolov8s-seg.pt \ epochs150 \ imgsz1024 \ batch8 \ lr00.01 \ lrf0.01 \ patience30 \ augmentTrue \ mosaic1.0 \ copy_paste0.3 \ device0 \ projectruns/segment \ namewind_blade_v1参数说明imgsz1024 是因为叶片缺陷通常占比较小分辨率太低会丢失细节batch8 在 8GB 显存下比较稳显存够可以加到 16lr00.01 是初始学习率lrf0.01 是最终学习率因子配合余弦退火patience30 表示 30 轮无提升就早停mosaic1.0 开启马赛克增强copy_paste0.3 开启复制粘贴增强这两个对分割任务提升明显。如果显存不够优先降 batch 而不是降 imgsz因为分辨率对分割精度影响更大。训练过程中重点看三个指标mask mAP50、mask mAP50-95、以及每类的 mask precision 和 recall。如果某一类 recall 特别低通常是该类样本太少需要做类别平衡或针对性增强。3.3 数据增强策略针对工业缺陷的调整工业缺陷检测和自然图像检测有个关键区别缺陷的形态、纹理、背景相对固定过度增强反而会引入噪声。我一般会这样配mosaic1.0保留但注意如果缺陷区域很小mosaic 后可能被裁掉可以配合 close_mosaic10 在最后 10 轮关闭copy_paste0.3对分割任务很有效能把缺陷实例复制到其他图上增加样本多样性degrees10小幅旋转模拟无人机不同角度拍摄translate0.1小幅平移scale0.5缩放范围叶片缺陷尺度变化大这个可以保留fliplr0.5水平翻转叶片左右对称翻转合理flipud0.0垂直翻转要谨慎叶片上下纹理不对称翻转可能引入不合理样本如果训练后发现模型在验证集上 mask 边界不够精细可以把 imgsz 提到 1280同时把 batch 降到 4用梯度累积模拟大 batch。4. 避坑与排查标注、训练、评估中的五个血泪教训4.1 现象训练 loss 正常下降但 mask mAP 始终为 0原因COCO 转 YOLO 时 category_id 映射错误或者 segmentation 点数为奇数导致解析失败。YOLO 要求每行坐标点成对出现如果原始多边形点数为奇数最后一个点会被丢弃导致多边形无效。解决转换后随机抽查几个 txt 文件确认每行的坐标数量是偶数且 class_id 在 names 范围内。可以用脚本统计每个 txt 的坐标点数和类别分布。4.2 现象验证集 mask 可视化时边界明显偏移原因转换时用的 img_width 和 img_height 与实际图像尺寸不一致。常见于数据集里混入了不同分辨率的图像但转换脚本只用了固定尺寸。解决遍历 images 目录用 PIL 读取每张图的实际尺寸建立 filename 到 (width, height) 的映射转换时按图查表。如果图像尺寸差异大建议先统一 resize 到固定尺寸再标注或者训练时用 letterbox 保持比例。4.3 现象某些类别 mask mAP 很高某些类别几乎为 0原因类别样本极度不平衡。叶片裂纹可能几百个实例而剥落只有十几个。YOLO 默认的损失函数对少数类不够友好。解决一是对少数类做过采样在 dataset 里重复出现二是用 copy_paste 增强少数类三是调整损失权重YOLOv8-seg 支持通过 cls 和 box 参数调权重但分割 mask 的权重调整空间有限更推荐前两种。4.4 现象训练到后期 mask loss 震荡不收敛原因学习率太大或 batch 太小导致梯度噪声大。分割任务对学习率比检测更敏感。解决把 lr0 降到 0.005 或 0.001同时把 warmup_epochs 加到 5。如果 batch 小于 8建议开 accumulate 做梯度累积比如 batch4, accumulate2 等效 batch8。4.5 现象推理时 mask 边缘锯齿严重原因YOLOv8-seg 输出的 mask 是原型 mask 与系数矩阵相乘后上采样得到的分辨率有限。如果 imgsz 设置太小边缘自然粗糙。解决推理时把 imgsz 提到 1280 或 1536同时用 retina_masksTrue 让 mask 在原图分辨率上生成。如果还不行可以对 mask 做一次形态学闭运算或高斯模糊后处理但会轻微改变面积需权衡。5. 进阶技巧用 mask 面积做缺陷分级与产线判定训练出模型只是第一步真正落地到风电运维需要把 mask 转成可量化的运维指标。我常用的做法是对每张图的每个缺陷实例计算 mask 面积占叶片区域的比例再结合缺陷类型做分级。import cv2 import numpy as np from ultralytics import YOLO model YOLO(runs/segment/wind_blade_v1/weights/best.pt) results model.predict(test_image.jpg, imgsz1280, retina_masksTrue, conf0.25) # 缺陷分级阈值面积占比 SEVERITY_THRESHOLDS { crack: [0.001, 0.005, 0.02], # 轻微、中等、严重 corrosion: [0.002, 0.01, 0.05], pitting: [0.0005, 0.003, 0.01], spalling: [0.001, 0.008, 0.03] } for r in results: if r.masks is None: continue masks r.masks.data.cpu().numpy() # shape: (n, h, w) classes r.boxes.cls.cpu().numpy().astype(int) img_area r.orig_shape[0] * r.orig_shape[1] for mask, cls_id in zip(masks, classes): cls_name model.names[cls_id] mask_area mask.sum() ratio mask_area / img_area thresholds SEVERITY_THRESHOLDS.get(cls_name, [0.001, 0.005, 0.02]) if ratio thresholds[0]: level 轻微 elif ratio thresholds[1]: level 中等 elif ratio thresholds[2]: level 严重 else: level 危急 print(f缺陷类型{cls_name}面积占比{ratio:.4f}等级{level})逻辑说明先加载训练好的模型用 retina_masksTrue 获取原图分辨率的 mask。然后遍历每个检测到的实例计算 mask 像素面积占整图面积的比例再根据预设阈值分级。阈值需要根据实际业务调整比如裂纹超过 2% 面积就算危急必须停机检修。参数方面conf0.25 是置信度阈值漏检多就降到 0.15误检多就提到 0.4。retina_masksTrue 会稍微增加推理时间但对面积计算精度提升明显。验证方法拿一批人工标注过的测试图把模型输出的分级结果和人工判定做混淆矩阵看各级别的召回率和误报率。如果“危急”级别的召回率低于 95%说明阈值偏松或模型漏检需要针对性优化。从那以后我每次拿到新的工业缺陷数据集都会先跑一遍标注完整性检查再转格式再小规模过拟合测试最后才开完整训练。这套流程帮我省了至少三次通宵排查的功夫。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网