news 2026/10/10 20:38:47

风机叶片缺陷检测数据集:18912张图与YOLO/COCO/VOC格式实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
风机叶片缺陷检测数据集:18912张图与YOLO/COCO/VOC格式实战

简介:本资源为风力涡轮机缺陷检测数据集,面向从事新能源设备智能运维、工业视觉检测的算法工程师与高校研究者,可用于训练和评估风机叶片、塔筒等关键部件的缺陷识别模型。数据集包含18912张图片,支持YOLO、PASCAL VOC XML与COCO JSON三种主流标注格式,便于直接接入目标检测框架开展实验。压缩包整体约584.4MB,图片与标注文件按类别组织,配套标注说明可参考作者提供的在线页面,方便快速核对与转换格式。已有354人学习下载,适合需要真实工业场景数据验证模型泛化能力的中高级开发者。借助该数据集,读者可完成从数据加载、格式转换到模型训练与精度评估的完整流程,并对照91.4%的准确识别率基线,分析不同检测算法在风机缺陷任务上的表现差异,为后续优化提供可靠参照。

1. 风机叶片巡检的“数据荒”,这份 18912 张的缺陷数据集能补上多少

做过风电巡检的都知道,叶片表面的裂纹、砂眼、雷击损伤这些缺陷,靠人眼加望远镜一天看不了几台,而且漏检率全凭老师傅心情。真正想把无人机航拍图丢给模型自动框缺陷,第一步就卡在数据上——网上开源的风机缺陷集要么几百张,要么只给分类标签不给框,训出来的模型换个风场就翻车。这份风力涡轮机缺陷检测数据集给到 18912 张图,标注覆盖 YOLO、PASCAL VOC XML、COCO JSON 三种格式,官方口径 91.4% 准确识别率。它解决的不是“有没有数据”的问题,而是“能不能直接进训练管线、不用自己从 LabelImg 开始点”的问题。适合两类人:一是做新能源巡检算法、想快速搭 baseline 的工程师;二是拿它当课程设计或毕设、需要现成 COCO JSON 跑通检测流程的学生。下面按“数据长什么样 → 怎么转成训练格式 → 怎么训 → 坑在哪”拆一遍。

2. 拆开数据包:三种标注格式到底怎么选、怎么读

2.1 先看清目录结构和标注分布

拿到一个检测数据集,别急着写 DataLoader,先花十分钟把目录摸清楚。这类风机缺陷集常见组织方式是images/放原图、annotations/放三种格式的标注文件,或者按train/val/test分好再各自带标注。18912 张图的量级,如果全是高清航拍图,解压后大概在 3~6 GB 之间,具体看分辨率。我一般先跑一段统计脚本,确认类别数和每类框数量,避免训到一半发现某个缺陷类只有几十个框。

import json from collections import Counter # 读 COCO JSON,统计类别分布和图片数 with open("annotations/instances.json", "r", encoding="utf-8") as f: coco = json.load(f) print("图片总数:", len(coco["images"])) print("标注框总数:", len(coco["annotations"])) # 类别 id 到名字的映射 cat_map = {c["id"]: c["name"] for c in coco["categories"]} print("类别列表:", cat_map) # 每个类别的框数量 counter = Counter(cat_map[a["category_id"]] for a in coco["annotations"]) for name, cnt in counter.most_common(): print(f"{name}: {cnt} 个框")

这段脚本干的事很直接:coco["images"]是图片清单,coco["annotations"]是每个框的记录,category_id对应categories里的类别。跑完你会得到一张类别分布表。如果发现某类框数低于 200,训练时就要考虑过采样或者类别加权,否则模型会直接把这个类忽略掉。参数上唯一要注意的是编码,COCO JSON 里如果有中文类别名,encoding="utf-8"不能省,不然 Windows 下直接报 UnicodeDecodeError。

2.2 三种格式的取舍:YOLO 快、VOC 稳、COCO 全

