• python --opencv图像处理形态学(开运算、闭运算、梯度运算、顶帽运算、黑帽运算)


    引言

    前面介绍了图像形态学的两种基础算法,图像腐蚀和图像膨胀,本篇接着介绍图像形态学中的开运算、闭运算以及梯度运算。
    需要了解清楚图像的腐蚀与膨胀基础原理,不然真的没办法理解开运算和闭运算。

    第一件事情还是给图像增加噪声,思路沿用之前加噪声的思路,使用 Numpy 给图片添加黑白两种噪声点,代码如下

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    img = cv.imread("demo.png", cv.IMREAD_UNCHANGED)
    source = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    rows, cols, chn = source.shape
    
    # 加噪声-白点噪声
    for i in range(500):
        x = np.random.randint(0, rows)
        y = np.random.randint(0, cols)
        source[x, y, :] = 255
    
    # 图像保存 白点噪声图像
    cv.imwrite("demo_noise_white.jpg", source)
    print("白点噪声添加完成")
    
    # 重新读取图像
    img1 = cv.imread("demo.png", cv.IMREAD_UNCHANGED)
    source1 = cv.cvtColor(img1, cv.COLOR_BGR2RGB)
    
    # 加噪声-黑点噪声
    for i in range(1000):
        x = np.random.randint(0, rows)
        y = np.random.randint(0, cols)
        source1[x, y, :] = 0
    
    # 图像保存 黑点噪声图像
    cv.imwrite("demo_noise_black.jpg", source1)
    print("黑点噪声添加完成")
    
    # 显示结果
    titles = ['White Img','Black Img']
    images = [source, source1]
    
    # matplotlib 绘图
    for i in range(2):
       plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述

    开运算

    图像开运算实际上是一个组合运算,开运算是图像先进行腐蚀,再进行膨胀的运算。

    图像被腐蚀后,去除了噪声,但是也压缩了图像;接着对腐蚀过的图像进行膨胀处理,使得刚才在腐蚀过程中被压缩的图像得以恢复原状。

    下面是一个图像开运算的流程图:
    在这里插入图片描述

    开运算的一些特性:

    • 开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不便。
    • 开运算是一个基于几何运算的滤波器。
    • 结构元素大小的不同将导致滤波效果的不同。
    • 不同的结构元素的选择导致了不同的分割,即提取出不同的特征。
    • 我们先不管开运算 OpenCV 为我们提供的函数是什么,先使用前面介绍过的图像腐蚀与膨胀处理看下结果

    案例:

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    source = cv.imread("demo_noise_white.jpg", cv.IMREAD_GRAYSCALE)
    
    # 设置卷积核
    kernel = np.ones((5, 5),np.uint8)
    
    # 图像腐蚀
    erode_img = cv.erode(source, kernel)
    
    # 图像膨胀
    dilate_result = cv.dilate(erode_img, kernel)
    
    # 显示结果
    titles = ['Source Img','Erode Img','Dilate Img']
    images = [source, erode_img, dilate_result]
    
    # matplotlib 绘图
    for i in range(3):
       plt.subplot(1, 3, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述
    可以看到降噪的效果还是不错的。

    接着看 OpenCV 为开运算提供的函数。

    图像开运算主要使用到的函数是 morphologyEx() 它是形态学扩展的一组函数,而其中的 cv.MORPH_OPEN 对应的是开运算。

    使用时语法如下:

    dst = cv.morphologyEx(src, cv.MORPH_OPEN, kernel)
    
    • 1
    • src:原图形
    • cv2.MORPH_OPEN:表示开运算
    • kernel:卷积核

    我们再使用 morphologyEx() 函数去重新实现下刚才的图像开运算,看下和之前的结果有啥区别:

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    source = cv.imread("demo_noise_white.jpg", cv.IMREAD_GRAYSCALE)
    
    # 设置卷积核
    kernel = np.ones((5, 5),np.uint8)
    
    #图像开运算
    dst = cv.morphologyEx(source, cv.MORPH_OPEN, kernel)
    
    # 显示结果
    titles = ['Source Img','Dst Img']
    images = [source, dst]
    
    # matplotlib 绘图
    for i in range(2):
       plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述
    至少从肉眼的角度上看不出来和之前的方式有啥区别,实际上也没啥区别。

    闭运算

    与开运算相反的是闭运算,闭运算是图像先膨胀,后腐蚀,它有助于关闭前景物体内部的小孔,或物体上的小黑点。

    先看下图像闭运算的流程图:

    在这里插入图片描述

    闭运算的一些特性:

    • 闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
    • 闭运算是通过填充图像的凹角来滤波图像的。
    • 结构元素大小的不同将导致滤波效果的不同。
    • 不同结构元素的选择导致了不同的分割。

    首先还是用 dilate()erode() 函数实现一下图像闭运算,代码如下:

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    source = cv.imread("demo_noise_black.jpg", cv.IMREAD_GRAYSCALE)
    
    # 设置卷积核
    kernel = np.ones((5, 5),np.uint8)
    
    # 图像膨胀
    dilate_result = cv.dilate(source, kernel)
    
    # 图像腐蚀
    erode_img = cv.erode(dilate_result, kernel)
    
    # 显示结果
    titles = ['Source Img','Dilate Img','Erode Img']
    images = [source, dilate_result, erode_img]
    
    # matplotlib 绘图
    for i in range(3):
       plt.subplot(1, 3, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述
    如果想要使用形态学扩展的函数 morphologyEx() 则需要把里面的参数换成 MORPH_CLOSE ,同样,既然是形态学扩展函数,那么图像腐蚀和图像膨胀也有对应的参数:

    • 图像腐蚀:MORPH_ERODE
    • 图像膨胀:MORPH_DILATE

    接着还是使用 MORPH_CLOSE 参数来实现下图像的闭运算:

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    source = cv.imread("demo_noise_black.jpg", cv.IMREAD_GRAYSCALE)
    
    # 设置卷积核
    kernel = np.ones((5, 5),np.uint8)
    
    # 图像闭运算
    dst = cv.morphologyEx(source, cv.MORPH_CLOSE, kernel)
    
    # 显示结果
    titles = ['Source Img','Dst Img']
    images = [source, dst]
    
    # matplotlib 绘图
    for i in range(2):
       plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述

    梯度运算

    图像形态学的梯度运算和前面的开运算闭运算是一样的,都是组合函数。

    梯度运算实际上是图像膨胀减去图像腐蚀后的结果,最终我们得到的是一个类似于图像轮廓的图形。
    在这里插入图片描述
    梯度运算在 morphologyEx() 函数中的参数是 MORPH_GRADIENT ,示例代码如下:

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    source = cv.imread("demo.png", cv.IMREAD_GRAYSCALE)
    
    # 设置卷积核
    kernel = np.ones((5, 5), np.uint8)
    
    # 图像梯度运算
    dst = cv.morphologyEx(source, cv.MORPH_GRADIENT, kernel)
    
    # 显示结果
    titles = ['Source Img','Dst Img']
    images = [source, dst]
    
    # matplotlib 绘图
    for i in range(2):
       plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述

    顶帽运算

    图像处理顶帽运算是一个获取图像噪声的运算,它是由原始图像减去图像开运算而得到的结果:

    顶帽运算 = 原始图像 - 开运算

    在这里插入图片描述
    图像顶帽运算同样是使用形态学扩展函数 morphologyEx() ,它的参数是 MORPH_TOPHAT ,示例如下:

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    source = cv.imread("demo_noise_white.jpg", cv.IMREAD_GRAYSCALE)
    
    # 设置卷积核
    kernel = np.ones((5, 5), np.uint8)
    
    # 开运算
    open = cv.morphologyEx(source, cv.MORPH_OPEN, kernel)
    
    # 顶帽运算
    dst = cv.morphologyEx(source, cv.MORPH_TOPHAT, kernel)
    
    # 显示结果
    titles = ['Source Img','Open Img', 'Tophat Img']
    images = [source, open, dst]
    
    # matplotlib 绘图
    for i in range(3):
       plt.subplot(1, 3, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述

    黑帽运算

    图像处理顶帽运算是一个获取图像内部的小孔,或者前景色中的小黑点的运算。

    它是由图像闭运算减去原始图像的操作:

    黑帽运算 = 闭运算图像 - 原始图像

    在这里插入图片描述

    图像顶帽运算同样是使用形态学扩展函数 morphologyEx() ,它的参数是 MORPH_BLACKHAT ,示例如下:

    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 读取图片
    source = cv.imread("demo_noise_black.jpg", cv.IMREAD_GRAYSCALE)
    
    # 设置卷积核
    kernel = np.ones((5, 5), np.uint8)
    
    # 黑帽运算
    dst = cv.morphologyEx(source, cv.MORPH_BLACKHAT, kernel)
    
    # 构造显示结果数组
    titles = ['Source Img', 'Black Img']
    images = [source, dst]
    
    # matplotlib 绘图
    for i in range(2):
       plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
       plt.title(titles[i])
       plt.xticks([]),plt.yticks([])
    
    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

    在这里插入图片描述

  • 相关阅读:
    100家!第一批5G应用解决方案供应商推荐名录
    【C/C++】函数指针与指针函数
    多御安全浏览器超强版本发布:新增密码检查功能
    python默认的输入类型是字符串,怎样转换为其他的类型
    XLSReadWriteII 读取EXCEL数据 动态响应字段的列编号
    Kotlin难点
    使用Java实现电影权限管理系统
    ELK安装、部署、调试 (二) ES的安装部署
    通过构造函数中设置_前端培训
    VMware虚拟机安装运行MacOS系统
  • 原文地址:https://blog.csdn.net/weixin_44634704/article/details/126487259