news 2026/9/11 18:25:42

基于形态学处理的齿轮缺陷缺口检测MATLAB仿真

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于形态学处理的齿轮缺陷缺口检测MATLAB仿真

简介:面向本硕博及科研人员的齿轮缺陷缺口检测仿真资源包,基于形态学处理与MATLAB实现,适合学习图像形态学在工业缺陷检测中的应用。资源围绕齿轮缺口检测算法展开,涵盖形态学操作、边缘提取与缺口定位等关键流程,能够帮助读者理解从图像预处理到缺陷判别的完整思路,并可直接运行Runme_.m文件复现检测结果。压缩包共四个文件,大小约442KB,内含MATLAB主程序、测试图片、操作录像与说明文档,录像演示了从环境设置到结果输出的完整过程,可有效避免子函数误运行、路径错误等常见问题。该资源目前已有530人学习,配有可视化示例与代码注释,适合本硕博教研学习与算法复现时参考,是入门图像形态学缺陷检测的实用素材。形态学操作与缺口标记部分尤其适合作为课程设计或毕业设计的参考基线。

1. 形态学处理解决的不是“找缺口”,而是先定义什么是齿轮

拿到一批齿轮毛坯图像,第一反应通常是灰度差分:缺了个口的地方灰度跳变明显,直接找边缘不就行了。实际跑一次会发现,光照从不同方向打过来,同一个缺口可能跨过 5 到 8 个像素的过渡带;齿面的加工纹理、油污、氧化色都在边缘上制造假突变。这时候再回头看形态学处理,它的价值不在“找出差异”,而在把图像还原成几何模型——齿轮就是若干个等间距凸起的圆盘,所有不符合这个模型的区域都算可疑缺陷。

基于形态学处理的齿轮缺陷缺口检测 matlab 仿真,本质是把问题拆成两步:先用开闭运算把二值图形状规整化,再通过连通域属性和径向轮廓判缺齿、缺口和局部缺料。这套流程不需要深度学习和标注样本,一张中等分辨率图片配一台普通 PC 就能跑出可解释的量化结果,适合非标质检设备的前期验证,也适合刚开始接触 matlab 图像处理的人建立完整的形态学分析思路。本文给出的所有代码基于 R2020a 及以上版本,只用到 Image Processing Toolbox,不依赖 Simulink 和额外工具箱。

2. 齿轮缺陷缺口检测的原理拆分:二值化、结构元素与连通域判定

2.1 为什么先做形态学而不是直接找边缘

像素级边缘检测对每一个灰度突起都敏感,齿轮表面的磨削纹路会形成几十条弱边缘,缺口的边缘往往混在其中。形态学的核心假设是:齿轮是“已知形状”,缺口是“偏离形状”,而不是“灰度变化”。基于这个假设,处理流程会先把灰度图变成干净的二值图,再做一次形状规整。规整的力度要精心控制:开运算去掉齿轮表面孤立亮点和毛刺,闭运算把齿根阴影造成的断裂桥接起来。两者交替操作,相当于给二值图做一次低通滤波——滤掉的是小于结构元素的几何细节,保留的是齿轮整体形状。

从这个角度看,结构元素是整套方案里最关键的旋钮。针对齿轮这种近似圆形对称的零件,常用disk结构元素,因为它不偏向任何方向。以下代码演示最基础的操作序列:

img = imread('gear_sample.png'); if size(img, 3) == 3 img = rgb2gray(img); end % 自适应阈值,光照不均匀时比全局阈值更稳 bw = imbinarize(img, 'adaptive'); bw = ~bw; % 齿轮区域置为前景 se = strel('disk', 3); bw = imclose(bw, se); % 先闭合断裂的齿根 bw = imopen(bw, se); % 再去除毛刺和孤立点