数据集同时给 YOLO、PASCAL VOC XML、COCO JSON,不是让你三选一随便用,而是对应不同训练框架。YOLO 格式是每张图一个.txt,每行class_id x_center y_center width height,坐标全部归一化到 0~1,Ultralytics 系的 YOLOv5/v8/v11 直接吃。VOC XML 是每张图一个 XML,框坐标是绝对像素值,适合老一点的 TensorFlow Object Detection API 或者 PaddleDetection。COCO JSON 是单个大文件,包含 images、annotations、categories 三个主键,MMDetection、Detectron2、YOLO 的新版都能读。

格式文件组织坐标类型典型框架转换成本
YOLO txt每图一个 txt归一化 cxcywhUltralytics YOLO最低,直接训
VOC XML每图一个 xml绝对像素 xyxyTF OD API、Paddle中,需转 COCO 或 YOLO
COCO JSON单文件绝对像素 xywhMMDetection、Detectron2低,配置 dataset 即可

选型逻辑很简单:如果你只是想快速验证“这个数据能不能训出东西”,用 YOLO 格式跑 YOLOv8n,半小时出结果。如果你要做多模型对比、发论文,用 COCO JSON 配 MMDetection,因为它的评估指标 mAP 计算最标准。VOC XML 更多是兼容老管线,新项目我一般直接跳过它,除非你手上的代码只认 XML。

提示:三种格式的类别 id 映射不一定一致。YOLO 的 class_id 从 0 开始,COCO 的 category_id 可能从 1 开始甚至跳号。混用之前先对齐,否则框会全错位。

2.3 用 COCO JSON 反查图片和标注是否对得上

数据集最怕的是图片和标注不同步——有图没框、有框没图。COCO JSON 的好处是可以一次性校验。下面这段脚本检查每张图是否有对应标注,以及每个标注的 image_id 是否真实存在。

import json with open("annotations/instances.json", "r", encoding="utf-8") as f: coco = json.load(f) img_ids = {img["id"] for img in coco["images"]} ann_img_ids = {a["image_id"] for a in coco["annotations"]} # 有图但没有任何框的图片 no_ann = img_ids - ann_img_ids # 有框但图片不存在的(脏数据) ghost = ann_img_ids - img_ids print("无标注图片数:", len(no_ann)) print("幽灵标注数:", len(ghost)) # 抽查一张图的框数量 sample_id = coco["images"][0]["id"] boxes = [a for a in coco["annotations"] if a["image_id"] == sample_id] print(f"图片 {sample_id} 有 {len(boxes)} 个框")

no_ann里的图片如果是纯背景图,可以保留当负样本;如果数量超过总图 10%,说明标注可能漏了。ghost不为空就是数据打包时出的错,必须清掉,否则训练时 DataLoader 会直接抛 KeyError。这一步花两分钟,能省掉后面调半天 loss 不下降的玄学时间。

3. 把 COCO JSON 转成 YOLO 格式:脚本、参数和四个边界坑

3.1 转换脚本的核心逻辑

虽然数据集号称支持 YOLO,但如果你拿到的是 COCO JSON 版本,还是得自己转一道。转换的核心就三件事:读图宽高、把 xywh 转成归一化 cxcywh、按类别名映射到连续 id。下面这个脚本我用了很多次,直接抄。

