OpenCV形态学操作

1.1. 形态学操作介绍

初识:

形态学操作是一种基于图像形状的处理方法,主要用于分析和处理图像中的几何结构。其核心是通过结构元素(卷积核)对图像进行扫描和操作,从而改变图像的形状和特征。例如:

  • 腐蚀(Erosion):将图像中的前景物体边界向内收缩,使物体变小。
  • 膨胀(Dilation):将图像中的前景物体边界向外扩展,使物体变大。
  • 开运算(Opening):先腐蚀后膨胀,用于去除小噪点。
  • 闭运算(Closing):先膨胀后腐蚀,用于填补小孔。

功能:

形态学操作的主要功能包括:

  • 去噪:通过腐蚀或开运算去除小的噪点。
  • 边缘提取:通过形态学梯度(膨胀与腐蚀的差)突出边缘。
  • 图像分割:通过闭运算或开运算分离或连接物体。
  • 特征增强:通过顶帽或黑帽操作提取特定特征。
    • 顶帽:原图与开运算的差
    • 黑帽:闭运算与原图的差

应用场景:

|-----------|----------------|
| 操作类型 | 应用场景 |
| 腐蚀 | 去噪、细化边缘、分离相邻对象 |
| 膨胀 | 填补小孔、连接对象、加粗前景 |
| 开运算 | 去除小噪点、平滑前景边界 |
| 闭运算 | 填补暗孔、平滑前景边界 |
| 形态学梯度 | 边缘检测、轮廓提取 |
| 顶帽运算 | 提取亮点、去除低频背景信息 |
| 黑帽运算 | 提取暗纹、增强低频阴影 |

1.2. 原理介绍

1.2.1. 腐蚀(Erosion) :

  • 腐蚀操作会将图像中的前景物体(通常是白色区域)的边界向内收缩。具体来说,当结构元素的中心移动到图像的某个像素时,只有当结构元素覆盖的所有像素都是前景物体的像素时,该中心像素才会被保留为前景物体的一部分。否则,该像素将被视为背景(黑色区域)。这种操作会使物体的边缘变细,可以去除小的突出物和噪点。

1.2.2. 膨胀(Dilation) :

  • 膨胀操作与腐蚀相反,它会将前景物体的边界向外扩展。当结构元素的中心移动到图像的某个像素时,只要结构元素覆盖的像素中存在至少一个前景物体的像素,该中心像素就会被保留为前景物体的一部分。这种操作会使物体的边缘变粗,可以填补物体中的小孔和断开的部分。

1.2.3. 开运算(Opening) :

  • 开运算是先腐蚀后膨胀的过程。它可以通过去除小的突出物和噪点来平滑前景物体的边界。开运算对于去除小的白色噪点特别有效。
    • 腐蚀:可以有效的消除突出物体和噪点,但是原前景会变小,有的地方存在孔洞与断开
    • 膨胀:修复孔洞,恢复大小。

1.2.4. 闭运算(Closing) :

  • 闭运算是先膨胀后腐蚀的过程。它可以通过填补小的孔洞来平滑前景物体的边界。闭运算对于填补小的黑色孔洞特别有效。
    • 膨胀:修复孔洞,但是前景图像会变大
    • 腐蚀:将大小近似恢复到原图大小

1.2.5. 顶帽操作:

    • 定义:顶帽操作是原始图像与开运算结果之间的差值。开运算是先进行腐蚀操作,再进行膨胀操作。
    • 功能:
      • 顶帽操作可以提取图像中比背景亮的细小区域。
      • 提取比背景亮的细小区域。去除大范围的低频背景信息,
      • 突出局部亮点。增强对比度。
    • 原理:
      • 开运算会去掉毛刺和突出部分
      • 原图减去开运算结果,就可以获得开运算去除的细小区域

1.2.6. 黑帽操作:

    • 定义: 黑帽操作是闭运算结果与原始图像之间的差值。闭运算是先进行膨胀操作,再进行腐蚀操作。黑帽操作可以提取图像中比背景暗的细小区域。
    • 功能:
      • 提取比背景暗的小区域。
      • 突出细小的暗纹和阴影区域。
      • 增强对比度,适合背景亮、局部暗区域的图像。
    • 原理:
      • 闭运算先膨胀在腐蚀,把孔洞和非连续区域不全了
      • 闭运算减去原图像,就可以得到闭运算去除的部分------比背景暗的小区域

1.3. 在openCV中实现

1.3.1. kernel

以下函数都会用到kernel,结构元素(卷积核),用于定义邻域的形状和大小。选择合适的形状与大小,可以提高形态学操作的效果。首先需要了解一下如何选择kernel

1.3.1.1. 确定结构元素形状

