本节摘要:SOURCE 形态学章(合并原 4.1):基于结构元素的集合运算。本节动手腐蚀、膨胀、开运算、闭运算,清理二值分割噪点。
import cv2, numpy as np bin_img = cv2.imread('mask.png', 0) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) erode = cv2.erode(bin_img, kernel, iterations=1) dilate = cv2.dilate(bin_img, kernel, iterations=1) open_ = cv2.morphologyEx(bin_img, cv2.MORPH_OPEN, kernel) close = cv2.morphologyEx(bin_img, cv2.MORPH_CLOSE, kernel)
| 问题 | 运算 |
|---|---|
| 阈值后椒盐点 | OPEN |
| 断线字符 | CLOSE |
| 分离粘连物体 | 腐蚀迭代 |

MORPH_GRADIENT = dilate - erode 得边界;顶帽 原图 - 开 增强亮小目标。
⚠️ 常见坑:对 0/255 灰度图当二值 — 先 threshold。
💡 关键直觉:形态学只在二值/低灰度级上几何意义明确。
第 4 章:分割。
形态学建立在集合运算上:结构元素(核)在图像上滑动,腐蚀取"结构元素完全被前景覆盖"的位置,膨胀取"结构元素与前景有交集"的位置。直观效果:腐蚀让前景缩小,细小突起、孤立亮斑被去除;膨胀让前景扩大,内部小孔、细缝被填充。灰度图上的形态学也有定义(取邻域最小或最大),但在二值图上几何意义最直观,这也是形态学几乎总跟在阈值分割后面的原因——先把图像变成 0/1 掩膜,再用形态学整理。
import cv2, numpy as np # 顶帽:原图 - 开运算,提取比周围亮的小目标 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7)) tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, kernel) # 黑帽:闭运算 - 原图,提取比周围暗的小目标 blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, kernel)
开运算 = 先腐蚀后膨胀,效果是去掉前景上细小的亮斑、断开细的连接(小噪点被腐蚀掉,主体先缩后放回到近似原状);闭运算 = 先膨胀后腐蚀,效果是填上前景内部的小孔、接上断裂的笔画。两者都是"先破坏再修复"的对称结构,区别在于先腐蚀还是先膨胀。工业场景里,阈值分割后的二值图几乎必接一次开闭:椒盐噪点用开运算去,字符断线用闭运算补,这是分割后处理的标准第一步。
结构元素(矩形、十字、椭圆)的形状决定处理的各向异性:矩形对水平和垂直结构一视同仁,十字偏向对角线方向的连接,椭圆更接近真实目标形状、边缘更平滑。迭代次数控制处理强度,但多次小核迭代与一次大核并不完全等价——迭代会保留更多细节。工程调参经验:先小核后大核、能用一次完成就不用多次,避免过度处理抹掉目标本身。形态学梯度(膨胀减腐蚀)提取边界,顶帽增强亮目标,黑帽增强暗目标,这些组合运算在光照不均的工业场景里非常实用。
连通域分析是形态学的常用搭档:形态学处理完的二值图,用 cv2.connectedComponents 统计连通域数量和面积,可以过滤掉太小的噪点、找出最大的目标、按面积筛选 ROI。这套"阈值、形态学、连通域"组合拳,是工业视觉里最基础也最常用的流水线。
实验建议:对带椒盐噪声的二值图分别做开、闭、先开后闭,数一数连通域数量变化,观察噪声点和目标主体谁先被处理;再对比矩形核与椭圆核对圆角目标的边缘影响。这个实验能直观建立"运算-效果"的对应关系。
最后提醒:形态学只对二值图(或低灰度级图)有明确的几何意义,对 0/255 的图,先确认是否已经做过阈值处理;对灰度图做形态学虽然语法合法,但结果往往不如二值图直观,容易产生误解。
补一个与轮廓结合的常见用法:形态学处理完的二值图常用 findContours 提取轮廓,再配合 boundingRect、contourArea 等计算目标的位置和尺寸。这套"阈值、形态学、轮廓"流程在工业视觉里是测量和定位的标准套路,几乎每个产线项目都会用到。此外,距离变换(distanceTransform)可以求每个前景像素到最近背景的距离,用于骨架提取和分水岭标记生成——它是形态学思想的重要延伸,也是处理粘连目标时的前置步骤。理解形态学"以形状为单位处理图像"的本质,就能举一反三。