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()
  • 在这个图中前景是白色,黑色是背景
  • 顶帽操作结果是开运算去除的噪点,可以看到白色前景的噪点确实去掉了,在这里体现在于背景(黑色部分)更连续了
  • 黑帽操作是闭运算补全的孔洞,白色为前景,红框部分可以理解为前景中的孔洞,闭运算填补了孔洞
相关推荐
AWS官方合作商6 分钟前
Amazon Lex:AI对话引擎重构企业服务新范式
人工智能·ai·机器人·aws
workflower10 分钟前
Prompt Engineering的重要性
大数据·人工智能·设计模式·prompt·软件工程·需求分析·ai编程
学长学姐我该怎么办22 分钟前
年前集训总结python
python
curemoon29 分钟前
理解都远正态分布中指数项的精度矩阵(协方差逆矩阵)
人工智能·算法·矩阵
量化投资技术29 分钟前
【量化科普】Sharpe Ratio,夏普比率
python·量化交易·量化·量化投资·qmt·miniqmt
yanglamei196231 分钟前
基于Python+Django+Vue的旅游景区推荐系统系统设计与实现源代码+数据库+使用说明
vue.js·python·django
虚假程序设计34 分钟前
python用 PythonNet 从 Python 调用 WPF 类库 UI 用XAML
python·ui·wpf
胡桃不是夹子1 小时前
CPU安装pytorch(别点进来)
人工智能·pytorch·python
Fansv5871 小时前
深度学习-6.用于计算机视觉的深度学习
人工智能·深度学习·计算机视觉
xjxijd2 小时前
AI 为金融领域带来了什么突破?
人工智能·其他