当前位置: 首页 > news >正文

基于 MVTec AD 真实图像子集的工业表面异常检测:Python 无监督缺陷检测实战

关键词:工业缺陷检测、MVTec AD、无监督异常检测、IsolationForest、SSIM、异常热力图、机器视觉质检、Python 项目实战

摘要

工业质检场景里,正常样本通常更容易采集,缺陷样本却少、杂、贵,直接做目标检测或分割往往会卡在标注成本上。本文实现一个轻量级工业表面异常检测项目:只用正常图像建模,推理时输出异常分数、热力图、二值掩膜、CSV 报表和指标图。示例数据采用 MVTec AD transistor 类公开真实图像子集,便于读者快速复现完整流程。

本项目适合作为课程实验、论文基线和机器视觉质检原型的入门版本。它不依赖 PyTorch/TensorFlow,也不需要大模型权重,核心依赖是numpypandasscikit-imagescikit-learnmatplotlibPillow

项目实现效果

项目按“真实图像输入 - 正常样本训练 - 异常分数融合 - 热力图定位 - 报表输出”组织。示例真实子集包含 10 张正常训练图、1 张正常测试图和 2 张可见表面损伤测试图,标签清单保存在data/real_transistor_subset/labels.csv

这套结构保留了完整工程闭环:configs/real_transistor_config.json管理数据路径、图像尺寸和阈值;src/feature_extractor.py负责特征提取;src/anomaly_detector.py负责模板建模、IsolationForest 和预测;src/evaluation.py负责批量评估、报表和结果可视化。

算法流程如下。训练阶段只读取train/good中的正常图像,先生成正常模板,再提取统计特征、纹理残差、梯度、直方图、模板差异和 SSIM 差异。推理阶段将 IsolationForest 分数、MSE 差异和 SSIM 误差融合为异常分数,同时输出局部热力图。

单张真实表面损伤图的推理结果如下。左上角是输入图,右上角是异常热力图,左下角是二值掩膜,右下角是叠加可视化。热力图可以辅助判断异常集中位置,比单纯的正常/异常标签更适合质检复核。

数据与运行方式

项目默认使用真实图像子集配置:

python main.py--modeall--configconfigs/real_transistor_config.json

单图推理命令如下:

python main.py--modeinfer--configconfigs/real_transistor_config.json--inputdata/real_transistor_subset/test/surface_damage/damage_005.jpg--outputimages/results/single_inference_real.png

运行后会生成这些关键文件:

outputs/detection_report.csv outputs/metrics.json images/results/anomaly_score_chart.png images/results/confusion_matrix.png images/results/result_00_good.png images/results/result_01_surface_damage.png images/results/single_inference_real.png models/surface_anomaly_detector.joblib

正常样本的可视化结果如下。模型输出为正常,异常分数略低于配置阈值。

与正常图相比,表面损伤图在异常分数和局部热力图上会出现更明显响应。示例数据来自公开真实图片子集,适合展示项目运行链路;如果要做正式论文实验,仍应下载完整 MVTec AD 数据集并按类别重新评估。

真实子集评估结果

批量评估会把每张测试图的预测结果写入outputs/detection_report.csv。示例真实子集的检测结果如下:

样本类型数量预测结果
正常样本11 张预测正常
表面损伤样本22 张预测异常

指标文件outputs/metrics.json的核心结果为:

指标数值
Accuracy1.000
Precision1.000
Recall1.000
F11.000
TP/TN/FP/FN2 / 1 / 0 / 0

异常分数图如下。绿色柱表示正常样本,红色柱表示异常样本,虚线为当前配置阈值0.990。这个阈值是在示例小子集上校准的,迁移到其他工位或完整数据集时需要重新调整。

混淆矩阵适合放进项目报告或实验记录,用来说明示例真实子集的图像级判断结果。

核心算法说明

正常模板

训练阶段先把所有正常训练图统一缩放到配置尺寸,默认256 x 256,再求平均得到正常模板。对于固定相机、固定背景、固定产品姿态的质检任务,模板差异是一个容易解释的 baseline。

template=mean(normal_images)

模板方法不是万能的。如果真实现场存在明显位移、旋转、尺度变化或光照漂移,应先做 ROI 裁剪、图像配准、亮度归一化,或进一步扩展为 PatchCore、FastFlow、Reverse Distillation 等深度异常检测方法。

特征提取

每张图片会提取六类信息:

特征类型作用
灰度统计描述整体亮度和分位数分布
局部残差捕捉局部纹理突变
梯度统计反映边缘和划痕类变化
灰度直方图表征整体灰度结构
模板差异衡量与正常模板的像素偏离
SSIM 差异衡量局部结构相似度下降

IsolationForest负责学习正常样本的特征分布。推理时,项目把特征异常分数、MSE 差异和 SSIM 误差组合成最终异常分数:

anomaly_score=0.40*feature_score+0.34*mse_score+0.26*ssim_score

热力图与掩膜

局部热力图由模板差异和 SSIM 局部误差共同生成。项目随后对热力图进行阈值化、开闭运算和连通域过滤,得到二值缺陷掩膜。这样做的好处是输出不仅有图像级判断,还能给出可视化定位结果,便于人工复核。