import json import os from pathlib import Path def coco_to_yolo(coco_json, img_dir, out_dir): with open(coco_json, "r", encoding="utf-8") as f: coco = json.load(f) # 类别 id 重映射为 0 起始的连续整数 cats = sorted(coco["categories"], key=lambda x: x["id"]) cat_id_map = {c["id"]: i for i, c in enumerate(cats)} names = [c["name"] for c in cats] # 图片 id 到文件名的映射 img_info = {img["id"]: img for img in coco["images"]} # 按 image_id 聚合标注 from collections import defaultdict anns = defaultdict(list) for a in coco["annotations"]: anns[a["image_id"]].append(a) os.makedirs(out_dir, exist_ok=True) for img_id, img in img_info.items(): w, h = img["width"], img["height"] lines = [] for a in anns.get(img_id, []): x, y, bw, bh = a["bbox"] # COCO 是左上角 xywh cx = (x + bw / 2) / w cy = (y + bh / 2) / h nw = bw / w nh = bh / h cid = cat_id_map[a["category_id"]] lines.append(f"{cid} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}") # 文件名去掉扩展名,存同名 txt stem = Path(img["file_name"]).stem with open(os.path.join(out_dir, stem + ".txt"), "w") as f: f.write("\n".join(lines)) # 顺便生成 classes.txt with open(os.path.join(out_dir, "classes.txt"), "w", encoding="utf-8") as f: f.write("\n".join(names)) print("转换完成,类别:", names) coco_to_yolo("annotations/instances.json", "images", "labels")

逻辑说明:bbox在 COCO 里是[x_min, y_min, width, height],绝对像素。YOLO 要的是中心点归一化坐标,所以先x + bw/2再除以图宽。cat_id_map把原始 category_id 压成 0 起始,因为 YOLO 的 class_id 必须从 0 连续。classes.txt的顺序就是 class_id 的顺序,训练时data.yaml里的 names 要跟它一致。参数上,:.6f保留六位小数足够,再多没必要。

3.2 边界坑一:图片尺寸和标注尺寸不一致

有些数据集在打包时图片被缩放过了,但 COCO JSON 里的width、height还是原图尺寸。这时候你按 JSON 里的宽高归一化,框会整体偏移。排查方法是抽几张图用 PIL 读实际尺寸,跟 JSON 里的对比。

from PIL import Image import json with open("annotations/instances.json") as f: coco = json.load(f) for img in coco["images"][:5]: real = Image.open(os.path.join("images", img["file_name"])).size if real != (img["width"], img["height"]): print("不一致:", img["file_name"], "JSON:", (img["width"], img["height"]), "实际:", real)

如果发现不一致,转换脚本里的w, h要改成用 PIL 实时读取,而不是信 JSON。这个坑很隐蔽,因为训练不会报错,只是 mAP 死活上不去。

3.3 边界坑二:类别名里有空格或特殊字符

COCO 的categories里如果类别名是blade crack这种带空格的,生成classes.txt没问题,但写data.yaml时如果直接拼字符串容易出问题。常见做法是统一把类别名转成下划线或者拼音,保持跟标注文件里的 class_id 对应即可。另外注意中文类别名在某些框架的日志里会乱码,建议转英文或拼音。

3.4 边界坑三:空标注图片的处理

转换后会生成一些空的.txt文件,对应没有缺陷的纯背景图。YOLO 训练时这些空文件是合法的负样本,但如果你用的 DataLoader 会跳过空文件,就等于丢了负样本,模型误检率会升高。确认你的训练配置里skip_empty是 False。如果数据集里负样本比例过高(比如超过 30%),可以适当抽掉一部分,避免正负失衡。

3.5 边界坑四:坐标越界

COCO 标注偶尔会有框超出图片边界的情况,比如x + bw > w。转成 YOLO 后 cx 可能大于 1,训练时会被 clamp 或者直接报错。转换时加一道裁剪:

x = max(0, min(x, w)) y = max(0, min(y, h)) bw = min(bw, w - x) bh = min(bh, h - y)

这四行加上去,能避免大部分“训练到第几个 epoch 突然 loss 变 NaN”的问题。血泪经验:坐标越界不报错,但会让梯度爆炸。

4. 训练配置与 91.4% 准确率的复现路径

4.1 用 YOLOv8 跑一个 baseline

数据转好之后,最快验证的方式是 Ultralytics YOLOv8。先建data.yaml:

path: ./dataset train: images/train val: images/val nc: 4 names: ['crack', 'erosion', 'lightning_damage', 'sand_hole']

nc是类别数,names顺序必须跟classes.txt一致。然后一条命令开训:

