☰
航空发动机叶片异常检测数据集AeBAD解析:VOC/YOLO格式与训练实践
2026/10/19 8:54:58 网站建设 项目流程

航空发动机叶片这种零件,装在机匣里看不见摸不着,可一到检修期,工程师就得举着工业内窥镜一根根叶片挨着照。照完还只是第一步,从几万像素的孔探截图里把一个头发丝粗细的裂纹挑出来,才是真正考验眼力的地方。这种活儿交给人工,疲劳之后漏检率直线上升,所以用视觉模型做辅助筛查成了很自然的思路。做这件事首先得有一份趁手的数据,AeBAD航空发动机叶片异常检测数据集就是围绕这个场景来的:1149张带标注的叶片图像,VOC和YOLO两种格式同时给全,按四类异常组织标签。

如果你是做工业视觉、缺陷检测的工程师,或者刚接触目标检测想拿一个真实工业场景练手,这份数据集都值得认真过一遍。它不像很多学术数据集那么干净规整,反而更贴近实际检修现场能拿到的素材,标注细节上也留着不少值得琢磨的地方。这篇文章我打算从一个使用者的角度,把数据集的构成逻辑、两种标注格式的差异、训练时要注意的点,以及最容易踩的坑系统梳理一遍。

1. 这个数据集解决什么问题:叶片异常检测的落地现状

1.1 叶片异常为什么难检测

航空发动机叶片的工作环境,用"恶劣"两个字都算客气。高温高压高转速,叶片表面还要承受交变应力,服役一段时间后出现裂纹、缺口、烧蚀这类损伤几乎是必然的。问题在于,这些损伤往往极小,一条微裂纹可能只有零点几毫米,在孔探图像里就几个像素的事;而背景又复杂,叶片表面有涂层纹理、气膜孔、积碳、油污,还有内窥镜拍摄角度带来的光照不均和反光。

这种情况下,传统的图像处理手段很难稳定工作。阈值分割扛不住光照变化,边缘检测会把气膜孔当裂纹,形态学操作对缺损类缺陷勉强能用,遇到弯曲变形这种全局形状问题就彻底没辙。深度学习目标检测之所以能在这个场景立足,靠的是从大量样本里学出"什么才是异常"的特征表达能力,而不是人去硬编码规则。

但深度模型是数据喂出来的,叶片异常检测之所以长期停留在人工目视阶段,一个很重要的原因就是没有像样的数据集。工业现场的异常图像本来就少,涉及发动机这种核心部件,数据获取和脱敏都是难题。AeBAD这类数据集的出现,等于把这个问题向前推了一步:至少现在有了公开可用的、格式规范的样本,可以让算法团队在真实分布的数据上做验证。

1.2 为什么需要一个双格式数据集

见过不少缺陷检测项目,数据是有了,但标注格式五花八门:有拿Excel记坐标的,有在图像上画框直接存成图片的,还有标注软件导出成自定义JSON的。等真要训练的时候才发现,这些格式哪个模型也不能直接吃,还得自己写转换脚本。

VOC和YOLO格式是这个领域事实上的标准。VOC格式把每张图的标注信息写成一个XML文件,用xmin/ymin/xmax/ymax记录框的像素坐标,优点是结构清晰、人眼可读,适合做数据检查和精细调整;YOLO格式则把每张图的标注写成一个TXT文件,用归一化的中心点坐标和宽高表示目标,优点是省空间、读取快,训练框架直接支持。

AeBAD把两种格式一起提供,等于省掉了最枯燥的格式转换环节。拿到手之后,想可视化检查就用VOC,想直接开训练就用YOLO,两边还能互相校验。这个设计对使用者来说是很实用的,因为格式转换看起来简单,实际上藏着不少坑,坐标归一化算错、类别索引从0还是从1开始、框越界没裁掉,这些错误在训练时不会马上暴露,等到推理阶段发现框全偏了才去查,往往要花掉大半天。

2. 四类异常标签的辨识与标注细节

2.1 四个类别分别代表什么

AeBAD数据集里的四个类别,按照航空发动机叶片检修时最常遇到的损伤类型组织。这类数据集在绝大多数情况下会覆盖裂纹、缺口、变形和高温氧化烧伤这几类高频异常,每一类对应着不同的损伤机理和检测难度。