结构元素的形状应根据图像的特征和处理目标来选择。常见的结构元素形状包括:

  • 矩形(Rectangular):
    • 适用于处理规则形状的图像,如文本、表格等。
    • 代码示例:
python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
  • 椭圆(Elliptical):
    • 适用于处理圆形或椭圆形的图像,如细胞、颗粒等。
    • 代码示例:
python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
  • 十字形(Cross-shaped):
    • 适用于处理需要突出中心点的图像,如边缘检测等。
    • 代码示例:
python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))

1.3.1.2. 确定结构元素大小

结构元素的大小应根据图像中物体的大小和细节来选择。以下是一些指导原则:

  • 去除小噪点:
    • 如果图像中有小的噪点,选择较小的结构元素(如 3x3 或 5x5)。
    • 代码示例:
python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
  • 填补小孔:
    • 如果图像中有小的孔洞,选择较大的结构元素(如 5x5 或 7x7)。
    • 代码示例:
python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
  • 处理大物体:
    • 如果图像中有较大的物体,选择更大的结构元素(如 7x7 或 9x9)。
    • 代码示例:
python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))

1.3.1.3. 选择结构元素的步骤

  1. 分析图像特征:
    • 观察图像中的物体大小、形状和细节。
    • 确定需要处理的目标(如去除噪点、填补孔洞、提取边缘等)。
  1. 选择结构元素形状:
    • 根据图像的特征选择合适的形状(矩形、椭圆、十字形等)。
  1. 选择结构元素大小:
    • 根据图像中物体的大小和细节选择合适的大小。
    • 可以通过实验逐步调整结构元素的大小,观察不同大小对结果的影响。
  1. 实验和调整:
    • 使用不同的结构元素大小和形状进行实验,观察处理后的图像效果。
    • 根据实验结果调整结构元素的大小和形状,直到达到满意的效果。

1.3.2. cv2.erode

函数:

python 复制代码
def erode(src: cv2.typing.MatLike, kernel: cv2.typing.MatLike, dst: cv2.typing.MatLike | None = ..., anchor: cv2.typing.Point = ..., iterations: int = ..., borderType: int = ..., borderValue: cv2.typing.Scalar = ...) -> cv2.typing.MatLike: ...

参数解释:

  • src:输入图像(通常是二值图像或灰度图像)。
  • kernel:结构元素(卷积核),用于定义邻域的形状和大小。
  • dst:输出图像。如果未指定,则默认与输入图像具有相同的类型和大小。
  • anchor:结构元素的锚点位置,默认为 (-1, -1),表示锚点位于结构元素的中心。
  • iterations:迭代次数,默认为 1。增加迭代次数会增强腐蚀的效果。
  • borderType:边界填充方式,默认为 cv2.BORDER_CONSTANT。常见的边界填充方式有:
    • cv2.BORDER_CONSTANT:用常数值填充边界。
    • cv2.BORDER_REFLECT:用镜像反射的方式填充边界。
    • cv2.BORDER_REPLICATE:用边界像素值重复填充边界。
    • cv2.BORDER_WRAP:用环绕方式填充边界。
  • borderValue:边界填充的值,默认为 0。

参数确定方法:

  • 结构元素(Kernel):如第一点所讲
  • 迭代次数(Iterations):根据需要调整,次数越多,腐蚀效果越明显。通常设置为 1 或 2。

参数对结果的影响:

  • 结构元素的形状和大小:影响腐蚀的范围和效果。较大的结构元素会使腐蚀效果更明显,但可能会导致图像失真。
  • 迭代次数:增加迭代次数会使腐蚀效果更明显,但可能会导致图像过度腐蚀。

使用注意事项:

  • 选择合适的结构元素大小和形状,避免过度腐蚀导致图像失真。
  • 迭代次数不宜过多,以免影响图像的整体结构。

结合腐蚀和对不同结构元素的效果进行对比:

python 复制代码
def TestMorphologicalErode(iterator:int):

    # 读取图像
    img = cv2.imread('Word.jfif', 0)  # 以灰度模式读取图像
    
    # 定义不同形状和大小的结构元素
    kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 矩形结构元素
    kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))  # 椭圆结构元素
    kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))  # 十字形结构元素
    
    # 腐蚀操作
    erosion_rect = cv2.erode(img, kernel_rect, iterations=1)
    erosion_ellipse = cv2.erode(img, kernel_ellipse, iterations=1)
    erosion_cross = cv2.erode(img, kernel_cross, iterations=1)
    
    # 显示结果
    plt.figure(figsize=(12, 8))
    plt.subplot(2, 2, 1)
    plt.imshow(img, cmap='gray')
    plt.title('Original Image')
    plt.axis('off')
    
    plt.subplot(2, 2, 2)
    plt.imshow(erosion_rect, cmap='gray')
    plt.title('Erosion with Rectangular Kernel')
    plt.axis('off')
    
    plt.subplot(2, 2, 3)
    plt.imshow(erosion_ellipse, cmap='gray')
    plt.title('Erosion with Elliptical Kernel')
    plt.axis('off')
    
    plt.subplot(2, 2, 4)
    plt.imshow(erosion_cross, cmap='gray')
    plt.title('Erosion with Cross-shaped Kernel')
    plt.axis('off')
    
    plt.show()

