图像形态学操作-腐蚀与膨胀,开运算和闭运算(含简单代码演示)

发布于:2025-05-26 ⋅ 阅读:(169) ⋅ 点赞:(0)

形态学操作是图像处理中的基础技术,主要用于分析和处理图像中的形状与结构,其中膨胀(Dilation)腐蚀(Erosion)是最核心的两个操作。它们通常基于结构元素(Structuring Element)对二值图像(黑白图像)进行处理,也可扩展至灰度图像。

1. 膨胀(Dilation)

原理
  • 定义:膨胀通过滑动结构元素(如矩形、圆形等)扫描图像,若结构元素与图像中的前景(白色区域)有交集,则将锚点位置设为前景。

  • 效果:扩展前景区域,填充小孔洞、连接邻近物体、平滑边缘。

  • 数学表达(集合论):
    A\oplus B=\left \{ \left.\begin{matrix} z \end{matrix}\right| \left ( B \right )_z\bigcap A\neq \varnothing \right \}
    其中,A 是原图像,B 是结构元素,(B)z 表示结构元素平移至位置 z。

应用场景
  • 填补断裂的文字笔画。

  • 连接因噪声分离的物体。

  • 增加目标区域尺寸。

示例

原始图像:[0,1,0](二值化,1为前景)
结构元素:[1,1,1](3像素水平线,锚点居中)
膨胀结果:[1,1,1](所有位置被填充)。

2. 腐蚀(Erosion)

原理
  • 定义:腐蚀要求结构元素完全覆盖图像的前景区域,仅在满足条件时保留锚点位置的前景。

  • 效果:缩小前景区域,消除细小噪声、分离粘连物体、锐化边缘。

  • 数学表达
    A\ominus B=\left \{ \left.\begin{matrix} z \end{matrix}\right| \left ( B \right )_z\subseteq A \right \}

应用场景
  • 去除图像中的胡椒噪声(孤立小点)。

  • 分离紧邻的物体(如细胞、颗粒)。

  • 保留主体结构,去除边缘毛刺。

示例

原始图像:[1,1,1,1,1](连续前景)
结构元素:[1,1,1](3像素水平线)
腐蚀结果:[0,1,1,1,0](两端被腐蚀)。

3. 膨胀与腐蚀的对比

特性 膨胀(Dilation) 腐蚀(Erosion)
作用 扩大前景区域 缩小前景区域
抗噪声能力 可能放大噪声 能消除小噪声
结构依赖 依赖结构元素与图像的交集 依赖结构元素完全覆盖图像区域
对偶性 膨胀的补集 = 腐蚀补集(对偶操作) 腐蚀的补集 = 膨胀补集(对偶操作)

4. 结构元素的影响

  • 形状:矩形、圆形、十字形等不同形状会控制膨胀/腐蚀的方向性(如十字形侧重水平和垂直扩展)。

  • 尺寸:结构元素越大,膨胀/腐蚀的效果越显著。

  • 锚点位置:决定膨胀/腐蚀的中心参考点(默认常为中心)。


5. 组合应用

  • 开运算(Opening):先腐蚀后膨胀,用于去噪并保持主体形状。

  • 闭运算(Closing):先膨胀后腐蚀,用于填充孔洞并平滑轮廓。


直观理解

  • 膨胀:想象用“画笔”沿物体边缘涂抹,使其变粗。

  • 腐蚀:想象用“橡皮”擦除物体边缘,使其变细。

通过调整结构元素和组合操作,膨胀与腐蚀能灵活应对图像分割、边缘检测、形态过滤等多种任务。以下展示一个单区域的膨胀操作代码实现:

import numpy as np
from scipy.ndimage import binary_dilation

region = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          [0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
          [0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
          [0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
          [0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
          [0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

# 转换为NumPy数组
region_np = np.array(region)

# 定义3x3全1结构元素(可根据需要调整结构元素形状)
struct = np.ones((3, 3), dtype=int)

# 执行膨胀操作
dilated = binary_dilation(region_np, struct).astype(int)

# 转换回列表格式并打印结果
dilated_region = dilated.tolist()

for row in dilated_region:
    print(row)
'''
dilated_region = 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 1, 1, 0, 0, 0, 0, 0]
[0, 1, 1, 1, 1, 1, 1, 0, 0, 0]
[0, 1, 1, 1, 1, 1, 1, 1, 0, 0]
[0, 1, 1, 1, 1, 1, 1, 1, 0, 0]
[0, 1, 1, 1, 1, 1, 1, 1, 0, 0]
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0]
[0, 0, 0, 1, 1, 1, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
'''

网站公告

今日签到

点亮在社区的每一天
去签到