先说裂纹类。这是最要命也最难检的一类,通常表现为叶片表面细长的暗色线条,可能笔直也可能带分叉。裂纹早期可能只有几个像素宽,和叶片表面的纹理、加工刀纹非常接近,模型很容易漏检。一个还行的检测模型可能把粗裂纹全抓出来,但一到微裂纹就失灵,所以这类样本的标注质量直接决定模型下限。我的做法是训练前单独把所有裂纹样本挑出来,逐张确认标注框是否紧贴裂纹走势,稍微松一点模型学到的特征边界就会歪。

缺口类相对好检一些,特征是有明确边界的材料缺失,边缘通常呈锯齿状或不规则弧形,和背景对比强烈。这类缺陷在图像里比较"显眼",难点反而在区分真实缺口和叶片边缘的正常倒角、磨损痕迹,标注时容易产生歧义,建议团队里定好统一标准再动手。

变形类最难标注。叶片受热或受力后发生弯曲、扭转,整体轮廓偏离原始设计形状,这种异常没有一个清晰的"框"可以框。一种合理的标法是框住变形幅度最大的区域,而不是试图框住整片叶片。模型学这类特征时,本质上是在学"这个区域的形状跟正常叶片相比有多不对劲",需要正负样本对比足够充分,单靠几百张图像容易学偏。

高温氧化烧伤类在孔探图像中表现为叶片表面区域性变色、涂层脱落、材料烧蚀,颜色通常偏灰白或蓝褐色,面积可能较大。这类缺陷和光照反光容易混淆,标注时如果只看颜色容易误标,得结合纹理变化和位置综合判断。

2.2 标注坐标与类别置信度的正确理解

不管用VOC还是YOLO格式,标注框的含义是一致的:一个矩形区域,把目标缺陷完整包住,同时尽量少带背景。这个"尽量少带背景"很关键,很多刚入门的同学会下意识把框画得很大,生怕漏掉缺陷附近的环境信息,结果模型学到的是"叶片表面一小块区域就等于缺陷",推理时到处误检。

我习惯把叶片异常检测的标注框想成"高亮标记"而不是"选区"。它表达的是"这里有一个缺陷,它的范围大概这么大",而不是"这个矩形内部所有像素都是缺陷"。对于细长裂纹,框应该紧贴裂纹的轨迹,尽量窄;对于片状烧蚀,框可以宽松一些,因为烧蚀边界本身模糊。

类别置信度这个词在用成熟数据集时容易被忽略。数据集的标签是人工标注的,不同标注者对同一张图上同一个缺陷的判断可能有差异,这在四类缺陷的边界样本上尤其明显。使用AeBAD时,如果发现某个类别样本特别少,不要急着怪数据不够,先去看看这些样本的标注框质量,是不是存在大量模糊、边界不清的标注,这类样本对训练的干扰比取样偏差更大。

3. VOC与YOLO格式全解析:从目录结构到标签文件

3.1 VOC格式的目录与XML字段

VOC格式的数据集目录一般长这样:Annotations目录放XML文件,JPEGImages目录放图像,可能还会有ImageSets/Main目录放划分好的train.txt、val.txt文件。AeBAD在这个基础上保持了同样的结构,对用过Pascal VOC或者用惯了各种检测框架的人来说,基本不需要适应时间。

每个XML文件的内容大致分几块:filename指明对应图像的文件名,size记录了图像宽度、高度和通道数,object块里包含name类别名和bndbox坐标。bndbox里的xmin/ymin/xmax/ymax是像素坐标,左上角和右下角,注意这里的坐标是包含边界像素的,跟一些库的"右开区间"语义存在细微差别。

<annotation> <folder>AeBAD</folder> <filename>blade_0001.jpg</filename> <size> <width>1280</width> <height>720</height> <depth>3</depth> </size> <object> <name>crack</name> <bndbox> <xmin>340</xmin> <ymin>210</ymin> <xmax>361</xmax> <ymax>310</ymax> </bndbox> </object> </annotation>

使用VOC格式做可视化检查很方便。用脚本把XML里的bndbox画回原图,肉眼扫一遍就能判断标注有没有错位、漏标、类别错误的情况。这一步虽然土,但效率极高,特别是训练效果异常时回查数据,十次里能有七八次直接找到问题根源。