结果发现:

  • 腐蚀操作,字反而变粗了,其实这里可以理解前景为,黑色的字是背景,腐蚀会让白色的前景变小,即黑色的背景变大,所以黑色的字变大了
  • 矩形的白色孔洞腐蚀的厉害,十字星与椭圆的与原图保留的较好(对比"惊"的口)

1.3.3. cv2.dilate

函数:

python 复制代码
def dilate(src: cv2.typing.MatLike, kernel: cv2.typing.MatLike, dst: cv2.typing.MatLike | None = ..., anchor: cv2.typing.Point = ..., iterations: int = ..., borderType: int = ..., borderValue: cv2.typing.Scalar = ...) -> cv2.typing.MatLike: ...

参数解释:

  • src:输入图像(通常是二值图像或灰度图像)。
  • kernel:结构元素(卷积核),用于定义邻域的形状和大小。
  • dst:输出图像。如果未指定,则默认与输入图像具有相同的类型和大小。
  • anchor:结构元素的锚点位置,默认为 (-1, -1),表示锚点位于结构元素的中心。
  • iterations:迭代次数,默认为 1。增加迭代次数会增强膨胀的效果。
  • borderType:边界填充方式,默认为 cv2.BORDER_CONSTANT。
  • borderValue:边界填充的值,默认为 0。

参数确定方法:

  • 结构元素(Kernel):如第一部分所示
  • 迭代次数(Iterations):根据需要调整,次数越多,膨胀效果越明显。通常设置为 1 或 2。

参数对结果的影响:

  • 结构元素的形状和大小:影响膨胀的范围和效果。较大的结构元素会使膨胀效果更明显,但可能会导致图像失真。
  • 迭代次数:增加迭代次数会使膨胀效果更明显,但可能会导致图像过度膨胀。

使用注意事项:

  • 选择合适的结构元素大小和形状,避免过度膨胀导致图像失真。
  • 迭代次数不宜过多,以免影响图像的整体结构。

对比不同形状结构元素的膨胀操作:

python 复制代码
def TestMorphologicalDilate(iterator:int):

    # 读取图像
    img = cv2.imread('Word.jfif', 0)  # 以灰度模式读取图像

    # 定义不同形状和大小的结构元素
    kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 矩形结构元素
    kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))  # 椭圆结构元素
    kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))  # 十字形结构元素

    # 腐蚀操作
    erosion_rect = cv2.dilate(img, kernel_rect, iterations=1)
    erosion_ellipse = cv2.dilate(img, kernel_ellipse, iterations=1)
    erosion_cross = cv2.dilate(img, kernel_cross, iterations=1)

    # 显示结果
    plt.figure(figsize=(12, 8))
    plt.subplot(2, 2, 1)
    plt.imshow(img, cmap='gray')
    plt.title('Original Image')
    plt.axis('off')

    plt.subplot(2, 2, 2)
    plt.imshow(erosion_rect, cmap='gray')
    plt.title('Dilation with Rectangular Kernel')
    plt.axis('off')

    plt.subplot(2, 2, 3)
    plt.imshow(erosion_ellipse, cmap='gray')
    plt.title('Dilation with Elliptical Kernel')
    plt.axis('off')

    plt.subplot(2, 2, 4)
    plt.imshow(erosion_cross, cmap='gray')
    plt.title('Dilation with Cross-shaped Kernel')
    plt.axis('off')

    plt.show()
  • 膨胀操作会让白色孔洞变大,黑色字体会变瘦
  • 矩形效果不好,实际运行时可以在字体边缘看到一些处理过的痕迹,椭圆形与十字星更适合毛笔字的处理

1.3.4. cv2.morphologyEx(开运算、闭运算、顶帽操作、黑帽操作、形态学梯度)

函数:

python 复制代码
cv2.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst

参数解释:

  • src:输入图像(通常是二值图像或灰度图像)。
  • op:形态学操作类型:
    • cv2.MORPH_OPEN:开运算。
    • cv2.MORPH_CLOSE:闭运算。
    • cv2.MORPH_TOPHAT:顶帽操作。
    • cv2.MORPH_BLACKHAT:黑帽操作。
    • cv2.MORPH_GRADIENT:形态学梯度。
  • kernel:结构元素(卷积核),用于定义邻域的形状和大小。
  • dst:输出图像。如果未指定,则默认与输入图像具有相同的类型和大小。
  • anchor:结构元素的锚点位置,默认为 (-1, -1),表示锚点位于结构元素的中心。
  • iterations:迭代次数,默认为 1。增加迭代次数会增强操作的效果。
  • borderType:边界填充方式,默认为 cv2.BORDER_CONSTANT。
  • borderValue:边界填充的值,默认为 0。

