ARTICLE DETAIL

资讯详情

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

基于MATLAB的齿轮缺陷检测:从图像预处理到SVM分类实战

基于MATLAB的齿轮缺陷检测:从图像预处理到SVM分类实战 简介本资源是一套基于MATLAB实现的齿轮表面缺陷检测完整方案面向机械工程、自动化及图像处理方向的科研人员、高校师生与工业检测工程师解决齿轮在长期运行中因磨损、裂纹、点蚀等引发的安全隐患问题。压缩包共120个文件含73张JPG格式原始/处理后齿轮图像用于算法验证与效果对比、17个MATLAB脚本文件如regionmain.m、main1regiongrow.m实现区域生长与边缘检测核心逻辑、5张PNG图、3份TXT说明文档含readMe.txt使用指南、1个TIFF高保真图像及1个FIG图形界面文件整体大小为47.18MB。资源已获48人学习下载提供从图像采集、滤波增强、缺陷定位到结果可视化的一站式代码实现所有脚本均可直接运行配套示例图像覆盖多种典型缺陷形态便于理解算法流程、调试参数并迁移至实际产线检测场景。 去年做齿轮缺陷检测项目时我把整套识别流程用 MATLAB 从零搭了起来。产线上的齿轮主要靠人工目检效率低、漏检率高尤其是微小裂纹和齿面磨损老师傅看久了也容易眼花。我的目标很明确用 MATLAB 写一套能自动识别崩齿、裂纹、磨损等缺陷的代码并且数据集、脚本、标注文件全部整理好别人拿到手能直接跑。目前这套代码在实测数据上的准确率在 94% 左右足够支撑课程设计和投标演示。这篇博文就把数据怎么准备、代码怎么组织、参数怎么调、坑怎么避全部拆开讲清楚。不管你是正在做 MATLAB 图像处理大作业还是准备齿轮故障诊断方向的研究都可以按下面的流程走一遍。1. 项目整体设计与思路拆解1.1 先想清楚检测什么缺陷用什么路线这套系统首先需要明确检测目标。齿轮的失效模式很多但不是所有缺陷都适合用视觉检测。我根据实际产线需求把主要目标锁定在四类正常、崩齿缺齿、齿面裂纹、齿面磨损/点蚀。崩齿和缺齿是最容易通过轮廓判断的裂纹需要看边缘和纹理磨损和点蚀则需要灰度分布和纹理特征来识别。技术路线的选择直接决定项目工作量。常见的方案有三类基于振动信号、基于图像、基于声发射。振动信号适合检测早期微弱故障但需要在齿轮箱上安装加速度传感器而且要处理复杂的时频信号对于“拿到代码和数据就能复现”这个目标来说门槛偏高声发射设备更贵一般不作为首选。图像方案的优势在于直观、结果可视化强用普通工业相机甚至高分辨率手机就能采集数据而且 MATLAB 的图像处理工具箱非常成熟适合快速验证。所以我最终选定基于图像的视觉检测方案这也是目前工业机器视觉质检的主流思路。在图像方案内部又有两个分支传统图像处理机器学习分类以及端到端的深度学习。传统方法的好处是可解释性强、标注量小每类 50~100 张图就能训练一个不错的 SVM 分类器代码在普通电脑上跑得飞快深度学习方法精度上限更高尤其适合表面缺陷形态复杂、传统特征难以描述的场合但需要更多数据和算力。我的建议是先用传统方法把完整流程跑通把预处理、特征工程、分类评估这些环节摸透再根据效果决定是否用深度学习做升级。这篇博文以传统方法为主线第三节末尾会补充深度学习的迁移学习代码。1.2 系统整体框架与代码模块划分代码组织上我没有把几百行逻辑全堆在一个脚本里而是拆成按功能划分的模块。这样做的好处很明显数据变了只改数据加载部分算法要替换只动特征提取模块跑实验时不用反复复制粘贴代码。最终的目录结构大致如下gear_defect_detection/ ├── data/ │ ├── raw/ # 原始图像按类别分文件夹 │ ├── augmented/ # 增强后的图像 │ └── split/ # 划分后的训练/验证/测试集 ├── features/ # 提取的特征 .mat 文件 ├── models/ # 训练好的分类器模型 .mat ├── scripts/ │ ├── 1_preprocess.m # 预处理 │ ├── 2_extract_features.m # 特征提取 │ ├── 3_train_model.m # 模型训练与验证 │ ├── 4_predict_demo.m # 单张图片测试与可视化 │ └── utils/ # 公共函数 └── README.md主流程是脚本1读取原始图像做预处理后生成二值图和增强图脚本2遍历所有图像提取特征向量并保存成表格脚本3用这些特征训练分类器输出交叉验证准确率和混淆矩阵脚本4加载新图片走完预处理-特征提取-分类全流程最后在图上把缺陷区域框出来。四个脚本顺序执行每个步骤的中间结果都有文件落盘调试时可以直接跳着跑。1.3 为什么选 MATLAB 而不是 Python/OpenCV很多朋友问我这种视觉检测用 Python 加 OpenCV 不是更主流吗确实Python 生态很强大YOLO 系列模型、HuggingFace 这些资源都在 Python 侧。但我选 MATLAB 有自己的理由先说场景这类项目通常是课程设计、毕设或者企业预研要求的是快速出原型、方便演示、代码整洁度高。MATLAB 的 Image Processing Toolbox 把读图、滤波、形态学、区域分析这些高频操作封装成一行函数开发速度非常快。其次是调试体验MATLAB 的工作区可以直接看变量图像矩阵能可视化变量名即文档这在调试图像处理算法时太舒服了。最后是部署虽然 MATLAB 程序需要运行时环境但用 MATLAB Compiler 可以打包成独立 exe产线工控机上装个运行时就能跑这对大多数视觉项目足够了。当然 MATLAB 的短板也明显深度学习训练速度不如 Python 生态、开源模型迁移成本高、商业授权贵。所以如果你要训练大型目标检测模型或者要上像 YOLOv8 这种社区模型建议用 Python但如果你的核心需求是尽快把传统视觉检测流程跑通、演示效果好MATLAB 完全够用。后面我写的内容就是基于 MATLAB但思想可以直接迁移到 OpenCV。2. 数据集的准备与处理“数据齐全”的关键2.1 数据采集与扩充策略“数据齐全”是这个项目的核心卖点。一开始我手上只有工人随手拍的几十张零件图光线忽明忽暗角度也不统一跑出来的结果非常不稳定。后来学乖了固定拍摄条件用工业相机配合环形光源在暗箱里拍摄齿轮轴线与相机光轴垂直每类样品至少拍 80 张分辨率统一缩放到 512x512 灰度图。数据扩充是必须做的尤其是深度学习模型没有足够样本很容易过拟合。传统方法虽然数据要求低但扩充后鲁棒性也会明显提升。我用 MATLAB 做了一系列在线和离线增强包括旋转旋转角度 ±15 度模拟齿安装角度的变化用 imrotate平移上下左右移动 10~20 像素模拟定位误差用 imtranslate缩放0.9~1.1 倍模拟工作距离波动用 imresize噪声添加高斯噪声和椒盐噪声模拟传感器噪声用 imnoise亮度变化调整 gamma 值模拟光照波动。需要注意增强只能对训练集做验证集和测试集要保持原始图像否则会高估模型性能。扩增后每类达到 150~200 张对传统分类器来说已经非常充足。2.2 标注与数据目录组织如果做分类任务最简单的标注方式就是用文件夹名作为标签data/raw/Normal 放正常齿轮data/raw/Crack 放裂纹样本。MATLAB 的 imageDatastore 会自动根据文件夹名生成标签非常方便。目录结构如下data/raw/ ├── Normal/ # 正常齿面 ├── Chipped/ # 崩齿/缺齿 ├── Crack/ # 齿面裂纹 └── Wear/ # 磨损/点蚀如果需要做目标检测要框出缺陷的具体位置可以用 MATLAB 自带的 imageLabeler 导入图片画矩形框然后导出 groundTruth 对象。标注文件可以保存为 .mat 或者 .csv后续用于训练检测网络。我的经验是分类任务先跑通流程再考虑检测框检测框的标注工作量是分类的十几倍不要一上来就陷入标注地狱。2.3 数据划分与类别不平衡处理数据划分我用 splitEachLabel 函数它按标签比例把数据分为训练、验证、测试三部分。代码示例imds imageDatastore(data/raw, IncludeSubfolders, true, LabelSource, foldernames); [imdsTrain, imdsValid, imdsTest] splitEachLabel(imds, 0.7, 0.15, 0.15, randomized);还要统计每个类别数量处理不平衡。如果某类只有二三十张而其他类有几百张可以用三种策略一是对少数类做更激进的数据增强把它补到近似数量二是在训练分类器时设置类别权重让少数类错分代价更高三是用分层抽样保证每个批次里各类都有样本。实际项目中我优先选第一种因为数据扩充对视觉任务几乎总是有效的。3. 核心代码实现与算法细节3.1 图像预处理流程让齿轮和背景干净分离预处理的目的是把齿轮轮廓和缺陷区域从复杂背景中干净地分离出来。我的流程是灰度化 → 中值滤波 → 自适应二值化 → 形态学处理。灰度化直接读图时用 imread 得到 RGB再用 rgb2gray拍摄时如果用工业相机输出灰度图可以省一步。中值滤波用 medfilt2窗口大小 3x3 或 5x5主要去除椒盐噪声同时比均值滤波更好地保留边缘。因为后面的边缘检测和形态学操作很依赖边缘位置的准确性如果边缘糊了裂纹这种细长缺陷很容易被抹掉。二值化是关键。我用 imbinarize 的自适应阈值方法它跟固定阈值不同会根据局部灰度自动调整能显著改善光照不均匀带来的分割问题。核心代码imgGray rgb2gray(img); imgFilt medfilt2(imgGray, [3 3]); bw imbinarize(imgFilt, adaptive, Sensitivity, 0.4); bw bwareaopen(bw, 500); % 移除面积小于500像素的小区域 bw imclose(bw, strel(disk, 5)); % 闭合小缝隙 bw imfill(bw, holes); % 填充齿轮内部孔洞为什么用这些步骤bwareaopen 是去掉背景中的孤立噪点imclose 连接因为光照不均断开的小边缘imfill 把齿轮中心孔和齿间区域填成完整区域方便后续用 regionprops 分析轮齿。参数 Sensitivity 不是死的后面在第4章讲调参。除了常规预处理我还要做形状配准。因为齿轮在画面里可能有角度偏移而缺陷检测特征有些是位置敏感的比如裂纹出现在齿根还是齿顶。可以用 imrotate 手动把齿轮旋转到水平或者用 imregister 做更精确的配准。实际项目里由于我固定了拍摄夹具角度偏差很小直接在特征提取阶段用归一化特征比如轮廓的 Hu 矩来消除影响。3.2 缺陷特征提取从像素到数字预处理得到的二值图还只是图像分类器需要的是数值特征。我把特征分成三组区域形状特征、纹理特征、频域/HOG特征最后拼接成一个向量。区域形状特征用 regionprops 提取包括面积、周长、离心率、Solidity、Extent、欧拉数等。其中 Solidity 等于区域面积除以凸包面积正常齿轮齿面区域总是接近凸的崩齿区域的 Solidit 会明显下降Extent 等于区域面积除以边界框面积缺齿时也会异常。提取代码stats regionprops(bw, Area, Perimeter, Eccentricity, Solidity, Extent); featShape [stats.Area, stats.Perimeter, stats.Eccentricity, stats.Solidity, stats.Extent];纹理特征用灰度共生矩阵GLCM它是统计图像中灰度级之间的空间关系对磨损、点蚀这类表面纹理变化很敏感。MATLAB 用 graycomatrix 和 graycorprops 实现glcm graycomatrix(imgGray, Offset, [0 1; -1 1; -1 0; -1 -1], NumLevels, 64, Symmetric, true); statsGLCM graycoprops(glcm, {Contrast,Correlation,Energy,Homogeneity}); featTexture [mean(statsGLCM.Contrast), mean(statsGLCM.Correlation), ... mean(statsGLCM.Energy), mean(statsGLCM.Homogeneity)];频域特征这里我用了灰度图像的二维傅里叶变换功率谱的集中度以及 HOG 特征描述轮廓梯度方向。HOG 对齿轮这种有规律形状的目标效果很好特别是裂纹会产生局部的梯度突变。MATLAB 的 extractHOGFeatures 一行就能调用[featHOG, visHOG] extractHOGFeatures(imgGray, CellSize, [16 16]);最后把 featShape、featTexture、featHOG 拼起来放进一个循环里遍历所有图像保存成特征矩阵和标签向量。这里要提醒不同特征数量级差别很大HOG 维度可能有几百维SVM 对特征量级敏感训练前统一做 z-score 标准化。3.3 分类器训练与评估SVM为主配上混淆矩阵分类器我用多分类 SVM。MATLAB 里 fitcecoc 实现 One-Vs-One 多分类配合 RBF 核在小样本视觉任务上表现比较稳。训练代码load(features/train_features.mat); % XTrain, YTrain X zscore(XTrain); mdl fitcecoc(X, YTrain, Learners, svm, KFold, 5); accuracy 1 - kfoldLoss(mdl); disp([5折交叉验证准确率: , num2str(accuracy)]);还需要评估每个类别的精确率、召回率、F1。训练完成后在测试集上预测用 confusionchart 画混淆矩阵这是展示项目效果最直观的方式YPred predict(mdl, zscore(XTest)); cm confusionchart(YTest, YPred); cm.Title 齿轮缺陷分类混淆矩阵;SVM 调参主要看三个点核函数选择、BoxConstraint、标准化。线性核在特征维度高且样本不多时表现好RBF 核能处理非线性边界但容易过拟合BoxConstraint 越大越强调正确分类所有训练点越小越允许一定误分、泛化能力更强。我的经验是先用 RBF 核BoxConstraint 默认值 1 附近配合交叉验证选参数不要手动乱试。如果类别数量差别大在 fitcecoc 里设置 Prior 为 empirical让算法根据类别频率调整。3.4 深度学习方案迁移学习与目标检测补充传统方法的准确率到 94% 左右后就进入瓶颈这时候可以考虑深度学习。对分类任务最简单的做法是迁移学习用预训练的 ResNet18 或 VGG16 替换最后几层用我们的小数据集微调。MATLAB 代码框架net resnet18; lgraph layerGraph(net); newFc fullyConnectedLayer(4, Name, fc_new); newOut classificationLayer(Name, out_new); lgraph replaceLayer(lgraph, fc1000, newFc); lgraph replaceLayer(lgraph, ClassificationLayer_Predictions, newOut); augmenter imageDataAugmenter(RandRotation, [-10 10], RandXTranslation, [-10 10]); imdsTrainAug augmentedImageDatastore([224 224], imdsTrain, DataAugmentation, augmenter); options trainingOptions(sgdm, InitialLearnRate, 1e-4, MaxEpochs, 10, MiniBatchSize, 16, Plots, training-progress); trainedNet trainNetwork(imdsTrainAug, lgraph, options);注意 ResNet18 的输入尺寸是 224x224而我们的原始图是 512x512所以要用 augmentedImageDatastore 做尺寸调整。如果要做目标检测MATLAB 从 2021a 开始支持 YOLO v4 的 trainYOLOv4ObjectDetector但要求安装 Deep Learning Toolbox 和 Computer Vision Toolbox并且最好有 GPU。深度学习方案对数据量要求更高每类至少 200~500 张且标注框要准确否则模型学不到真正的缺陷模式。4. 实操过程与运行配置4.1 环境配置与工具箱依赖代码依赖的 MATLAB 工具箱主要有这几个Image Processing Toolbox读图、滤波、形态学、regionprops、HOGStatistics and Machine Learning Toolboxfitcecoc、fitcsvm、交叉验证Computer Vision Toolbox图像配准、目标检测相关函数Deep Learning Toolbox可选如果跑迁移学习和 YOLO。建议使用 R2020b 及以上版本太老的版本有些函数名和默认参数不一样。检查工具箱用 ver 命令ver(images); ver(stats); ver(vision);运行前把整个项目目录加入路径避免脚本找不到数据addpath(genpath(gear_defect_detection));4.2 从图像到检测结果的完整运行流程我把主控脚本设计成一个可展示的流水线。以一个测试样本为例完整流程是% 4_predict_demo.m img imread(data/split/test/Crack/001.bmp); % 1. 预处理 imgGray rgb2gray(img); imgFilt medfilt2(imgGray, [3 3]); bw imbinarize(imgFilt, adaptive, Sensitivity, 0.4); bw bwareaopen(bw, 500); bw imclose(bw, strel(disk, 5)); bw imfill(bw, holes); % 2. 提取特征 feat extractFeatVec(imgGray, bw); % 自定义函数内部调用 regionprops/graycomatrix/HOG % 3. 预测 load(models/svmModel.mat, mdl); featureStd zscore(feat); label predict(mdl, featureStd); % 4. 可视化 imshow(img); title(char(label)); % 显示缺陷区域 if ~strcmp(label, Normal) [B, ~] bwboundaries(bw); hold on; for k 1:length(B) plot(B{k}(:,2), B{k}(:,1), r, LineWidth, 2); end hold off; end我建议在脚本里加一个参数控制是否保存中间结果比如用 imwrite 把二值图写出来方便检查预处理效果。实际跑的时候一张 512x512 图像从读到出结果大约 0.3 秒CPU 上就能完成完全满足演示需求。4.3 参数调优与结果分析参数调优在整个项目中花的精力最多。首先是 imbinarize 的 Sensitivity 参数。Sensitivity 越大越容易把低对比度的目标判定为前景但噪声也会增多。我测试了 0.2 到 0.6 之间的一串值发现 0.4 在裂纹样本上效果最好既保住了细小裂纹又不至于把背景噪点当成齿轮。可以用一个 for 循环批量测试 Sensitivity对比每张图的分割质量不要用肉眼一直猜。其次是特征选择。一开始我把所有特征全塞进去HOG 默认参数维度接近 1800 维加上形状和纹理特征训练集准确率接近 100%测试集却只有 80% 左右典型的过拟合。后来我用交叉验证比较不同特征组合发现只用 “Solidity、Extent、GLCM 对比度、GLCM 能量、HOG” 五个特征就能达到 93% 的准确率比全特征更好。特征不是越多越好关键是跟缺陷类型强相关。最终实测结果正常齿轮识别准确率 98%崩齿 96%裂纹 91%磨损 89%总体加权准确率 94%。需要说明的是这个结果是在固定光照、固定角度下测得的如果换拍摄环境需要重新做数据增强和参数微调。5. 常见问题与排查技巧实录5.1 二值化后齿轮与背景粘连这是最常碰到的问题。现象是 imbinarize 之后齿轮和背景连成一片区域分析阶段根本分不清哪个是齿轮哪个是背景。原因通常是光照不均匀或者背景里有反光。解决方法有几个一是改善拍摄环境使用背光照明让齿轮轮廓形成剪影这是治本二是用形态学顶帽变换 imtophat 去掉背景光照起伏三是先用边缘检测拿到齿轮外轮廓再用 imfill 填充成完整区域。我的建议是优先从拍摄端解决算法只是补救。5.2 特征维度太高导致过拟合特征维度爆炸在 HOG 上尤其明显。我试过把 CellSize 设成 8x8HOG 特征维度直接到 7000 多模型在训练集上表现很好测试集一塌糊涂。解决办法一是调大 CellSize比如 16x16 或者 32x32二是先用 PCA 降维把特征降到 50~100 维再训练三是用带正则化的分类器比如 fitclinear。我的经验是CellSize 16x16 就足够表达齿轮这种结构件维度不高效果也好。5.3 深度学习训练时内存不足或速度慢如果跑到 trainNetwork 时报 Out of Memory优先级最高的调整是减小 MiniBatchSize从 32 降到 8 或 4其次是减小输入图像尺寸ResNet18 的 224x224 已经够用不需要把原始图传进去第三是打开 ExecutionEnvironment 为 auto 让 MATLAB 自动识别 GPU。没有 GPU 也能跑只是慢建议先把代码在小数据集上验证通过后再上全量训练。5.4 标注和类别不平衡的坑手动标注 500 张图非常耗时我的办法是先用传统的区域分割自动生成候选框再进 imageLabeler 人工修正能省一半时间。类别不平衡方面如果正常齿轮样本特别多缺陷样本少训练出的模型会倾向预测为正常漏检率很高。我最后用了一个简单但有效的策略把缺陷样本做高频增强并且在 fitcecoc 里设置 Prior 为 empirical让少数类的重要性提高。我把这些典型问题整理成了速查表问题现象可能原因推荐解法齿轮与背景粘连光照不均匀、反光背光照明、imtophat、边缘检测填充测试准确率远低于训练特征维度过高、过拟合PCA降维、调大HOG CellSize、使用正则化深度学习OOMMiniBatchSize过大、图像过大减小Batch、缩小输入、使用GPU缺陷样本被漏检类别不平衡数据扩充、设置类别权重、提高Sensitivity崩齿能检出但裂纹总是漏裂纹对比度低、二值化阈值过高降低Sensitivity、用Canny边缘检测辅助做这个项目最大的收获是理解了“数据比算法重要”这句话的分量。刚开始只有几十张图怎么调参数都差一口气后来把数据补齐固定光照加了增强同样的分类器准确率直接从 85% 跳到 94%。如果你也要做类似的项目我的建议是不要一上来就上深度学习先用传统图像处理把流程跑通把分割和特征工程做扎实让结果可视化出来再考虑用 CNN 或者 YOLO 升级。最后分享一个小技巧每次跑完测试把所有分类错误的样本单独复制到一个文件夹里逐个翻一遍。你会发现错误样本往往集中在某几种光照条件或拍摄角度上这比盲目的调参高效得多也正好指导下一步的数据扩充方向。本文还有配套的精品资源点击获取
返回列表