yolo detect train data=data.yaml model=yolov8s.pt epochs=100 imgsz=640 batch=16 patience=20

参数说明:model=yolov8s.pt是预训练权重,小模型速度快,适合先跑通。imgsz=640是输入分辨率,如果原图很大且缺陷很小,可以提到 1024,但显存要够。patience=20是早停,20 个 epoch 验证集不提升就停,省时间。batch=16根据显存调,8G 显存跑 640 大概能到 16。

4.2 91.4% 这个数字怎么理解

官方说的 91.4% 准确识别率,大概率是 mAP@0.5 或者 top-1 分类准确率,具体口径得看原文档。检测任务里,mAP@0.5 能到 0.9 以上算不错,但要注意这是在他们自己的验证集上。你复现时如果只拿到 0.85 左右,不一定是代码问题,可能是 train/val 划分不同。建议自己按 8:1:1 重新划分,跑三次取平均,心里才有底。另外,如果缺陷类之间长得很像(比如砂眼和雷击坑),混淆矩阵会告诉你哪些类在互相误判。

4.3 数据增强的参数怎么设

风机缺陷检测的难点是缺陷尺度变化大——裂纹可能横跨半个叶片,砂眼只有几十像素。增强策略上,mosaic和mixup能提升小目标召回,但mixup对缺陷检测有时会引入不真实的叠加,我一般把mixup关掉,只留mosaic=1.0。旋转增强要开,因为无人机拍摄角度不固定。HSV 抖动可以抑制光照影响,风场早晚光线差异大。具体在 YOLO 的hyp.yaml里调,或者命令行加degrees=10 hsv_h=0.015 hsv_s=0.7。

4.4 验证集评估看哪些指标

训完别只看一个 mAP,至少看四个数:mAP@0.5、mAP@0.5:0.95、precision、recall。风机巡检场景里 recall 比 precision 重要,漏检一个裂纹的代价远大于多报几个疑似。如果 recall 低,先查标注里有没有漏标,再考虑降低置信度阈值。混淆矩阵和 PR 曲线在runs/detect/val目录下,打开看一眼,比盯 loss 曲线有用。

5. 避坑与排查:训练不收敛、框错位、显存炸了怎么办

5.1 现象:loss 一直不降,mAP 在 0.1 附近晃

原因:最常见的是类别 id 和data.yaml里的 names 顺序对不上,模型学的是错位的标签。其次是图片路径写错,DataLoader 实际读到的是空图或默认图。解决:先跑一遍转换脚本里的校验逻辑,确认每张图都有对应 txt;再打印一个 batch 的标签看看 class_id 范围是否在[0, nc-1]内。

5.2 现象:验证时框整体偏移或缩放

原因:训练用的图片尺寸和标注归一化时用的尺寸不一致。比如转换时用了 COCO JSON 里的 1920x1080,但实际图片是 1280x720。解决:转换脚本里改用 PIL 实时读图宽高,重新生成一遍 labels。这个坑我踩过两次,第一次调了三天学习率,最后发现是尺寸问题。

5.3 现象:训练到一半 CUDA out of memory

原因:imgsz或batch设太大,或者mosaic增强在后期仍然开启导致单批图像数量翻倍。解决:先把batch减半,如果还炸,把imgsz从 1024 降到 640。另外 YOLO 的close_mosaic参数可以在最后 10 个 epoch 关掉 mosaic,既省显存又稳定收敛。

5.4 现象:某些类别完全检测不到

原因:该类样本太少,或者该类缺陷在图像里太小。解决:统计每类框数量,低于 200 的做过采样;检查 anchor 尺寸是否匹配,YOLOv8 是 anchor-free,但小目标仍然需要高分辨率输入。可以把imgsz提到 1280 试一轮,如果显存不够就用切片推理(SAHI)。

5.5 现象:模型在验证集好,换一批图就崩

