工业视觉质检是 AI 落地最实的场景之一:产线上一台相机加一个推理盒子,替掉人眼盯屏幕的质检工位,账很好算。但真做过项目的人都知道,从"实验室跑通 demo"到"产线 7×24 小时稳定运行",中间隔着一条深沟。本文按实际项目节奏,把缺陷检测从 0 到 1 的关键决策点梳理一遍,包括数据、模型、部署三个层面的坑。
先想清楚:工业质检难在哪
和互联网 CV 任务比,工业缺陷检测有四个反直觉的特点。
缺陷样本极度稀缺。良率 99.9% 的产线,攒一个月可能只有几十张缺陷图,还经常凑不齐缺陷类型——这正是异常检测(anomaly detection)路线在工业界比监督检测更吃香的原因。
类别严重不平衡且边界模糊。划痕多深算缺陷、色差多少算超差,标准往往写在老师傅脑子里,标注一致性比想象中差。项目早期一定要拉着工艺、质检、客户三方把判定标准量化成可执行的规则,否则模型永远在追一个移动的靶子。
误检和漏检的代价不对称。漏检放走不良品会流向客户,误检过高则拉低产线直通率、增加复判人力。指标设计必须反映这个不对称性——通常漏检率的容忍度比误检率低一个数量级。
成像条件决定上限。打光方案(同轴光、条形光、穹顶光)、相机选型、镜头畸变控制,这些光学工程对最终效果的影响常常大于模型结构。见过太多项目模型换了三轮,最后发现是光源频闪的问题。
数据策略:少样本下的生存之道
冷启动阶段的数据工作建议按这个顺序推进:
- 先采后标,定标再扩:首批采 500-2000 张良品图 + 尽量多的缺陷图,用一小批双人标注的数据评估标注一致性(Cohen's Kappa),达标后再放量;
- 缺陷类型分级:把缺陷按发生频率和检出难度分级,高频易检的先上线,低频难检的列入持续收集清单;
- 主动制造缺陷:和工艺配合,人为复现典型缺陷(划、压、污染、缺料),是冷启动阶段性价比最高的数据扩增手段;
- 图像增强要物理合理:亮度、对比度、旋转、裁剪随便用,但弹性形变、颜色抖动要小心——很多缺陷本身就是形态和颜色信息,乱增强会把正例特征洗掉。
一个经验数字:单一工位、单一缺陷族,监督方案通常需要每类缺陷 200-500 张有效样本才能收敛到可用水平;异常检测方案用几百张良品图就能起步。
模型选型:三条技术路线
监督检测/分割(YOLOv8-seg、Mask R-CNN、RT-DETR):缺陷类型明确、样本够、需要输出缺陷类别和精确位置时选它。优点是输出结构化、可解释;缺点是对新缺陷类型零泛化。小目标缺陷建议上 FPN + 高分辨率输入,或者直接切 patch 检测再拼图。
无监督异常检测(PatchCore、PaDiM、FastFlow、EfficientAD):只用良品训练,学习"正常长什么样",推理时输出像素级异常热力图。PatchCore 在 MVTec AD 基准上长期霸榜,思路是用预训练 backbone 抽 patch 特征建正常特征库,推理时做最近邻检索打分。它几乎是为工业场景量身定做的:冷启动快、对未见缺陷有一定检出能力、热力图还能辅助定位。
半监督/混合方案:产线稳定后,积累的缺陷图越来越多,常见做法是用异常检测做第一道筛(低漏检),监督分类做第二道判(低误检),两阶段串联平衡指标。
另外,大模型时代的视觉基础模型也在渗透这个场景:SAM 用来辅助标注能省 70% 的标注工时;CLIP 系的零样本异常检测(WinCLIP、AnomalyCLIP)在缺陷描述可文本化的场景值得一试,但产线级稳定性目前还不如专用模型。
动手试试:用 anomalib 训练 PatchCore
Intel 开源的 anomalib 把主流异常检测算法封装成了统一 API,十几行代码就能训练评估:
from anomalib.data import MVTecAD from anomalib.models import Patchcore from anomalib.engine import Engine # 1. 数据: 良品图放 train/good, 测试集含缺陷图与掩码 datamodule = MVTecAD( root="./datasets/mvtec", category="bottle", image_size=256, train_batch_size=8, ) # 2. 模型: WideResNet-50 backbone + 核心集采样的最近邻库 model = Patchcore( backbone="wide_resnet50_2", layers=["layer2", "layer3"], coreset_sampling_ratio=0.1, # 核心集比例, 控显存和速度 num_neighbors=9, ) # 3. 训练(实际是特征库构建) + 测试 engine = Engine(image_metrics=["AUROC", "F1Score"], pixel_metrics=["AUROC"]) engine.fit(model=model, datamodule=datamodule) engine.test(model=model, datamodule=datamodule)换成自己的数据,把 datamodule 换成Folder格式即可。MVTec AD 上 PatchCore 的图像级 AUROC 通常能到 98%+,但别被基准分数迷惑——产线光照漂移、来料批次差异对特征分布的冲击,比基准数据集大得多。
部署落地:让模型在产线上活下来
模型上线前后的工程清单,按重要性排序:
- 推理加速:边缘端首选 TensorRT(NVIDIA)或 OpenVI