开闭运算可以让缺陷图更干净,也可能把细裂纹删除或把相邻目标合并。本文从像素尺度、邻域连通性和图像边界出发,推导核尺寸与面积阈值,给出可复现的小矩阵实验和适合工程验收的参数检查流程。
一个“去噪”参数如何变成漏检原因
二值缺陷图有许多零散亮点,开发时加入 5×5 开运算,图像立即干净。上线之后,宽度约 3 像素的细划痕也消失了。算法按设定删除了无法容纳结构元素的区域,而任务把这些区域定义成必须检出的缺陷。
形态学处理不是无损美化。必须先说明前景含义、最小目标、可接受间隙和像素对应的物理尺度,再讨论核大小。本文将缺陷定义为白色前景,背景为零,主要讨论固定倍率下的二维检测;透视变化明显时,应先建立空间变化的尺度模型。
核尺寸必须与物理尺度一起保存
假设物方采样为 0.02 mm/像素,最小必须保留的裂纹宽度为 0.06 mm,则只有约 3 像素。一个 5×5 方核先腐蚀时,需要局部至少有足够大的完整白色邻域,这类细线很容易被删除。
若相机分辨率翻倍且视场相同,原来 3 像素的目标变成 6 像素。继续使用相同的 5×5 核,物理含义已经变了。反过来,ROI 裁剪不会自动改变像素尺度;真正的缩放、像素合并和镜头倍率变化才会改变它。参数文件里应把采样尺度与处理分辨率一起保存。
用二维坐标表达结构元素时,矩形核对方向敏感,圆盘或离散椭圆核更接近各向同性,但离散化之后仍不是连续圆。细长核可以针对某个方向连接断裂,却会对旋转目标产生不同结果。因此“用椭圆核就没有方向偏差”也需要通过旋转样例验证。
从集合操作理解开闭运算
对二值前景集合 A 和结构元素 B,腐蚀保留那些 B 放进去后仍完全位于 A 内的位置;膨胀则扩张前景支持范围。开运算是先腐蚀再膨胀,闭运算是先膨胀再腐蚀。算子和边界参数可参照 OpenCV 图像滤波及形态学接口。
一个半径 r 像素的膨胀,会让两侧前景向间隙扩张。对简单平行边界,间隔约不大于 2r 的区域可能被连接;闭运算能保留连接后的桥。因此先闭运算再统计连通域,会改变目标数量。连接是否合理,需要由“这是同一个破损目标还是两个独立缺陷”的任务定义决定。
下面是一段不依赖第三方库的 Python 3 实验。使用 3×3 方核,图外固定为背景;它仅用于解释操作语义,处理大图时应使用经过优化的图像库。
1 | def morph(a, mode): |
这个例子也说明面积相同不代表形态学结果相同。九个像素组成的 3×3 方块可以保留,九个像素组成的细线可能完全消失。不能根据“噪点面积小”就推导“开运算只删除小面积目标”。
连通性不是实现细节
考虑下面两个对角接触的像素:
1 | 1 0 |
4 邻域只承认上下左右连接,结果是两个目标;8 邻域还承认对角连接,结果是一个目标。对细裂纹,8 邻域通常更容易保持斜向链条;对紧邻颗粒,它也更容易把仅在角点接触的对象合并。没有一个选择适合所有任务。
OpenCV 的 connectedComponentsWithStats 可返回每个标签的外接框、像素面积和质心,标签 0 表示背景;输入是 8 位单通道图像。接口含义见 OpenCV 连通域与形状分析文档。不要把背景面积作为最大缺陷,也不要依赖标签编号长期对应同一目标。
如果希望“斜向细线算一条、对角颗粒又算两个”,仅切换 4/8 邻域无法同时表达这个语义,可能需要距离、方向、细化或基于形状的二次判定。应先将冲突样例加入验收集,再引入更复杂算法。
面积阈值怎样换算成平方毫米
当两个方向物方采样为 sx、sy mm/像素,像素计数 N 的面积为 A=N·sx·sy。假设两方向均为 0.02 mm/像素,要求目标面积至少 0.03 mm²,最低像素面积为 ceil(0.03/0.0004)=75。
面积阈值能抑制小颗粒,但对长而细的裂纹未必合适。长度 2 mm、宽 0.02 mm 的缺陷面积只有 0.04 mm²,却可能比一个更大的圆点严重。目标筛选应同时考虑长度、宽度、方向或任务相关形状,不宜只按面积一刀切。
连通域像素面积也不同于轮廓多边形面积。前者统计被分类为前景的像素格数量,后者对边界坐标积分;小目标、细线和含孔目标可能存在明显差异。验收规范必须明确采用哪种定义,不能把两个函数输出混用。
图像边界代表未知区域,还是已知背景
上述示例显式把图外设为背景,这意味着目标贴着边界时可能被腐蚀。图像库的默认形态学边界可能使用特殊值,并不等同于显式补零;工程代码应写清 borderType、borderValue 或先填充边界,避免依赖隐含行为。
更关键的问题是裁剪目标的测量含义。一个缺陷与 ROI 边界相交,其真实面积可能还在视场之外。把它当普通完整目标,会系统性低估面积;直接删除它,又可能漏掉严重缺陷。可以增加 touches_border 字段,将其判为“检测到但尺寸不完整”,或扩大 ROI 后重新测量。
若采用填充,最后要将坐标转换回原图,并在去除填充后判断是否碰原始边界。对整个场景边缘和内部 ROI 边缘还应区分:内部 ROI 外侧仍有原始图信息时,应优先利用真实邻域,而不是制造一圈黑边。
不改变边界的筛选与改变形状的处理
若需求只是去掉面积很小的独立颗粒,可以先做连通域再按面积筛选,这会保留其他目标原有的边界;开运算则会修改保留目标的局部轮廓。两者都能减少小区域,但对细长结构、尖角和尺寸测量的影响不同,应按任务选择。
如果必须用闭运算把一个目标内部断裂连接起来,可以用处理后的图确定候选区域,再回到原始二值图统计像素面积。这样可以避免把人为填补的桥直接当作真实缺陷面积,不过仍需处理两个真实目标被合并的情况。候选生成与尺寸计量使用不同掩膜时,应明确标注,便于追踪每个统计量的来源。
用参数扰动检查算法是否靠偶然工作
建议准备四类人工可控样例:最小宽度细线、间隙接近阈值的相邻目标、边界截断目标、不同旋转角度的相同形状。再加入真实图像中的低对比度和不均匀照明情况,分别记录检测数量、面积、合并与拆分错误。
把核尺寸从 3 调到 5、阈值上下扰动少量灰度、面积界限上下变化 10%,观察输出是否剧烈跳变。若业务结论只在一个非常窄的参数点成立,说明系统缺少鲁棒余量。应回查采样分辨率、照明和目标定义,而不只是继续寻找一个更精巧的常数。
最终输出最好包含原始掩膜、处理后掩膜、目标统计和被剔除原因。发生漏检时,才能判断目标消失于阈值化、形态学还是筛选阶段。可追踪的处理链,比一张干净的二值图更有工程价值。