原因:数据集的拍摄条件太单一,模型学到了背景捷径。比如所有训练图都是晴天拍的,阴天图就废了。解决:增强里加大 HSV 和亮度抖动,或者手动混入一些不同光照的负样本。如果数据集本身多样性不足,再强的模型也救不了,这是数据层面的天花板。

6. 进阶技巧:用切片推理把大图小缺陷的召回再拉一截

风机航拍图动辄 4000x3000,缺陷可能只占 50x50 像素。直接缩到 640 训练,小缺陷信息丢得差不多了。我一般会在 baseline 跑通后,加一层切片推理(SAHI,Slicing Aided Hyper Inference)。原理很简单:把大图切成有重叠的小块,每块单独推理,再把框映射回原图做 NMS。这样小缺陷在切片里变成了“大目标”,召回率能明显提升。

from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction # 加载训好的 YOLO 模型 detection_model = AutoDetectionModel.from_pretrained( model_type="yolov8", model_path="runs/detect/train/weights/best.pt", confidence_threshold=0.25, device="cuda:0" ) # 切片推理:512x512 的切片,重叠 20% result = get_sliced_prediction( "test_blade.jpg", detection_model, slice_height=512, slice_width=512, overlap_height_ratio=0.2, overlap_width_ratio=0.2 ) # 导出 COCO 格式结果 result.export_visuals(export_dir="output/")

参数说明:slice_height/width根据缺陷尺度调,缺陷越小切片越小,但切片太多会慢。overlap_ratio一般 0.2,太小会切断跨切片的缺陷,太大则重复框多。confidence_threshold可以比训练时低一点,因为切片后误检会被 NMS 压掉。跑完对比一下切片前后的 recall,通常能涨 3~8 个百分点。

另一个技巧是测试时增强(TTA),YOLO 自带augment=True,推理时对图片做翻转和缩放再合并结果。代价是推理速度慢 2~3 倍,适合离线巡检报告生成,不适合实时视频流。

从那以后我每次拿到新数据集,都强制先跑一遍标注校验和尺寸核对,再开始训。这两个检查加起来不到五分钟,但能省掉后面几天的无效调参。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 20:34:42

数据挖掘十大算法Python源码实战:从跑通到调优的完整攻略

简介:数据挖掘十大算法是数据科学入门与进阶的核心主题,一套Python实现合集覆盖Apriori、C4.5、CART、EM、K-means、KNN、PageRank等经典算法,面向算法学习者与需要快速上手的开发者,帮助理解各算法的原理与落地方式。压缩包共15个…

作者头像 李华
网站建设 2026/10/10 20:26:23

跨地域大文件怎么传?2026主流传输软件实测对比

在工程设计、影视后期、科研办公、互联网开发等行业的日常协作中,大文件传输已经成为高频刚需操作。多数用户常面临普通传输工具文件大小受限、传输中断重试、跨网传输卡顿、数据无安全防护等各类问题,严重影响工作效率。挑选适配的大文件传输软件&#…

作者头像 李华
网站建设 2026/10/10 20:25:09

为Ubuntu终端接入大模型Codex:把auth.json改到TaoToken的一行指令

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 20:25:02

Java 从零开始:用 Spring Boot 创建你的第一个 MCP 服务并接入 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 20:23:18

上市公司现金流分析:从docx数据提取到指标计算与财务排雷

简介:一份面向上市公司财务与金融实证研究的现金流指标数据集说明文档,资源标签为大数据,覆盖1991年至2024年6月沪深北A股季度数据,基于年报及公告整理,包含净利润现金净含量、营业收入现金含量、营业利润现金净含量、…

作者头像 李华
网站建设 2026/10/10 20:21:01

字符串第一个不重复字符:计数表与两遍遍历解法详解

1. 问题拆解:先搞清楚"第一个不重复"在问什么这道题的题目描述通常是这样的:给你一个字符串 s,找到并返回它的第一个不重复字符的下标;如果不存在,则返回 -1。举例来说,s "leetcode"&…

作者头像 李华