当前位置:   article > 正文

python图像形态学操作——膨胀,腐蚀;开运算,闭运算_cv2腐蚀膨胀

cv2腐蚀膨胀

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


图像形态学操作——膨胀,腐蚀;开运算,闭运算

形态学,是图像处理中应用最为广泛的技术之一,主要用于从图像中提取对表达和描绘区域形状有意义的图像分量,使后续的识别工作能够抓住目标对象最为本质的形状特征。

图像的膨胀(Dilation)和腐蚀(Erosion)是两种基本的形态学运算,其中膨胀类似于“领域扩张”,将图像中的白色部分进行扩张,其运行结果图比原图的白色区域更大;腐蚀类似于“领域被蚕食”,将图像中白色部分进行缩减细化,其运行结果图比原图的白色区域更小。
下图:(原图,腐蚀,膨胀)
原图腐蚀膨胀


一、图像腐蚀

腐蚀的运算符是“-”,其定义如下:
在这里插入图片描述

该公式表示图像A用卷积模板B来进行腐蚀处理,通过模板B与图像A进行卷积计算,得出B覆盖 区域的像素点最小值,并用这个最小值来替代参考点的像素值。
在这里插入图片描述

代码:

1.cv2.erode()函数

函数:
ero = cv2.erode(src,kernel,anchor,iterations)
参数1:src,原图像
参数2:kernel,腐蚀操作的内核,默认为一个简单的 3x3 矩
参数3:anchor,默认为Point(-1,-1),内核中心点
参数4:iterations,腐蚀次数,默认值1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
#1.读取图片
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread("/kaggle/input/morphology/morphology.png", cv2.IMREAD_UNCHANGED)
plt.imshow(img)
plt.axis('off')#关闭坐标系
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

原图

#2.图片灰度化(已经是灰度图片则不用做这一步)
def rgb2gray(rgb):#灰度化
    """
    rgb 2 gray
    Args:
        rgb image
    Returns:
        gray image
    """
    gray = rgb[:, :, 0] * 0.299 + rgb[:, :, 1] * 0.587 + rgb[:, :, 2] * 0.114
    return gray
img = rgb2gray(img)

#2.灰度图片二值化
def thre_bin(gray_image, threshold=170):  #二值化
    """
    binary image
    Args:
        gray_image:image with gray scale
        threshold:the split standard
    Returns:
        bin image
    """
    threshold_image = np.zeros(shape=(gray_image.shape[0], gray_image.shape[1]), dtype=np.uint8)
    # loop for every pixel
    for i in range(gray_image.shape[0]):
        for j in range(gray_image.shape[1]):
            if gray_image[i][j] > threshold:
                threshold_image[i][j] = 1
            else:
                threshold_image[i][j] = 0
    return threshold_image

bin_image = thre_bin(img)

#3.腐蚀(写法1)
#定义一个3*3的卷积核
kernel=np.ones((3,3),np.uint8)
#图像腐蚀:cv2.erode(输入图像,卷积核,iterations=腐蚀的次数)

erosion = cv2.erode(bin_image, kernel,iterations=1)

plt.imshow(erosion,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

在这里插入图片描述

#3.腐蚀(写法2)#效果和方法1完全相同的,原理式写法
def erode_bin_image(img):#输入x为二值图像;#腐蚀

    K_size = 3
    #kernle
    K= np.array([[1, 1, 1],[1, 1, 1], [1, 1,1]],dtype=int)

    H, W = img.shape
    # zero padding
    pad = K_size // 2
    out = np.ones((H + pad * 2, W + pad * 2), dtype=np.int)*255
    out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
    tmp = out.copy()

    # filtering
    for y in range(H):
        for x in range(W):
                out[pad + y, pad + x] = np.min(K * (tmp[y: y + K_size, x: x + K_size]))
    #out = np.clip(out, 0, 255)  # 将值限制在给定的上下界
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)

    return out
    
erode_image=erode_bin_image(bin_image)
plt.imshow(erode_image,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show()   #效果和方法1完全相同
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

二、膨胀

膨胀的运算符是“⊕”,其定义如下:

在这里插入图片描述

该公式表示用B来对图像A进行膨胀处理,其中B是一个卷积模板或卷积核,其形状可以为正方形或圆形,通过模板B与图像A进行卷积计算,得出B覆盖区域的像素点最大值,并用该值替换参考点的像素值实现膨胀。

代码

cv2.dilate()函数

函数:
dst = cv2.dilate(src, kernel, iterations)
参数:
dst表示处理的结果,
src表示原图像,
kernel表示卷积核,
iterations表示迭代次数。
注意:迭代次数默认是1,表示进行一次膨胀,也可以根据需要进行多次迭代,进行多次膨胀。通常进行1次膨胀即可。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
#1.写法1
#此处bin_image是二值图像,如果输入图像不是二值图像,可用上面的代码处理
kernel=np.ones((3,3),np.uint8)
dilation=cv2.dilate(bin_image,kernel,iterations=1)
plt.imshow(dilation,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

#写法2,#效果和方法1完全相同的,原理式写法
def dilate_bin_image(img):#输入x为二值图像;#膨胀

    K_size = 3
    #kernle
    K= np.array([[1, 1, 1],[1, 1, 1], [1, 1,1]],dtype=int)

    H, W = img.shape
    # zero padding
    pad = K_size // 2
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
    tmp = out.copy()

    # filtering
    for y in range(H):
        for x in range(W):
                out[pad + y, pad + x] = np.max(K * (tmp[y: y + K_size, x: x + K_size]))
    #out = np.clip(out, 0, 255)  # 将值限制在给定的上下界
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)

    return out
dilate_image=dilate_bin_image(bin_image)
plt.imshow(dilate_image,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show()  #效果和方法1完全相同
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

开运算

开运算 = 先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了)
在这里插入图片描述

开运算总结:

  1. 开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不变。
  2. 开运算是一个基于几何运算的滤波器。
  3. 结构元素大小的不同将导致滤波效果的不同。
  4. 不同的结构元素的选择导致了不同的分割,即提取出不同的特征。

闭运算

闭运算 = 先膨胀运算,再腐蚀运算(看上去将两个细微连接的图块封闭在一起)
在这里插入图片描述
闭运算总结:

  1. 闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。

  2. 闭运算是通过填充图像的凹角来滤波图像的。

  3. 结构元素大小的不同将导致滤波效果的不同。

  4. 不同结构元素的选择导致了不同的分割。

总结

本文总结了腐蚀和膨胀的cv2函数写法和原理式python代码写法。并总结了开运算和闭运算的原理和作用。

参考:

python图像处理(八)——形态学运算之图像腐蚀与图像膨胀
基于Python和遥感图像的膨胀与腐蚀操作

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/441665
推荐阅读
相关标签
  

闽ICP备14008679号