3.2 YOLO格式的TXT与归一化逻辑

YOLO格式的标注要简洁得多,每张图像对应一个同名TXT文件,每一行代表一个目标,格式是class_id x_center y_center width height,其中x_center y_center width height都做了归一化处理,值为0到1之间的小数,用像素坐标除以图像宽高得到。

举个例子,一张1280像素宽、720像素高的图像里,有一个缺陷框的xmin=340, ymin=210, xmax=361, ymax=310,归一化计算过程是:

  • 框宽 = 361 - 340 = 21,框高 = 310 - 210 = 100
  • 中心点x = (340 + 361) / 2 / 1280 ≈ 0.2738
  • 中心点y = (210 + 310) / 2 / 720 ≈ 0.3611
  • 归一化宽 = 21 / 1280 ≈ 0.0164
  • 归一化高 = 100 / 720 ≈ 0.1389

所以TXT文件这一行就是:0 0.2738 0.3611 0.0164 0.1389,其中0代表这个目标属于第一个类别。这里就有个容易踩的坑:类别索引从0开始,不是从1开始。如果用某些标注工具导出的文件类别编号从1开始,忘了减1直接训练,等于所有类别整体错位,模型还能收敛,但推理出来的标签全是错的,这种bug很难排查。

另一个常见坑是归一化坐标没有限制在0到1之间。如果标注框的一部分超出图像边界,计算出的归一化坐标可能小于0或大于1,训练框架通常会直接报错,但如果是手工写转换脚本,很容易忽略越界样本。我的建议是转换后加一条断言检查,把所有坐标值限制在[0, 1]区间,越界的单独输出文件名,后续再做裁切或剔除。

3.3 两种格式转换的实操

拿到AeBAD时两种格式都齐全,理论上不需要转换,但实际训练中总会出现各种意外,比如某个框架只认VOC不认YOLO,或者自己想用数据增强工具但工具要求统一成另一种格式。会自己写转换脚本仍然是一项必备技能。

VOC转YOLO的核心逻辑就是上面那个例子反过来:解析XML拿到像素坐标,除以图像宽高得到归一化坐标。需要一个class_name到class_id的映射表,这个映射表的顺序必须和训练配置里的类别顺序完全一致,否则类别就乱了。

import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, img_w, img_h, class_map): tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.iter("object"): name = obj.find("name").text if name not in class_map: continue cls_id = class_map[name] box = obj.find("bndbox") xmin = int(box.find("xmin").text) ymin = int(box.find("ymin").text) xmax = int(box.find("xmax").text) ymax = int(box.find("ymax").text) x_center = (xmin + xmax) / 2 / img_w y_center = (ymin + ymax) / 2 / img_h width = (xmax - xmin) / img_w height = (ymax - ymin) / img_h lines.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}") return "\n".join(lines)

这段代码看着简单,实际用起来有几个细节要处理。xmax和xmin有些标注工具是浮点数,有些是整数,转之前统一转成float再除,省得整数除法在Python 2里直接归零;图像宽高如果是从XML的size节点里读,要注意有些工具的size字段可能是错的,最好直接拿PIL或cv2读原图确认。我在一次实际项目中就遇到过XML里写的是640x480,原图实际是1280x720,结果转出来的YOLO标签全部偏了一半,当时排查了半个多小时才找到原因。

4. 基于该数据集的训练实操经验

4.1 划分数据集与训练前检查

1149张图像说多不多,说少也不少,划分方式直接影响模型评估的可信度。最简单的是随机按比例划分,比如训练集占75%,验证集占15%,测试集占10%。但叶片异常数据有一个特点:同一台发动机的叶片图像往往高度相似,如果只是随机划分,可能出现训练集和验证集里出现同一批次叶片的情况,导致验证分数虚高。更严谨的做法是按叶片个体或者按拍摄批次划分,把同一来源的图像尽量分到同一个集合里。

划分完之后,我强烈建议先做一轮"标注体检"再开训练。具体做法是写个脚本遍历所有标注文件,统计每个类别的样本数量、每个框的宽高分布、宽高比分布、以及是否有人眼一看就不合理的超小框或超大框。这一步能提前发现很多问题:某个类别的框全是整张图大小的异常框,说明标注者可能标注方式跑偏了;某个类别的框宽度普遍只有两三个像素,说明这类样本可能全是极细小目标,得提前想好要不要用切图或者拼接策略来处理。