这里imclose在前、imopen在后是有意安排的:齿轮图像的断裂通常发生在齿根和齿谷附近,先闭运算恢复连续轮廓;随后开运算只清除残留在齿面上的小亮点,不会破坏刚恢复的大轮廓。disk半径 3 表示结构元素直径 7 像素,对 640×480 图像是适中值。如果齿轮占图比例很小,这个半径会显得过大,容易把小缺口直接填平;如果图像分辨率更高,则需要相应放大,否则过滤不掉纹理。

2.2 区域属性如何区分“好的齿轮”和“坏的齿轮”

二值化加形态学处理后,判断缺陷的重任交给regionprops。区域属性度量的是面积、周长、形状复杂度这类几何量,它们对光照不敏感,对形态学处理后的轮廓比较稳定。齿轮检测中常用四个属性:

属性含义对齿轮缺陷的指向性
Area前景像素总数缺一大块时面积显著下降
FilledArea填充孔洞后的面积齿根断裂会产生孔洞,填充面积差值变大
Solidity面积 / 凸包面积缺齿使凸包外扩,Solidity 明显降低
Eccentricity区域离心率齿轮接近圆形,值应接近 0,异常缺口会拉大偏心

正常齿轮的 Solidity 一般在 0.75 到 0.88 之间,齿数越多齿越细,Solidity 越低。如果检测结果显著偏离正常范围,就要引起注意。以下代码在形态学处理后提取最大连通域,并计算上述属性:

cc = bwconncomp(bw); stats = regionprops(cc, 'Area', 'FilledArea', ... 'Solidity', 'Eccentricity', 'BoundingBox'); % 齿轮是图像中最大的连通域 [~, idx] = max([stats.Area]); gearStats = stats(idx); fprintf('Area = %d, FilledArea = %d\n', ... gearStats.Area, gearStats.FilledArea); fprintf('Solidity = %.3f, Eccentricity = %.3f\n', ... gearStats.Solidity, gearStats.Eccentricity);

这段代码的价值在于把“肉眼看不出来”变成可量化指标。一个缺失宽度只占齿宽三分之一的微小缺口,面积变化可能不到 2%,肉眼几乎无法察觉;但 Solidify 局部形状已经出现变化,再配合径向距离分析就能锁定位置。后面第 5 章会重点讲径向距离法,这里先用区域属性做粗筛。

2.3 形态学流程对照表:每种操作解决哪一类假象

把形态学操作细分成下表,可以避免盲目试参数。实际调参时先判断图像质量属于哪一类问题,再选择对应操作,不要四五个strel叠在一起。

图像现象形态学操作结构元素建议
齿面亮斑、金属反光点开运算disk, r=2~4
齿根断裂、齿谷桥接中断闭运算disk, r=3~5
齿轮与背景粘连、细长伪影开运算后再取最大连通域disk, r=5~8
齿轮边缘锯齿状闭运算后接开运算disk, r=2~3

注意,开闭运算都是非线性滤波,执行顺序对结果影响很大。先开后闭会保留断裂特征,适合检测裂纹类缺陷;先闭后开适合恢复轮廓整体形状,也就是齿轮缺齿检测的默认选择。若图像中有大量碎屑,应在形态学处理后追加bwareaopen(bw, 200)把小于 200 像素的连通域直接移除,避免它们干扰最大连通域统计。

3. 基于形态学处理的齿轮缺陷缺口检测 MATLAB 最小实现

3.1 完整流程脚本:从读图到缺陷标注

下面给出可以在本地直接运行的完整 matlab 仿真脚本。它读入gear_sample.png,输出三张图:原始灰度图、形态学处理后的二值图、缺陷区域标注图。整套流程覆盖灰度化、二值化、形态学规整、连通域筛选和缺陷标记五个阶段。

