ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Python的零件表面缺陷检测源码:从环境搭建到迁移学习实战

基于Python的零件表面缺陷检测源码:从环境搭建到迁移学习实战 简介这份资源面向计算机、人工智能、自动化等专业的在校学生、教师及企业开发者提供一套基于Python实现的工具零件表面高精度缺陷检测源码可用于毕业设计、课程设计、项目立项演示或算法进阶学习。压缩包共8个文件约10KB以3个Python脚本为核心分别承担模型训练与测试推理任务另含requirements.txt依赖清单、setup.py与setup.cfg打包配置、MANIFEST.in清单及.gitignore版本管理文件结构精简、便于快速部署与二次开发。项目代码均经测试运行成功后才上传功能完整可用适合基础尚可的读者在此基础上修改扩展实现更多检测功能。目前已有386人学习关注可作为缺陷检测方向入门与实战借鉴的轻量参考。1. 从一堆零件照片到可复现的缺陷检测这套 Python 源码到底能干什么工厂质检线上一个轴承套圈从相机下经过表面有没有划痕、凹坑、锈斑靠人眼盯着屏幕看一天下来眼睛发花漏检率还压不住。这套「基于 Python 实现的各种工具零件表面高精度缺陷检测源码」要解决的就是把这个判断过程交给模型输入一张零件表面图输出它是否合格、缺陷落在哪个区域。压缩包里给的不是一篇论文而是一套能跑起来的工程骨架——train.py、test.py、setup.py、requirements.txt、setup.cfg、MANIFEST.in、.gitignore、save-loss.txt从环境声明到训练入口到测试脚本都在适合计算机、人工智能、自动化方向的在校学生做毕设或课程设计也适合刚转进工业视觉方向的工程师拿来当第一个可改的基线。它不承诺你下载完就 SOTA但它把「数据怎么进、模型怎么训、指标怎么存、结果怎么测」这条链路铺平了你缺的是自己的零件图和调参耐心。2. 拆开压缩包先看结构train.py 与 test.py 的分工逻辑2.1 文件清单背后的工程约定拿到一个源码包我习惯先不急着pip install而是把目录树和每个文件的职责过一遍。这套资源的文件构成很典型属于「最小可运行工程」的配置文件作用你需要关注的点train.py训练主入口数据加载、模型定义、损失、优化器、epoch 循环都在这test.py推理/评估入口加载权重、跑验证集、输出指标或可视化requirements.txt依赖声明决定你装哪个版本的 torch、opencvsetup.pysetup.cfg打包配置说明它按可安装包组织不是随手脚本MANIFEST.in打包附带文件声明影响非 .py 资源是否被打进去save-loss.txt训练损失记录用来判断训练有没有收敛、有没有震荡.gitignore版本忽略侧面反映作者本地跑过哪些产物save-loss.txt这个文件值得单独说一句。很多学生交上来的代码只有.py训练过程全靠print跑完什么都不剩。这里作者把 loss 落盘成文本意味着你可以拿它画曲线、对比不同超参下的收敛速度。常见做法是用它配合 matplotlib 画 train loss 曲线判断是否过拟合。2.2 训练脚本的典型骨架与参数落点train.py是整套代码的心脏。工业缺陷检测的训练循环结构上和通用图像分类大同小异差别在数据增强策略和类别不平衡处理。下面是我按这类工程常见写法还原的骨架你对照自己的train.py看结构是否一致import torch import torch.nn as nn from torch.utils.data import DataLoader from dataset import DefectDataset # 数据加载类按实际文件名替换 from model import DefectNet # 模型定义按实际文件名替换 # 超参集中管理方便复现 EPOCHS 50 BATCH_SIZE 16 LR 1e-3 DEVICE torch.device(cuda if torch.cuda.is_available() else cpu) train_set DefectDataset(rootdata/train, modetrain) val_set DefectDataset(rootdata/val, modeval) train_loader DataLoader(train_set, batch_sizeBATCH_SIZE, shuffleTrue, num_workers4) val_loader DataLoader(val_set, batch_sizeBATCH_SIZE, shuffleFalse, num_workers4) model DefectNet(num_classes2).to(DEVICE) criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lrLR) with open(save-loss.txt, a) as f: for epoch in range(EPOCHS): model.train() running_loss 0.0 for imgs, labels in train_loader: imgs, labels imgs.to(DEVICE), labels.to(DEVICE) optimizer.zero_grad() outputs model(imgs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() avg_loss running_loss / len(train_loader) f.write(fepoch{epoch}, loss{avg_loss:.6f}\n) # 落盘供后续画曲线 print(fepoch {epoch} loss {avg_loss:.4f})逻辑说明DefectDataset负责把零件图读进来并做增强DefectNet是网络主体训练循环把每个 batch 的 loss 累加后求平均写进save-loss.txt。参数说明BATCH_SIZE受显存限制工业图分辨率高时通常只能开到 8 或 16LR用 1e-3 是 Adam 的常规起点若 loss 震荡就降到 1e-4num_workers在 Windows 上设 0 更稳Linux 上设 4 能提速。save-loss.txt用追加模式a多次训练会累积想干净对比就每次训练前清空或改名。2.3 测试脚本怎么读指标test.py的职责是加载训练好的权重在验证集或测试集上跑一遍输出准确率、混淆矩阵或缺陷区域可视化。工业场景里单纯看准确率会被类别不平衡骗——如果 95% 的零件都是合格品模型全判合格也有 95% 准确率但漏检的缺陷件才是要命的。所以看test.py时重点确认它有没有输出召回率Recall和精确率Precision尤其是缺陷类的召回。常见做法是加一段from sklearn.metrics import classification_report # 收集所有预测和标签后 print(classification_report(all_labels, all_preds, target_names[ok, defect]))这样你能看到缺陷类的召回是多少。如果缺陷召回低于 0.9说明漏检严重得回头查数据增强够不够、正负样本比例是否失衡。3. 环境搭建与依赖安装requirements.txt 里的版本坑3.1 用虚拟环境隔离别污染全局这类源码包最容易翻车的地方不是模型是环境。requirements.txt里如果写的是torch、opencv-python这种不带版本号的依赖你直接pip install -r很可能装到最新版而最新版和作者当时的 API 对不上报错报到怀疑人生。血泪经验是先建虚拟环境再装依赖。# 创建并激活虚拟环境Windows 与 Linux 命令不同 python -m venv venv # Windows venv\Scripts\activate # Linux / macOS source venv/bin/activate # 升级 pip 后安装依赖 python -m pip install --upgrade pip pip install -r requirements.txt逻辑说明虚拟环境把项目依赖和系统 Python 隔开避免不同项目互相打架。参数说明python -m venv venv里的第二个venv是目录名可以改成.venv。如果requirements.txt没锁版本装完后用pip freeze requirements-lock.txt把实际版本记下来下次复现就稳了。3.2 版本对齐torch 与 CUDA 的匹配深度学习项目最玄学的一环就是 torch 和显卡驱动的匹配。requirements.txt里如果只写torchpip 默认装 CPU 版或和你的 CUDA 不匹配的版本。正确做法是先确认显卡驱动支持的 CUDA 版本再去装对应 wheel。# 查看显卡和驱动支持的 CUDA 版本 nvidia-smi # 按官方索引装指定 CUDA 版本的 torch示例按实际版本替换 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118逻辑说明nvidia-smi右上角显示的 CUDA Version 是驱动支持的上限装 torch 时不能超过它。参数说明cu118代表 CUDA 11.8换成cu121就是 12.1。装完在 Python 里跑import torch; print(torch.cuda.is_available())返回True才算成功。如果返回False要么是装了 CPU 版要么是驱动太旧别急着改代码先解决环境。3.3 opencv 与图像读取的细节缺陷检测离不开图像处理opencv-python几乎是标配。注意两个点一是opencv-python和opencv-contrib-python别同时装会冲突二是 OpenCV 读进来是 BGR 通道而 torchvision 的 transforms 和预训练模型通常按 RGB 处理通道顺序错了模型精度会莫名其妙下降。import cv2 img cv2.imread(part_001.jpg) # 默认 BGR img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转 RGB 再送模型逻辑说明cv2.imread第二个参数默认是IMREAD_COLOR读成三通道 BGR。参数说明如果图是灰度缺陷图用cv2.IMREAD_GRAYSCALE读成单通道再在 dataset 里expand成三通道喂给预训练网络。这一步不做模型看到的颜色是反的训练 loss 可能降得很慢属于典型的隐性坑。4. 数据组织与训练调参让 save-loss.txt 真正有用4.1 数据集目录怎么摆源码里的DefectDataset通常按ImageFolder风格组织也就是按类别分文件夹。工业零件缺陷检测常见两类合格ok和缺陷defect缺陷里还可能细分划痕、凹坑、锈斑。目录结构建议这样data/ ├── train/ │ ├── ok/ │ └── defect/ └── val/ ├── ok/ └── defect/逻辑说明ImageFolder会自动按子文件夹名生成类别标签省去手写 label 映射。参数说明train 和 val 的类别文件夹名必须完全一致否则标签对不上。如果缺陷类型多可以按defect_scratch、defect_pit细分但类别越多每类样本越少小样本类别容易训崩新手建议先做二分类跑通再细分。4.2 数据增强工业图的增强不能照搬自然图像自然图像分类常用的随机裁剪、翻转、色彩抖动放到工业缺陷图上要谨慎。零件表面的划痕是有方向性的水平翻转可能把一条真实划痕变成不存在的方向色彩抖动可能把锈斑的颜色特征抹掉。我一般会这样配增强from torchvision import transforms train_tf transforms.Compose([ transforms.Resize((256, 256)), transforms.RandomHorizontalFlip(p0.3), # 降低概率缺陷有方向性 transforms.RandomRotation(10), # 小角度旋转模拟摆放偏差 transforms.ToTensor(), transforms.Normalize(mean[0.5]*3, std[0.5]*3), ])逻辑说明Resize统一尺寸RandomHorizontalFlip概率压到 0.3 减少方向性破坏RandomRotation限制在 10 度内。参数说明Normalize的均值和方差如果用的是预训练模型要换成 ImageNet 的mean[0.485,0.456,0.406]、std[0.229,0.224,0.225]否则预训练权重的优势发挥不出来。这一步是很多新手忽略的导致微调效果还不如从头训。4.3 用 save-loss.txt 判断收敛与过拟合训练跑起来后save-loss.txt就是你的黑匣子。把它读进来画曲线比盯着终端刷屏靠谱得多。import matplotlib.pyplot as plt epochs, losses [], [] with open(save-loss.txt) as f: for line in f: parts dict(p.split() for p in line.strip().split(, )) epochs.append(int(parts[epoch])) losses.append(float(parts[loss])) plt.plot(epochs, losses) plt.xlabel(epoch); plt.ylabel(loss); plt.title(train loss) plt.savefig(loss_curve.png)逻辑说明逐行解析epochx, lossy格式画成曲线。参数说明如果 loss 前期快速下降后长期平躺说明收敛了可以停如果 loss 上下剧烈震荡多半是学习率太大或 batch size 太小如果 train loss 一直降但验证指标变差就是过拟合该加数据或加正则。save-loss.txt只记了 train loss严谨做法是在训练循环里同时算 val loss 一起落盘两条曲线对比才看得出过拟合。5. 避坑与排查这套源码最容易卡住的五个地方5.1 现象运行 train.py 报 ModuleNotFoundError原因requirements.txt没装全或者你用的 Python 解释器和虚拟环境不是同一个。VS Code 里尤其常见右下角解释器还指着系统 Python。解决确认虚拟环境已激活pip list看依赖在不在VS Code 里CtrlShiftP选Python: Select Interpreter指到venv里的 python。装依赖时如果某个包编译失败优先找有没有预编译 wheel别硬编译。5.2 现象loss 一直是 nan 或者不下降原因学习率太大、输入没归一化、标签越界或者数据里有损坏图片。工业数据集常混进读不出来的图cv2.imread返回None送进网络就炸。解决先把学习率降到 1e-4 试检查Normalize有没有加在 dataset 的__getitem__里加一句if img is None: return self.__getitem__((idx1) % len(self))跳过坏图。nan 出现时用torch.autograd.set_detect_anomaly(True)定位是哪一层出的问题。5.3 现象显存不够CUDA out of memory原因工业图分辨率高batch size 开太大或者没释放中间变量。解决先把BATCH_SIZE降到 4 或 2用torch.cuda.empty_cache()清理缓存训练循环里用with torch.no_grad()包住验证部分。如果还不行把输入尺寸从 512 降到 256精度会掉一点但能跑起来先跑通再优化。5.4 现象测试准确率很高但实际漏检严重原因正负样本极度不平衡模型学会了全判合格。这是工业缺陷检测最典型的翻车方式。解决看test.py有没有输出缺陷类召回率没有就自己加classification_report训练时给缺陷类加权nn.CrossEntropyLoss(weighttorch.tensor([1.0, 5.0]))或者用重采样让每个 batch 里缺陷样本占比不低于三成。5.5 现象换了自己的数据集后 test.py 报维度不匹配原因模型最后一层全连接输出类别数写死成 2你的数据集类别数不一样或者输入通道数对不上灰度图 vs 三通道。解决找到模型定义里num_classes参数改成你的类别数灰度图在 dataset 里img img.repeat(3,1,1)扩成三通道。改完重新训练别拿旧权重直接测。6. 从跑通到改出自己东西迁移学习与指标验证的实操跑通原版只是起点真正让这套源码为你所用是把它改成能检测你自己零件的东西。最省力的路径是迁移学习拿 ImageNet 预训练的主干网络换掉最后的分类头用你自己的数据微调。下面是我常用的改法以 ResNet 为例import torch.nn as nn from torchvision import models def build_model(num_classes2, freeze_backboneTrue): model models.resnet18(weightsmodels.ResNet18_Weights.IMAGENET1K_V1) if freeze_backbone: for p in model.parameters(): p.requires_grad False # 冻结主干只训分类头 model.fc nn.Linear(model.fc.in_features, num_classes) # 换头 return model逻辑说明weights...IMAGENET1K_V1加载预训练权重freeze_backbone控制是否冻结主干。参数说明数据量少于一千张时先冻结主干只训分类头训几个 epoch 后再解冻全部微调学习率调小到 1e-4数据量上万张可以直接全量微调。num_classes按你的缺陷类别数改二分类就是 2。改完模型验证环节不能只看一个准确率数字。我一般会强制走一遍这套检查先看混淆矩阵确认缺陷类有没有被大量误判成合格再看缺陷类召回率低于 0.9 就不交付最后拿几张训练集里没出现过的真实零件图做盲测看模型在没见过的样本上稳不稳。这一步是后悔药——等上线了才发现漏检回头查数据分布就晚了。还有一个容易被忽略的技巧把test.py的输出从单纯打印指标改成同时保存缺陷区域的可视化图。做法是把模型预测为缺陷的图叠加一个热力图或框存到output/目录。质检场景里光告诉工人「这张不合格」没用得告诉他「缺陷在这」人家才信你。常见做法是用 Grad-CAM 生成热力图或者简单点把原图和预测标签一起存成对比图。这样你拿去答辩或者给产线看说服力完全不一样。从那以后我每次拿到一个新的缺陷检测源码包都强制先跑通原版、确认save-loss.txt有正常曲线、再用自己的小数据集替换跑一遍三步都过了才敢动模型结构。这套流程帮我省下过无数次「改了半天发现是环境问题」的时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表