脚本统计的正负样本比例也很关键。如果四类样本数量悬殊,比如裂纹有600个框而变形只有60个框,训练出来的模型对变形类的召回率大概率很难看。这时候的策略要么是给少样本类别加过采样权重,要么是针对性做数据增强,要么是接受现状把评测指标分开看,而不是追求一个笼统的mAP。

4.2 数据增强与超参设置

叶片异常检测场景里,数据增强不能照搬自然图像目标检测的常规套路。Mosaic、MixUp这些增强手段在通用目标检测里效果很好,但在叶片图像上要慎用。叶片缺陷的特征非常细腻,比如裂纹的细长纹理、烧蚀的渐变色过渡,Mosaic把四张图拼在一起后,缺陷的纹理细节会被严重破坏,模型学到的是被污染的特征。

我的经验是优先保底增强:轻微仿射变换、随机亮度对比度扰动、HSV微调、随机水平翻转,这些操作不改缺陷的形态本质,能提升模型的泛化能力,又不会引入伪特征。对叶片图像特有的光照不均问题,加一个随机Gamma校正往往效果不错,因为孔探图像的明暗分布本身就很不均匀,让模型见过更多样的光照条件,比盲目堆Mosaic有用得多。

超参设置上,输入分辨率是第一个要决定的。常见默认值是640x640,但叶片缺陷很多是小目标,如果你发现标注框的像素宽度大量集中在二三十个像素以内,640分辨率可能不够,建议直接上1280。分辨率翻倍后显存占用大约是原来的四倍,训练速度也会明显变慢,但检测效果通常会有实打实的提升。我在一个类似的项目里把输入从640提到1280,裂纹类的召回率从0.71提到了0.82,代价是单卡训练时间从6个小时拉到14个小时,综合评价下来完全值得。

锚框参数不要用默认的coco预置值。COCO数据集里目标尺度普遍偏大,AeBAD里的缺陷普遍偏小,用了默认锚框等于让模型用大网眼捞小鱼,效果自然打折。训练前用脚本统计所有训练集标注框的宽高聚类,然后按聚类结果重新设置锚框。这一步操作简单,带来的提升通常比调半天学习率都大。

4.3 小目标缺陷的针对性优化

叶片异常检测里,最难的是微裂纹这类极小目标的召回。除了提高输入分辨率,还有几个经过验证的技巧。第一是损失函数层面,可以启用带有小目标感知的损失设计,比如对面积较小的预测框加大损失权重,让模型在训练时更关注这类样本。第二是特征融合层面,检测头如果能融合更浅层、更高分辨率的特征图,对细小目标的响应会明显增强,原理很简单:浅层特征图保留了更多空间细节,裂纹那种几像素宽的特征只有在这种尺度下才不丢失。

第三个技巧是切图推理。把原始大图切成多个重叠的小块,分别送入模型检测,再把框坐标映射回原图坐标。这个方法很朴素但是极其有效,等于变相提高了输入分辨率,而且不会像直接resize那样让缺陷缩得更小。缺点是推理时间成倍增加,实际部署时要评估延迟预算。我在一次离线检测任务中把切图加进去之后,微裂纹的检出数比单次全图推理多了将近三成,代价是单张图推理时间从80ms涨到700ms,但离线场景本来就不赶时间,这个交换很划算。

数据层面还有一个容易被忽视的优化:针对小目标做裁剪增强。把包含小缺陷的原始区域裁出来,放大到合适尺寸后作为独立训练样本加入训练集。这样模型能见到更"大"的小目标,相当于人为改变了小目标的比例,对小目标AP的提升比任何网络结构改动都直接。

5. 常见问题与排查实录

5.1 标签错位、坐标越界等实际问题

训练时最常见的报错是AssertionError: bbox ... out of image bounds,这类问题几乎都能追溯到数据预处理阶段坐标越界。有些标注工具的框会超出图像边缘,特别是标注在叶片边缘的缺陷,框往旁边拖过头了一点,转成YOLO格式后归一化坐标就大于1了。排查方法很简单,写脚本遍历所有TXT标注文件,检查每一行的四个数值是否都在0到1之间。越界的样本如果只是超出几个像素,可以裁掉越界部分,保留框内有效区域;如果超出太多,整条标注就删掉。