% gear_defect_detection.m close all; clear; clc; img = imread('gear_sample.png'); if size(img, 3) == 3 img = rgb2gray(img); end % ------------------ 1. 二值化 ------------------ % 自适应阈值适合光照不均场景;BackgroundPolarity 指定齿轮 vs 背景关系 bw = imbinarize(img, 'adaptive', 'ForegroundPolarity', 'dark', ... 'Sensitivity', 0.6); % ------------------ 2. 形态学规整 ------------------ bw = bwareaopen(bw, 300); % 去掉小噪点 bw = imclose(bw, strel('disk', 4)); % 桥接齿根断裂 bw = imopen(bw, strel('disk', 2)); % 抹平齿面毛刺 % ------------------ 3. 取最大连通域 ------------------ cc = bwconncomp(bw); if cc.NumObjects == 0 error('没有检测到齿轮区域,请检查阈值方向或 Sensitivity'); end numPixels = cellfun(@numel, cc.PixelIdxList); [~, gearIdx] = max(numPixels); gearMask = false(size(bw)); gearMask(cc.PixelIdxList{gearIdx}) = true; % ------------------ 4. 区域属性粗筛 ------------------ gearStats = regionprops(gearMask, 'Area', 'FilledArea', ... 'Solidity', 'Eccentricity'); fprintf('Solidity = %.3f\n', gearStats.Solidity); fprintf('Eccentricity = %.3f\n', gearStats.Eccentricity); % ------------------ 5. 凸包差集定位缺陷 ------------------ % 齿轮凸包应覆盖所有齿尖;缺口与凸包之间的区域就是可疑缺陷 gearHull = bwconvhull(gearMask, 'union'); defectCandidates = gearHull & ~gearMask; defectCandidates = imopen(defectCandidates, strel('disk', 3)); defectCC = bwconncomp(defectCandidates); figure; subplot(1, 3, 1); imshow(img); title('原始图'); subplot(1, 3, 2); imshow(bw); title('形态学处理后二值图'); subplot(1, 3, 3); imshow(img); hold on; if defectCC.NumObjects > 0 defStats = regionprops(defectCC, 'Centroid', 'Area'); for k = 1:defectCC.NumObjects area = defStats(k).Area; if area > 80 % 过小区域视为误差 c = defStats(k).Centroid; rectangle('Position', ... [c(1)-30, c(2)-30, 60, 60], ... 'EdgeColor', 'r', 'LineWidth', 1.5); end end end title('缺陷标注');

3.2 关键参数说明:自适应阈值的坑与松紧调节

脚本中的Sensitivity是最容易踩坑的参数。Sensitivity越大,阈值越敏感,越容易把微弱的光照变化识别为前景。调节范围通常在 0.3 到 0.8 之间。0.6 是多数室内均匀光照齿轮图像的起点值;光照偏暗时增大到 0.7,反之降到 0.5。如果二值化结果中齿轮边缘出现非常密集的小孔洞,说明Sensitivity过高,背景纹理被当成前景。

ForegroundPolarity决定灰度图中齿轮是亮还是暗。白色塑料齿轮在深色背景上,前景是亮的,应设置为'bright';金属齿轮做暗场照明时,前景是暗的,应设置为'dark'。这里写成'dark'的原因在于:暗场照明下齿轮本身是吸光体,而背景是光源直射亮区。实际使用前建议先统计图像灰度直方图,确认峰值分布后决定方向,不要盲目套用。

凸包差集法来自一个几何事实:无缺陷齿轮的凸包和齿轮自身的二值图之间,只存在齿谷处的空隙;有缺陷时,缺口区域会被计入凸包但不在齿轮二值图中,因此gearHull & ~gearMask会把这些区域以较大连通块形式暴露出来。这样做不需要和标准模板比较,只需判断凸包差集区域是否超过经验阈值 80 像素。阈值 80 来自 640×480 图像的像素密度,换成高分辨率图像应按比例放大,通常取齿轮总面积的 1/500 到 1/800。

3.3 缺陷结果如何解读