参数确定方法:

  • 结构元素(Kernel) :根据图像的特征和处理目标选择合适的形状和大小。例如,去除小噪点时,可以选择较小的结构元素,如 np.ones((3, 3), np.uint8);填补小孔时,可以选择较大的结构元素,如 np.ones((5, 5), np.uint8)。
  • 迭代次数(Iterations):根据需要调整,次数越多,操作的效果越明显。通常设置为 1 或 2。

参数对结果的影响:

  • 结构元素的形状和大小:影响操作的范围和效果。较大的结构元素会使操作效果更明显,但可能会导致图像失真。
  • 迭代次数:增加迭代次数会使操作效果更明显,但可能会导致图像过度处理。

使用注意事项:

  • 选择合适的结构元素大小和形状,避免过度处理导致图像失真。
  • 迭代次数不宜过多,以免影响图像的整体结构。
  • 不同的操作类型(如开运算、闭运算等)对图像的影响不同,需根据具体需求选择合适的操作类型。

根据运算结果,我们可以尝试对比一下结果图

python 复制代码
def TestMorphologicalEx():
    image=cv2.imread("Word.jfif",0) #读取灰度图

    kernel=cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))#十字星 3*3        

    image_open=cv2.morphologyEx(image,cv2.MORPH_OPEN,kernel,iterations=1)
    image_close=cv2.morphologyEx(image,cv2.MORPH_CLOSE,kernel,iterations=1)
    image_TopHat=cv2.morphologyEx(image,cv2.MORPH_TOPHAT,kernel,iterations=1)
    image_BlackHat=cv2.morphologyEx(image,cv2.MORPH_BLACKHAT,kernel,iterations=1)

      # 显示结果
    plt.figure(figsize=(8, 12))
    plt.subplot(3, 2, 1)
    plt.imshow(image, cmap='gray')
    plt.title('Original Image')
    plt.axis('off')

    plt.subplot(3, 2, 2)
    plt.imshow(image, cmap='gray')
    plt.title('Original Image')
    plt.axis('off')

    plt.subplot(3, 2, 3)
    plt.imshow(image_open, cmap='gray')
    plt.title('image_open')
    plt.axis('off')

    plt.subplot(3, 2, 4)
    plt.imshow(image_close, cmap='gray')
    plt.title('image_close')
    plt.axis('off')

    plt.subplot(3, 2, 5)
    plt.imshow(image_TopHat, cmap='gray')
    plt.title('image_TopHat Original - open')
    plt.axis('off')

    plt.subplot(3, 2, 6)
    plt.imshow(image_BlackHat, cmap='gray')
    plt.title('image_BlackHat Close - Original')
    plt.axis('off')

    plt.show()
  • 在这个图中前景是白色,黑色是背景
  • 顶帽操作结果是开运算去除的噪点,可以看到白色前景的噪点确实去掉了,在这里体现在于背景(黑色部分)更连续了
  • 黑帽操作是闭运算补全的孔洞,白色为前景,红框部分可以理解为前景中的孔洞,闭运算填补了孔洞
相关推荐
2501_938140071 小时前
做内容很省心,2026好用AI笔记,支持抖音小红书视频无水印保存
人工智能
sell-cloud4 小时前
Prompt Engineering要凉了?Fable 5.5能“猜“意图,但银行正在封杀AI Agent——企业AI的真正护城河是什么
人工智能·prompt
Navicat中国5 小时前
Navicat 18 内置 AI 助手让数据库开发从繁琐操作迈向智能协作
大数据·人工智能·数据库开发
4SAPI6 小时前
多模型请求路由怎么设计?成本、速度和能力如何平衡
人工智能·python·gateway·php
魔乐社区6 小时前
翼芯・智算测试与适配优化专区,让国产算力“选得准、跑得通、用得好“
人工智能·开源·大模型
XCDoris8 小时前
郴州logo设计机构
大数据·人工智能·python
Goboy8 小时前
一个人带三个Agent,我用全新TRAE从0到1搭了个资讯周刊站
人工智能·trae
俊哥V8 小时前
每日 AI 研究简报 · 2026-10-19
人工智能·ai
AI_AGENT_DEV_AI8 小时前
AI英语教培智能体的开发
人工智能
物联网软硬件开发-轨物科技8 小时前
【技术白皮书】光伏清检一体化机器人系统解决方案技术白皮书
大数据·运维·网络·人工智能·机器人