目录结构

industrial_surface_anomaly_detection/ ├── main.py ├── requirements.txt ├── configs/ │ ├── real_transistor_config.json │ └── demo_config.json ├── data/ │ ├── real_transistor_subset/ │ └── README_MVTEC_AD.md ├── src/ │ ├── anomaly_detector.py │ ├── evaluation.py │ ├── feature_extractor.py │ ├── visualization.py │ └── data_generator.py ├── images/ │ ├── figures/ │ └── results/ ├── outputs/ └── models/

demo_config.jsonsrc/data_generator.py可用于离线教学扩展,本文展示和默认运行均使用真实图像子集。完整 MVTec AD 数据集体积较大,正式实验应从官方页面下载并遵守数据集许可。

扩展建议

如果要把这个项目继续做成更完整的工业质检系统,可以从以下方向扩展:

  1. 加入 ROI 自动裁剪,减少背景孔位和拍摄位置变化对模板差异的影响;
  2. 对完整 MVTec AD 单类别重新生成labels.csv,评估更多缺陷类型;
  3. 增加像素级指标,例如 AUROC、PRO、IoU 或 Dice;
  4. infer_single()接入 Flask、FastAPI、Streamlit 或 PySide6;
  5. 用 PatchCore、FastFlow 等方法替换当前轻量 baseline,并保留本文的报表和可视化结构。

参考资料

  1. MVTec AD 官方数据集页面:https://www.mvtec.com/company/research/datasets/mvtec-ad
  2. MVTec AD CVPR 2019 论文页面:https://openaccess.thecvf.com/content_CVPR_2019/html/Bergmann_MVTec_AD_–_A_Comprehensive_Real-World_Dataset_for_Unsupervised_Anomaly_CVPR_2019_paper.html
  3. Dataset Ninja MVTec AD 页面:https://datasetninja.com/mvtec-ad
  4. scikit-image SSIM 文档:https://scikit-image.org/docs/stable/api/skimage.metrics.html
  5. scikit-learn IsolationForest 文档:https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html
http://www.jsqmd.com/news/938695/

相关文章:

  • 保姆级教程:用UltraISO制作U盘,在旧电脑上安装ESXi 7.0搭建家庭实验室
  • 基于Arduino与树莓派的低成本Mesh网络智能家居系统DIY全解析
  • 3D 建模、虚拟仿真、数字孪生 从 0 开始到完成:三条实操路线
  • AI 项目如何申请软件著作权?2026 新规下材料清单、申请流程与补正避坑指南
  • 去水印工具有哪些?免费去水印工具推荐完整指南 - 工具软件使用方法推荐
  • STM32实战:用编码器测速搞定MG513电机转速(附4倍频配置与避坑点)
  • 无水印保存小红书图片?2026免费保存高清原图方法 - 科技大爆炸
  • 详解照片锐化步骤 移动端修复模糊影像实操教程 - 软件工具教程方法
  • 如何快速部署Windows运行库:系统管理员的终极解决方案
  • AI智能体工作流:避免过度设计,从概念到实践的成本效益分析
  • 小红书视频怎么关闭下载水印?小红书如何去除下载水印?实测有效方法汇总 - 工具软件使用方法推荐
  • 从ChronoZoom挑战赛看数据可视化在教育场景中的跨界实践
  • 3步开启英雄联盟智能辅助:本地化LCU工具LeagueAkari深度指南
  • 如何快速清理微信单向好友:3步完成好友关系检测与管理
  • 保姆级教程:在Ubuntu 20.04上从零跑通Cartographer ROS(含常见报错解决)
  • 从淘宝镜像到期说起:聊聊国内开发者如何科学管理npm源(nvm、yarn、pnpm全适配)
  • 人物抠图入门指南 新手用小程序快速分离人像背景 - 软件工具教程方法
  • 基于Pinoo与LDR传感器的激光防盗报警系统:创客入门综合实践
  • 12 封装与构造方法
  • 从任务到挑战:重塑众包理念,构建激发群体智慧的系统方法论
  • Maven 入门+高深 jar 包冲突 167-171
  • 从聊天到执行:Claude Opus 4.8、GPT-5.5/Codex、Qwen3.7-Max、RAGFlow 0.25.6 热点盘点
  • 告别远程桌面!在Win10/11上优雅管理AD域控的保姆级教程(含RSAT工具安装与避坑)
  • 逆推思维:找到达成目标的最短路线
  • 精选 MBTI 测算小程序 趣味专业人格测试工具一览 - 软件工具教程方法
  • 猫抓Cat-Catch:浏览器资源嗅探扩展的终极技术指南与深度解析
  • 乌鲁木齐市头屯河区救护车转运服务官方指定靠谱机构排名,救护车转运服务联系电话是多少? - 金诚回收
  • 5分钟快速清理微信单向好友:WechatRealFriends免费工具终极指南
  • 跨领域创意电路设计:从需求分析到系统集成的全流程实践
  • 技术故障沟通:从粉饰到坦诚的运维文化转型