Solidity和凸包差集共同决定缺陷判定。正常齿轮 Solidity 在 0.75 到 0.88,如果低于 0.7,优先怀疑缺齿而不是缺口;单个齿尖缺失会让凸包明显外扩,Solidity 可能掉到 0.6 以下。凸包差集检测出的区域数量和面积是第二层证据:一个齿尖缺口会产生 100 到 300 像素的差集区域,而齿根正常缝隙只有 10 到 40 像素。两者结合能有效排除误报,尤其是齿谷处的正常空隙不会被轻易认成缺口。

若脚本输出没有任何缺陷标记但实际齿轮确实有缺口,优先调整闭运算的disk半径。半径过大时小缺口被闭运算直接填平,这也是形态学方法最典型的过度处理问题,下一章专门展开。

4. 齿轮图像形态学处理的 4 个典型翻车场景与参数修正

4.1 边缘断裂严重时,先自适应阈值还是先形态学

最常遇到的第一个问题:齿轮图像光照不均,一侧亮一侧暗,全局阈值把暗处齿根直接切掉,亮处背景又和齿轮粘连。先做形态学没用——输入的二值图本身就是错的,闭运算只能桥接几个像素的缝隙,救不回整个齿根。

正确的顺序是先用自适应阈值替代全局阈值。imbinarize(img, 'adaptive')会把图像分成小块分别计算阈值,暗侧齿根也能保留下来。代价是背景噪声增多,所以后面必须紧跟bwareaopen(bw, 300)过滤小块。如果自适应阈值后仍然有齿根断裂,把Sensitivity从 0.6 降到 0.5,让阈值更好地贴合局部灰度变化。调参时不要动大结构元素,一味放大闭运算的半径会把小缺口填没。

4.2 结构元素取太大,小缺口被闭运算填平

strel('disk', r)中的 r 每增加 1,闭运算能桥接的断裂宽度约增加 2 像素。对于宽度只有 5 像素的微小缺口,r=4 的闭运算已经能把它填平,检测结果里缺口消失。这个问题在调试时极具迷惑性,因为看起来缺陷“不存在了”,根本不会报错。

针对小缺口检测,结构元素半径遵循“刚好不过桥”原则:先用 r=2 闭运算观察齿根断裂是否恢复,如果恢复不了再逐像素加 1,直到断痕刚被桥接为止。这个过程应该是写一个循环测试不同 r 值,而不是直接在脚本里填一个偏大的值。下表给出参考量级:

检测目标闭运算 r开运算 r备注
齿尖缺口,宽度 < 8 像素2 到 31 到 2偏大会漏检
齿根断裂,断口 > 10 像素4 到 52 到 3配合同心圆径向验证
缺齿,整个齿缺失6 到 103 到 5闭运算主要防齿根碎断

4.3 背景噪声被当成齿轮部件:连通域筛选强度不够

齿轮图像如果包含传送带、桌面纹理或其他工件,二值化后会出现多个大面积的连通域。此时直接取最大连通域可能把相邻部件和齿轮一起包进去,Solidity 和凸包差集计算结果全部失真。

修正方法是先取面积前 5 的连通域,逐个计算Eccentricity,齿轮的离心率一般低于 0.65,细长工件通常大于 0.9。也可以用BoundingBox的宽高比作为补充判据,齿轮的宽高比在 0.85 到 1.15 之间,超出范围直接排除。bwareaopen的面积阈值不要设得太大,以避免把齿轮和背景的连接部分切断,建议保持在齿轮总面积的 5% 以内。常见做法是把所有候选连通域画出来人工核对一次,确认筛选条件后再写死到脚本里。

4.4 二值化后齿轮内部出现孔洞:填充还是保留

齿轮表面如果有冲压印记、字符或中心孔以外的盲孔,在二值化后会形成前景内部的孔洞。缺陷检测时这些孔洞会被当成缺口输出一堆假阳性。保留正确中心孔信息的前提下,使用imfill(gearMask, 'holes')可以把非中心孔区域一并填平,中心孔本身由于和边界不连通会被保留。填充后再用gearMask & ~filledMask就能提取出表面孔洞,这些孔洞属于加工字符而非缺陷,可以直接忽略。