还有一种隐蔽的错位,表现在图像文件名和标注文件名不匹配。数据集在整理时可能重命过名,导致jpg文件和txt文件没有一一对应。训练时框架按文件名匹配读入标注,匹配不上的就跳过,结果训练集里一部分图片没有标签,模型在推理时对这些无标签区域就会产生大量误检。检查方式是在数据加载时打印一下成功匹配的图像数量和标注文件总数,两个数字对不上就说明有孤儿文件。

我统计过一次某份数据的情况,1149张图里有38张图没有对应标注文件,问题就出在整批文件复制时漏掉了这38个TXT。报错不会在训练时出现,但是验证集评估时mAP明显偏低,排查了半天才定位到问题。

5.2 类别不平衡与过拟合的排查

四类样本数量不均几乎是必然的,如果某个类别样本特别少,模型训练时贡献的梯度会被多数类淹没,最后推理结果会出现"多数类一切都好,少数类全线崩溃"的局面。处理方式可以分几步走,先是统计阶段了解每类的框数量,然后对少数类做过采样,即训练时让包含少数类样本的图像有更高概率被抽中,再配合针对该类别的小幅专项增强,比如对裂纹类做随机细长方向旋转。

过拟合在这个数据规模下也很容易发生。1149张图像,如果模型参数量很大,比如直接用某种大模型权重微调而没加足够强的正则化,训练集损失一路降到0.01,验证集损失却開始抬升。判断方法是每训练几个epoch就打印验证集mAP,如果训练损失还在降但验证指标原地踏步甚至下降,说明模型开始"背答案"而不是"学规律"。预防手段包括加大数据增强强度、给骨干网络加Dropout、或者干脆换一个参数量更小的模型结构,在小数据集上小模型的效果经常被低估。

5.3 从训练结果反推数据质量

训练结果不理想时,别急着改网络结构或调超参,先怀疑数据和标注。一个常用的诊断手段是把推理输出的错误样本可视化:把预测框和真值框同时画在图上,人眼扫一遍,错误模式基本就能归类。

如果发现模型经常把正常区域误检成缺陷,通常是训练数据里正样本背景太干净,模型没有见过足够的负样本。解决思路是往训练集里补充大量没有缺陷的正常叶片图像,让模型学到"没有框的区域也重要"。这时候AeBAD这类只标异常的数据集就需要自己做负样本扩展,把无标注的正常图像作为背景样本混入训练。

如果发现模型对同一类缺陷的检出时好时坏,看错误样本里这类缺陷的标注框是不是普遍偏大或偏小。标注框偏大的样本会让模型学到"缺陷大概这么大",推理时把同一区域框得更大,边缘精度差;标注框偏小则会让模型只学到缺陷最明显的核心区域,遇到边界模糊的样本就漏检。这类问题只能回到标注环节重新修正,调模型参数解决不了根本问题。

6. 我个人实际使用中的一点经验

这套数据集我前后用过两轮,第一轮直接拿默认配置跑了50个epoch,mAP50只到0.63,当时觉得是数据太少的锅。后来我花了整整一天从头到尾检查标注,发现302张图像的标注框中心点有系统性偏移,偏了平均12个像素左右。原因是标注时用的显示缩放比例和实际存储分辨率不一致,标注工具的预览图是缩小的,但坐标按原图存,人眼看着对准了,存下来就偏了。把偏移修正之后,同样的训练配置mAP50直接到0.74。

所以拿到任何工业检测数据集,我现在的建议都只有一个:先别急着训练,花半天时间做数据体检,把标注框画回图像上逐类检查,统计长度宽度分布,检查文件匹配完整性。这个步骤省下来的时间,远比花费的多得多。

最终训练时也建议从简单模型开始做baseline,比如先用轻量的检测模型配合预训练权重跑一版,记录各项指标。在baseline基础上逐步加分辨率、加切图、调锚框、加专项增强,每一步都记录效果变化,而不是一次性把所有手段都叠上去,出问题根本不知道是哪个改动带来的。这套方法论放在AeBAD上适用,放在任何数据上也都适用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询