Python图像形态学操作:膨胀、腐蚀、开运算和闭运算详解

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

文章目录

  • 图像形态学操作——膨胀,腐蚀;开运算,闭运算
  • 一、图像腐蚀
  • 代码:
  • 二、膨胀
  • 代码
  • 开运算
  • 闭运算
  • 总结
  • 参考:

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

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

    图像的膨胀(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.读取图片
    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()
    

    原图

    #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()
    

    #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完全相同
    

    二、膨胀

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

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

    代码

    cv2.dilate()函数

    函数:
    dst = cv2.dilate(src, kernel, iterations)
    参数:
    dst表示处理的结果,
    src表示原图像,
    kernel表示卷积核,
    iterations表示迭代次数。
    注意:迭代次数默认是1,表示进行一次膨胀,也可以根据需要进行多次迭代,进行多次膨胀。通常进行1次膨胀即可。
    
    #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()
    
    

    #写法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. 不同的结构元素的选择导致了不同的分割,即提取出不同的特征。

    闭运算

    闭运算 = 先膨胀运算,再腐蚀运算(看上去将两个细微连接的图块封闭在一起)

    闭运算总结:

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

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

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

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

    总结

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

    参考:

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

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python图像形态学操作:膨胀、腐蚀、开运算和闭运算详解

    发表评论