如果齿轮中心孔过大,imfill会把它也填掉,导致凸包差集计算失真。这种情况下先通过BoundingBox找到图像中心区域,用圆形掩膜把中心孔区域抠掉,再做填充。整套处理的顺序应该是:取最大连通域 → 中心孔掩膜 → 填充表面孔洞 → 凸包差集计算。

5. 用径向距离曲线精确锁定缺口角度和深度

区域属性只能判断齿轮有没有问题,生产现场更需要知道缺口在哪个齿的什么角度位置。径向距离方法是形态学处理后最直接的定位手段:先获取齿轮边界坐标,计算重心到每个边界点的距离,再按极角排序绘制距离曲线。正常齿轮的曲线是周期性锯齿波,峰值对应齿尖,谷值对应齿根;缺口所在位置距离值会明显低于相邻齿尖的峰值水平。

% radius_curve.m — 假设 gearMask 已由前一步得到 boundary = bwboundaries(gearMask, 'noholes'); B = boundary{1}; cy = round(mean(B(:, 1))); cx = round(mean(B(:, 2))); dy = B(:, 1) - cy; dx = B(:, 2) - cx; radius = sqrt(dx.^2 + dy.^2); theta = wrapTo2Pi(atan2(dy, dx)); [theta, sortIdx] = sort(theta); radius = radius(sortIdx); % 平滑曲线,避免单像素毛刺 radiusSmooth = movmean(radius, 9); % 找齿尖峰值:齿尖距离是局部极大值 [pks, locs] = findpeaks(radiusSmooth, ... 'MinPeakHeight', mean(radiusSmooth), ... 'MinPeakDistance', round(numel(theta) / 60 / 2)); fprintf('检测到 %d 个齿尖\n', numel(pks)); if numel(pks) < 目标齿数 fprintf('存在缺齿或缺口风险,请检查径向距离曲线\n'); end

MinPeakDistance需要按齿数估算。例如目标齿轮 30 齿,边界点总数约 2000,平均每齿 67 个点,峰间距约 33。这里除以 2 是为了不使用过小的峰间距导致误检,实际调试时先从齿数反推间距,再逐步放宽。如果检测出的峰数少于目标齿数,缺口位置就落在缺失峰附近,输出locs对应角度乘以 360 除以 2π 即可换算成物理角度。

径向距离曲线还有一个关键优势:不受缺齿数量的影响。区域属性和凸包法会因大面积缺齿而崩溃,径向曲线始终按齿尖峰数量计数,哪怕缺了三四个齿也能定位剩余齿的准确位置。最后一步是把角度值和缺陷类型绑定输出,生成工程可直接使用的缺陷报告字段。整个 matlab 仿真链路从二值化到径向曲线全部基于形态学处理完成,换一张新齿轮图只需要调整SensitivityMinPeakDistance两个参数。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 18:25:28

网络学习:网络层与数据链路层知识梳理

一、网络层网络层的作用&#xff1a;用户要的是可靠传输&#xff0c;而网络层提供传输能力&#xff0c;传输层提供可靠性&#xff08;TCP&#xff09;。网络层传输机制&#xff1a;把数据交给目标网络&#xff0c;再由路由器转较给目标主机。1.IP报头介绍IP报头采用定长报头与自…

作者头像 李华
网站建设 2026/9/11 18:24:01

UmiJS 4 打包优化:把 2.6MB 的 umi.js 砍到 860KB 的四步清单

UmiJS 4 打包优化&#xff1a;把 2.6MB 的 umi.js 砍到 860KB 的四步清单 【免费下载链接】umi A framework in react community ✨ 项目地址: https://gitcode.com/GitHub_Trending/um/umi 生产环境 build 出来的 dist 里躺着一个 2.6MB 的 umi.js&#xff0c;gzip 后传…

作者头像 李华