AOI 缺陷检测复现实操指南:Anomalib + MVTec AD(glass)与 YOLOv8 + NEU-DET 两条路线
摘要 :本文面向 AOI 玻璃微光学元件缺陷检测论文(Du et al., Optics Communications 2023)的复现需求,给出两条低成本 AutoDL 实操路线。路线 A 以 Anomalib + MVTec AD(glass 类别)复现无监督少样本异常检测,路线 B 以 Ultralytics YOLOv8 + NEU-DET 复现有监督两阶段检测主线,并附 CCS 卷积、IQE 图像质量评价、帧融合三个创新模块的代码框架、费用预算与避坑清单,两路线合计 GPU 费用可控制在 10 元以内。
目录
- [1. 路线总览与现成项目](#1. 路线总览与现成项目)
- [1.1 为什么是这两条路线](#1.1 为什么是这两条路线)
- [1.2 现成项目与数据集一览](#1.2 现成项目与数据集一览)
- [2. AutoDL 环境准备(两路线通用)](#2. AutoDL 环境准备(两路线通用))
- [2.1 实例选型与镜像](#2.1 实例选型与镜像)
- [2.2 学术加速与文件上传](#2.2 学术加速与文件上传)
- [2.3 省钱三原则](#2.3 省钱三原则)
- [3. 路线 A:Anomalib + MVTec AD(glass)](#3. 路线 A:Anomalib + MVTec AD(glass))
- [3.1 方法原理与论文的对应关系](#3.1 方法原理与论文的对应关系)
- [3.2 环境安装(GPU 实例内)](#3.2 环境安装(GPU 实例内))
- [3.3 数据准备(可在无卡模式做)](#3.3 数据准备(可在无卡模式做))
- [3.4 训练与评估(GPU 实例内)](#3.4 训练与评估(GPU 实例内))
- [3.5 预期结果与费用](#3.5 预期结果与费用)
- [4. 路线 B:Ultralytics YOLOv8 + NEU-DET](#4. 路线 B:Ultralytics YOLOv8 + NEU-DET)
- [4.1 方法原理与论文的对应关系](#4.1 方法原理与论文的对应关系)
- [4.2 环境安装与数据准备](#4.2 环境安装与数据准备)
- [4.3 训练与评估(GPU 实例内)](#4.3 训练与评估(GPU 实例内))
- [4.4 进阶:复现论文的四个创新模块(本指南的核心)](#4.4 进阶:复现论文的四个创新模块(本指南的核心))
- [4.5 预期结果与费用](#4.5 预期结果与费用)
- [5. 两路线对比与建议](#5. 两路线对比与建议)
- [6. 常见坑与对策](#6. 常见坑与对策)
- [7. 参考链接汇总](#7. 参考链接汇总)
1. 路线总览与现成项目
1.1 为什么是这两条路线
基准论文的核心方法可以拆成四个模块:两阶段 coarse-to-fine 检测、CCS 颜色通道分离卷积、IQE 图像质量评价、多帧融合决策。由于官方未开源代码、OGD-DET 数据集需邮件申请(周期不可控),复现按"方法可验证、数据可获取、费用可控"三个原则选了两条互补路线:
- 路线 A(无监督路线) :Anomalib + MVTec AD 的 glass 类别。只用良品样本训练即可检出缺陷,与论文"30 个样本就能训练"的少样本精神一致,且 MVTec AD 的 glass 类别就是透明玻璃表面缺陷,场景与论文最贴近。GPU 训练时间最短,适合先跑通找感觉。
- 路线 B(有监督路线):Ultralytics YOLOv8 + NEU-DET。对应论文的技术主线(YOLO 系列目标检测 + 小缺陷),NEU-DET 是工业缺陷检测最常用的公开基准(1800 张、6 类缺陷、VOC 标注),在此基础上可以完整复现论文的两阶段框架与三个创新模块。
1.2 现成项目与数据集一览
两条路线都有"官方现成项目",开箱即用,不需要从零写工程代码:
| 资源 | 地址 | 类型 | 说明 |
|---|---|---|---|
| Anomalib | https://github.com/open-edge-platform/anomalib | 官方代码库 | Intel 维护,内置 PatchCore/PaDiM/FastFlow 等模型与 MVTec AD 数据接口,pip 安装即可训练 |
| MVTec AD | https://www.mvtec.com/company/research/datasets/mvtec-ad | 公开数据集 | 15 个类别,含 glass(透明玻璃),需注册后从邮件链接下载 |
| Ultralytics YOLO | https://github.com/ultralytics/ultralytics | 官方代码库 | YOLOv5/v8/v11 一条命令训练,工业界事实标准 |
| NEU-DET(官方页) | http://faculty.neu.edu.cn/songkechen/zh_CN/zdylm/263270/list/ | 公开数据集 | 东北大学热轧带钢表面缺陷,1800 张、6 类、VOC XML 标注 |
| NEU-DET + YOLO 完整项目(社区) | https://github.com/Kshitij0605/Steel-Defect-Detection-using-Yolo-models | 社区复现 | 仓库内直接含数据集与 YOLOv5/v8/v9 训练代码,可对照参考 |
| NEU-DET + YOLOv8 完整项目(中文) | https://github.com/us-bit/Steel_Plate_Defect_Detection | 社区复现 | 中文 README,覆盖数据转换、训练、评估、可视化全流程 |
| AlexeyAB/darknet | https://github.com/AlexeyAB/darknet | 官方代码库 | 原味 YOLOv4/YOLOv4-tiny,论文原始架构,想贴近论文原版时用 |
优先级建议:先跑路线 A(半小时出结果、约 1 元钱),建立对"缺陷检测指标"的直觉;再跑路线 B 主线(约 2 小时);最后在路线 B 基础上加论文的四个创新模块做消融,这一步才是"理解论文"的核心。
2. AutoDL 环境准备(两路线通用)
2.1 实例选型与镜像
- 注册 https://www.autodl.com 并充值 20 元(足够全部实验)。
- 算力市场选 单卡 RTX 3090(24 GB),按量计费约 1.5~2 元/小时(4090 贵一倍,本指南实验完全用不满)。
- 镜像选择:PyTorch 2.1.0 / Python 3.10(或 3.11) / CUDA 12.1(框架镜像列表里直接选,不要自己装 CUDA)。
- 创建实例后,控制台点 JupyterLab 即可进入网页终端,本地无需装任何东西。
目录约定:代码与数据统一放 /root/autodl-tmp(数据盘,容量大、关机保留),不要放系统盘(约 30 GB 上限)。
2.2 学术加速与文件上传
bash
# 访问 GitHub / HuggingFace 前开启学术加速(AutoDL 内置)
source /etc/network_turbo
# 用完关闭,避免影响其他下载
unset http_proxy && unset https_proxy
- pip 安装包不需要 开加速,AutoDL 已配置国内镜像源,直接
pip install即可。 - 上传数据:小文件用 JupyterLab 直接拖拽;大文件用 AutoDL 网盘(控制台"文件存储"上传后实例内挂载
/root/autodl-nas);几十 MB 的数据集也可以开加速后直接wget。
2.3 省钱三原则
- 无卡模式做准备:控制台关机后可开"无卡模式开机"(约 0.1 元/小时,纯 CPU)。数据下载、格式转换、IQE 聚类这类不吃 GPU 的步骤全放这里做。
- 训练时才开 GPU:开卡 → 训练 → 看完日志立刻关机。AutoDL 关机后不收 GPU 费用,数据保留。
- 及时取回结果:训练产物(weights、metrics、可视化)打包下载回本地,再释放实例,避免长期占着数据盘。
3. 路线 A:Anomalib + MVTec AD(glass)
3.1 方法原理与论文的对应关系
PatchCore 的思路:只用正常样本的特征分布建模,推理时偏离分布的区域即缺陷。这与论文"少量样本训练即可上线"的工业诉求同源------论文用 30 个样本训练 YOLO,而 PatchCore 甚至不需要缺陷标注。对透明玻璃这种"缺陷形态千奇百怪、良品长得都一样"的场景,无监督路线往往比有监督更实用。
3.2 环境安装(GPU 实例内)
bash
source /etc/network_turbo
cd /root/autodl-tmp
git clone https://github.com/open-edge-platform/anomalib.git
cd anomalib
pip install -e . # 或直接 pip install anomalib
anomalib install # 安装完整依赖(SwAV 预训练权重等)
unset http_proxy && unset https_proxy
版本提示:Anomalib 2.x 的 API 与 1.x 差异较大,本指南按 2.x 写。如遇 API 报错,先
pip show anomalib确认版本,再对照官方文档。
3.3 数据准备(可在无卡模式做)
- 浏览器打开 https://www.mvtec.com/company/research/datasets/mvtec-ad ,填写邮箱注册(免费,链接发到邮箱,注意查垃圾邮件)。
- 下载 glass.tar.xz(单类别,约几百 MB;不必下全量 4.9 GB 的整包)。
- 上传到实例并解压:
bash
mkdir -p /root/autodl-tmp/datasets/MVTec_AD
tar -xJf glass.tar.xz -C /root/autodl-tmp/datasets/MVTec_AD
# 期望目录结构:
# MVTec_AD/glass/train/good/ ← 训练用良品
# MVTec_AD/glass/test/broken_large/ ← 测试缺陷(大裂)
# MVTec_AD/glass/test/broken_small/ ← 测试缺陷(小裂)
# MVTec_AD/glass/test/contamination/ ← 测试缺陷(污染)
# MVTec_AD/glass/ground_truth/... ← 像素级缺陷掩码
3.4 训练与评估(GPU 实例内)
新建 train_patchcore_glass.py:
python
from anomalib.data import MVTec
from anomalib.models import Patchcore
from anomalib.engine import Engine
datamodule = MVTec(root="datasets/MVTec_AD", category="glass")
model = Patchcore() # 换成 Padim() 即可跑 PaDiM 基线
engine = Engine(max_epochs=1) # PatchCore 本质是特征提取+核心集采样,1 epoch 足够
engine.fit(model=model, datamodule=datamodule)
engine.test(model=model, datamodule=datamodule) # 输出 image/pixel AUROC
bash
python train_patchcore_glass.py
也可用命令行(等价):
bash
anomalib train --model Patchcore --data MVTec --data.category glass
结果输出在 results/ 目录:.ckpt 权重、指标 CSV,以及缺陷热力图可视化(这是最直观的部分------模型把缺陷区域标红,可直接截图放进汇报)。
3.5 预期结果与费用
| 项目 | 预期 |
|---|---|
| PatchCore glass image-AUROC | ≈ 0.99 |
| PaDiM glass image-AUROC | ≈ 0.98 |
| 3090 训练耗时 | PatchCore 约 10~15 分钟,PaDiM 约 5~10 分钟 |
| GPU 费用 | 开卡 0.5 小时 ≈ 1 元 |
消融建议:同一数据上对比 PatchCore / PaDiM / FastFlow(各改一行模型名),观察"无监督三兄弟"在 glass 上的差异,这一步对理解异常检测范式帮助很大。
4. 路线 B:Ultralytics YOLOv8 + NEU-DET
4.1 方法原理与论文的对应关系
论文主线是"YOLO 检测小缺陷 + 两阶段先找工件再找缺陷"。NEU-DET 虽是钢材而非玻璃,但缺陷小、类别清晰、标注齐全,是验证检测方法的标准试验田。先复现单阶段基线(对应论文 Table 1 的对比实验),再组装两阶段框架与创新模块。
4.2 环境安装与数据准备
安装(GPU 实例内):
bash
pip install ultralytics
数据下载(无卡模式即可):三个来源任选其一------
- 官方页面申请下载:http://faculty.neu.edu.cn/songkechen/zh_CN/zdylm/263270/list/
- 直接克隆含数据的社区仓库(最快):
bash
source /etc/network_turbo
git clone https://github.com/Kshitij0605/Steel-Defect-Detection-using-Yolo-models.git
unset http_proxy && unset https_proxy
- Kaggle 搜索 "NEU-DET"(注意选带 VOC/XML 标注的检测版,不是分类版)。
VOC XML → YOLO txt 转换脚本(NEU-DET 原始标注是 PASCAL VOC 格式):
python
# voc2yolo.py 用法: python voc2yolo.py <images_dir> <annotations_dir> <out_dir>
import os, glob, xml.etree.ElementTree as ET
CLASSES = ["crazing", "inclusion", "patches", "pitted_surface", "rolled_in_scale", "scratches"]
def convert(img_dir, ann_dir, out_dir):
os.makedirs(out_dir, exist_ok=True)
for xml_path in glob.glob(os.path.join(ann_dir, "*.xml")):
root = ET.parse(xml_path).getroot()
w = int(root.find("size/width").text)
h = int(root.find("size/height").text)
lines = []
for obj in root.findall("object"):
c = CLASSES.index(obj.find("name").text)
b = obj.find("bndbox")
x1, y1 = float(b.find("xmin").text), float(b.find("ymin").text)
x2, y2 = float(b.find("xmax").text), float(b.find("ymax").text)
lines.append(f"{c} {(x1+x2)/2/w:.6f} {(y1+y2)/2/h:.6f} {(x2-x1)/w:.6f} {(y2-y1)/h:.6f}")
with open(os.path.join(out_dir, os.path.basename(xml_path)[:-4] + ".txt"), "w") as f:
f.write("\n".join(lines))
# 按 80/20 划分 train/val 后分别调用,目录结构见下方 neu.yaml
目标目录结构与 neu.yaml:
yaml
# neu.yaml
path: /root/autodl-tmp/NEU-DET
train: images/train
val: images/val
names:
0: crazing
1: inclusion
2: patches
3: pitted_surface
4: rolled_in_scale
5: scratches
NEU-DET/
├── images/{train, val}/ ← 1440 / 360 张
├── labels/{train, val}/ ← 对应 YOLO txt
└── neu.yaml
4.3 训练与评估(GPU 实例内)
bash
# 关键点:复用 COCO 预训练权重 yolo8n.pt(自动下载),这是省时省钱的核心
yolo train model=yolov8n.pt data=neu.yaml epochs=100 imgsz=640 batch=16 device=0
# 评估
yolo val model=runs/detect/train/weights/best.pt data=neu.yaml
| 项目 | 预期 |
|---|---|
| mAP@0.5 | 0.75 左右(crazing 类最难,约 0.5;patches 类最好,约 0.95) |
| 3090 训练耗时 | 约 1~1.5 小时 |
| GPU 费用 | ≈ 2~3 元 |
想复现论文 Table 1 的 Faster R-CNN / SSD 基线对比:装 MMDetection(pip install mmengine mmcv mmdet),用其预置配置换数据集即可,约再花 1 小时 GPU。
4.4 进阶:复现论文的四个创新模块(本指南的核心)
以下模块在单阶段基线跑通后逐一叠加,每加一个模块重训一次、记录指标变化------这就是属于自己的消融实验。
(1)两阶段 coarse-to-fine(模拟版)
NEU-DET 每张图都是纯钢材表面,没有"从背景里找工件"的问题。模拟方法:把 200×200 的原图贴到 640×640 的复杂背景(随机纹理/产线照片)上,于是------
- Stage 1(粗):在 640 图上训练一个 YOLOv8n 检测"钢材区域"(对应论文的玻璃定位,模型直接用 COCO 预训练微调 20 epoch 即可);
- Stage 2(细):裁出区域并放大回原分辨率,送入 4.3 训练好的缺陷检测模型。
对照实验:单阶段直接在 640 背景图上检测 vs 两阶段级联,观察 Precision 变化------论文宣称两阶段带来约 9.8% 的 Precision 提升,看能否复现出同方向的结果。
(2)CCS 颜色通道分离卷积(简化实现)
论文的 CCS 本质是"三个颜色通道各自过一组 CBL+MCBL4 再融合"。PyTorch 里用分组卷积近似(约 20 行):
python
import torch
import torch.nn as nn
class CCSConv(nn.Module):
"""CCS 简化版:每通道独立 CBL + 池化卷积堆叠,拼接后 1x1 融合"""
def __init__(self, c2=96):
super().__init__()
c = c2 // 3
def branch():
layers = [nn.Conv2d(1, c, 3, 1, 1), nn.BatchNorm2d(c), nn.LeakyReLU(0.1)]
for _ in range(2): # 论文为 MCBL4×4,此处减半便于收敛
layers += [nn.MaxPool2d(2, 2, ceil_mode=True),
nn.Conv2d(c, c, 3, 1, 1), nn.BatchNorm2d(c), nn.LeakyReLU(0.1)]
return nn.Sequential(*layers)
self.branches = nn.ModuleList([branch() for _ in range(3)])
self.fuse = nn.Conv2d(c * 3, c2, 1)
def forward(self, x): # x: [B,3,H,W]
outs = [b(x[:, i:i+1]) for i, b in enumerate(self.branches)]
return self.fuse(torch.cat(outs, dim=1))
接入方式:替换 YOLOv8 网络 model.yaml 里第一层卷积(ultralytics 支持自定义模块注册),NEU 是灰度图,可将三通道填同一灰度或保留 RGB 读取------重点是验证"通道分离是否带来增益"这个思想。
(3)IQE 图像质量评价(无 GPU,无卡模式跑)
论文用 HOG 特征 + K-means 聚类把清晰帧与模糊帧分开,纯传统机器学习:
python
# iqe.py ------ 训练阶段
from skimage.feature import hog
from sklearn.cluster import KMeans
import joblib, glob, cv2
feats = [hog(cv2.cvtColor(cv2.imread(p), cv2.COLOR_BGR2GRAY), orientations=9,
pixels_per_cell=(16, 16)).ravel()
for p in glob.glob("frames/*.png")]
km = KMeans(n_clusters=20, max_iter=100).fit(feats)
joblib.dump(km, "iqe_kmeans.pkl")
# 之后人工查看 20 个簇的中心图,把"清晰簇"编号记下来,例如 {2,5,7,9,11,13,15,17,19}
# 测试阶段:新帧 HOG 与各簇中心算 MSE,最近中心若属于清晰簇 → 保留该帧
验证方法:把测试图人工加高斯模糊/运动模糊造一组"模糊帧",看 IQE 的查全率------论文用 20 簇选 9 个参考簇,参数可直接沿用。
(4)多帧融合决策
对应论文"视频级输出":M/N 超过阈值 T 或任一帧置信度超过 Ct 即判缺陷:
python
def frame_fusion(confs, T=0.1, Ct=0.8):
"""confs: 一个样本所有帧的检测置信度列表(无缺陷帧为 0)"""
N = len(confs)
M = sum(1 for c in confs if c > 0.5)
return (M / N > T) or (max(confs, default=0) > Ct)
模拟方法:对每个测试样本做随机裁剪/旋转/模糊生成 20 帧"伪视频",对比"单帧判定 vs 融合判定"的 Recall 与 Precision。论文结论方向是融合显著提 Recall------若复现出同样趋势,就真正理解了这一模块存在的意义。
4.5 预期结果与费用
| 步骤 | 耗时 | 费用 |
|---|---|---|
| 数据准备与转换(无卡模式) | 1~2 小时 | ≈ 0.2 元 |
| 单阶段基线训练 | 1~1.5 小时 | ≈ 2~3 元 |
| 两阶段模拟 + CCS 消融(2~3 次重训) | 2~3 小时 | ≈ 4~6 元 |
| IQE + 帧融合(无卡模式) | 1 小时 | ≈ 0.1 元 |
5. 两路线对比与建议
| 维度 | 路线 A:Anomalib | 路线 B:YOLOv8 |
|---|---|---|
| 监督范式 | 无监督(只用良品) | 有监督(需缺陷标注) |
| 数据场景 | 透明玻璃(与论文一致) | 钢材表面(方法同源) |
| 对应论 文模块 | 少样本精神、异常检测范式 | 两阶段主线、CCS、IQE、帧融合 |
| GPU 时间 | ≈ 0.5 小时 | ≈ 3~5 小时 |
| 总费用 | ≈ 1~2 元 | ≈ 6~10 元 |
| 建议顺序 | 先跑,半天出结果 | 后跑,是复现的主体 |
两条路线合计预算 15 元以内,充值 20 元留足重试余量。
6. 常见坑与对策
| 症状 | 原因与解法 |
|---|---|
git clone 超时 |
忘开学术加速:source /etc/network_turbo;用完记得关 |
| MVTec 下载链接打不开 | 链接发在注册邮箱,常进垃圾箱;单类 glass.tar.xz 才几百 MB,别下 4.9 GB 全量包 |
| anomalib API 报错 | 1.x/2.x API 不同:固定 pip install anomalib 最新版并对照 2.x 文档,或 pip install anomalib==2.0.0 |
| YOLO 显存不足(OOM) | batch=16 改 batch=8,或 imgsz 降到 512 |
| NEU-DET 检测 mAP 偏低 | 属正常:crazing 类边界模糊天然难检;可加大 imgsz 到 800 或启用 mosaic 关闭(mosaic=0.5)微调 |
| 训练产物丢失 | 关机前在 JupyterLab 把 runs/、results/ 打包 zip 下载到本地 |
| 数据盘越用越满 | 释放实例前清掉不再用的数据集;autodl-tmp 大文件用完即删 |
7. 参考链接汇总
- 基准论文:Du Y. et al., An automated optical inspection (AOI) platform for three-dimensional (3D) defects detection on glass micro-optical components, Optics Communications 545 (2023) 129736. https://doi.org/10.1016/j.optcom.2023.129736
- 姊妹篇(算法细节更全):Zhou H. et al., Video-Based Two-Stage Network for Optical Glass Sub-Millimeter Defect Detection, AI 3(3):571-581, 2022. https://doi.org/10.3390/ai3030033 (OGD-DET 数据集申请:https://pntehan.github.io/OGD-DET/ ,邮件 zhouhan@iict.ac.cn)
- Anomalib:https://github.com/open-edge-platform/anomalib
- MVTec AD:https://www.mvtec.com/company/research/datasets/mvtec-ad
- Ultralytics:https://github.com/ultralytics/ultralytics
- NEU-DET 官方:http://faculty.neu.edu.cn/songkechen/zh_CN/zdylm/263270/list/
- AutoDL 使用文档:https://www.autodl.com/docs