图像处理中的形态学(Morphology)是一种基于形状的图像处理技术,主要用于分析和处理二值图像或灰度图像中的结构特征。其核心思想是通过特定的结构元素(Structuring Element)对图像进行局部操作,以提取有用的形状信息、消除噪声或增强结构。
一、基本操作
腐蚀(Erosion)
腐蚀(Erosion)是图像形态学中的一种基本操作,主要用于缩小图像中的亮区域(前景),能够去除细小噪声、分离粘连的物体或平滑边界。
用结构元素(Structuring Element)扫描图像的每一个像素,只有当结构元素完全覆盖图像中的前景区域时,中心像素才会被保留为前景(白色),否则被腐蚀(变为背景,黑色)。
数学表达:
对于二值图像 A 和结构元素 B,腐蚀定义为:
Bz 表示结构元素 B 平移 z 后的位置。
结果图像中,只有 B 完全包含在 A 内时,中心点 z 才保留。
结构元素(Structuring Element)
结构元素是一个小的二值矩阵(通常为矩形、圆形或十字形),其形状和大小决定了腐蚀的效果。
常见形状:
矩形(如
3×3
全1矩阵):适合通用场景。圆形:用于平滑边缘。
十字形:针对特定方向的结构。
大小:
结构元素越大,腐蚀效果越强(更多前景被消除)。
腐蚀的过程
以下是原图像和结构元素
滑动扫描图像,将结构元素的中心依次对准图像的每一个像素
检查条件:结构元素覆盖的所有位置是否在图像中均为前景。
若全部匹配:中心像素保留为前景。
任一不匹配:中心像素置为背景。
腐蚀后
代码
import cv2
img = cv2.imread("rr.png")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 7))
dst = cv2.erode(img, kernel, iterations=2)
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
代码运行的结果
膨胀(Dilation)
膨胀(Dilation)是图像形态学中的另一个基本操作,与腐蚀(Erosion)相反,它用于扩大图像中的亮区域(前景),填充小孔、连接断裂部分或增加物体尺寸。
数学定义
对于二值图像 A 和结构元素 B,膨胀定义为:
B^是结构元素 B 的反射(对称翻转)。
(B^)z 表示 B^ 平移 z 后的位置。
含义:只要结构元素与图像前景有至少一个像素的重叠,中心点就置为前景(1/白色)。
直观理解
膨胀 = "加粗"前景区域:
如果一个像素的邻域(由结构元素定义)内有任意前景像素,则该像素被置为前景。
因此,前景区域会向外扩展,填补空洞或连接断裂的边缘。
膨胀的过程
以下是原图像和结构元素
滑动扫描:
将 结构元素 的中心依次对准 原图像 的每个像素。
检查 结构元素 覆盖的区域是否与 原图像 的前景有重叠。
填充规则:
重叠的区域不填充,不重叠的区域填充。
代码
import cv2
img = cv2.imread("rr.png")
dst = cv2.dilate(img, (5, 5), iterations=5)
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行后的结果
开运算(Opening)
开运算(Opening)是图像形态学中的一种重要操作,它由腐蚀(Erosion)和膨胀(Dilation)两个基本操作组合而成,顺序为先腐蚀后膨胀。开运算主要用于消除小物体、平滑物体边界,同时保持主体形状不变。
数学定义
开运算的数学表达式为:
A:输入图像(二值或灰度)。
B:结构元素(Structuring Element)。
⊖:腐蚀操作。
⊕:膨胀操作。
含义:先通过腐蚀去除微小噪声或毛刺,再通过膨胀恢复主体形状。
开运算的作用
消除小物体:去除孤立的噪声点或细小前景。
平滑轮廓:保留大物体的形状,同时平滑边缘。
断开窄连接:分离通过细线连接的物体。
保持主体尺寸:与直接腐蚀不同,开运算能避免过度缩小物体。
import cv2
img = cv2.imread("demo.png")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))
dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行后的程序 ,先通过腐蚀,去除白点,在通过膨胀,将图像还原。
闭运算(Closing)
闭运算是图像形态学中的另一核心操作,与开运算相对应,由膨胀和腐蚀组合而成,顺序为先膨胀后腐蚀。闭运算主要用于填充前景物体内部的小孔、连接邻近物体,并平滑边界,同时保持主体形状基本不变。
数学定义
闭运算的数学表达式为:
A:输入图像(二值或灰度)。
B:结构元素。
⊕:膨胀操作。
⊖:腐蚀操作。
含义:先通过膨胀填充孔洞或断裂,再通过腐蚀恢复主体形状。
闭运算的作用
填充小孔:填补前景物体内部的空洞(如医学图像中的细胞内部空白)。
连接邻近物体:合并因噪声或光照断裂的相邻区域。
平滑边界:使物体轮廓更连贯,消除凸起或凹陷。
保持主体尺寸:与直接膨胀不同,闭运算能避免过度扩大物体。
代码:
import cv2
img = cv2.imread("demo1.png")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))
dst = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行后,图像中的白色区域膨胀,将黑点去除,之后腐蚀,将图像恢复成正常形状。
二、高级操作
形态学梯度(Morphological Gradient)
形态学梯度(Morphological Gradient)是图像处理中的一种重要操作,用于突出物体的边缘或轮廓。它通过结合膨胀(Dilation)和腐蚀(Erosion)操作,提取图像中目标的边界信息。
数学定义
形态学梯度的基本公式为
A:输入图像(二值或灰度)。
B:结构元素(Structuring Element)。
⊕:膨胀操作(扩大前景)。
⊖:腐蚀操作(缩小前景)。
物理意义:膨胀操作扩展物体边缘,腐蚀操作收缩物体边缘,两者之差即为物体的边界。
作用与特点
边缘检测:突出目标的轮廓,效果类似传统边缘检测算子(如Sobel、Canny),但更强调形态学特性。
抗噪声能力:相比微分算子,形态学梯度对噪声更鲁棒。
灰度图像适用:可直接处理灰度图像,保留亮度变化信息。
执行步骤
假设输入二值图像 A 和 3×3 矩形结构元素 B:
步骤1:膨胀(Dilation)
扩展前景边界:
步骤2:腐蚀(Erosion)
收缩前景边界:
步骤3:梯度计算
膨胀结果减去腐蚀结果:
代码
import cv2
img = cv2.imread("rr.png")
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行后的结果:
顶帽(Top Hat)
顶帽变换是图像形态学中的一种高级操作,用于提取图像中的微小亮细节或校正不均匀光照。它通过原图与开运算结果的差值实现,适用于增强低对比度区域或分离细小目标。
白顶帽(White Top-Hat)
数学定义
A:原图像(灰度或二值)。
A∘B:开运算结果(先腐蚀后膨胀)。
作用:提取比结构元素更小的亮细节(如白噪声、亮斑)。
代码
import cv2
import numpy as np
# 读取图像
img = cv2.imread('demo.png', cv2.IMREAD_GRAYSCALE)
# 定义结构元素
kernel = np.ones((5, 5), np.uint8)
# 进行顶帽操作
dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
# 显示原图和处理后的结果
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行后的结果
黑顶帽(Black Top-Hat)
数学定义
A∙B:闭运算结果(先膨胀后腐蚀)。
作用:提取比结构元素更小的暗细节(如黑点、孔洞)。
代码:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('demo1.png', cv2.IMREAD_GRAYSCALE)
# 定义结构元素
kernel = np.ones((7, 7), np.uint8)
# 进行顶帽操作
dst = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
# 显示原图和处理后的结果
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行后的结果: