• 形态学笔记:侵蚀+膨胀+开运算+闭运算+形态学梯度+顶帽运算+黑帽运算


    形态学

    一般在二值图上操作
    输入:原图、操作结构内核

    简单阈值

    对于每个像素,应用相同的阈值。如果像素值小于阈值,则将其设置为0,否则将其设置为最大值
    原图–>灰度图–>二值图

    logo = cv2.imread('./fans.jpg')
    # 参数1 被转换的图像
    # 参数2 原图转为灰度图
    logo_gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
    # 转为二值图
    # 参数1 灰度图
    # 参数2 阈值 小于阈值为0
    # 参数3 大于阈值为maxval
    # 参数4 类型    cv2.THRESH_BINARY   cv2.THRESH_OTSU 会自适应阈值
    # retval, logo_binary = cv2.threshold(logo_gray, 100, 255, cv2.THRESH_BINARY)
    retval, logo_binary = cv2.threshold(logo_gray, 100, 255, cv2.THRESH_OTSU)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    侵蚀

    内核在原图上滑动,内核框住的元素全为1才为1(保留1),否则为0(侵蚀)

    import cv2
    import numpy as np
    
    img = cv2.imread('./imgs/py_black.png')
    
    # kernel = np.ones((5, 5))
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 参数1 原图
    # 参数2 核
    # 参数3 侵蚀次数
    erode_img = cv2.erode(img, kernel, iterations=1)
    cv2.imshow('1', img)
    cv2.imshow('2', erode_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    原图

    image.png

    侵蚀后

    image.png

    膨胀

    内核在原图上滑动,内核框住的元素只要有1为1(膨胀),否则为0(保留0)

    import cv2
    import numpy as np
    
    img = cv2.imread('./imgs/py_black.png')
    # kernel = np.ones((5, 5))
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 参数1 原图
    # 参数2 核
    # 参数3 膨胀次数
    dilate_img = cv2.dilate(img, kernel, iterations=1)
    cv2.imshow('1', img)
    cv2.imshow('2', dilate_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    原图

    image.png

    膨胀后

    image.png

    开运算

    侵蚀+膨胀
    先侵蚀后膨胀,用于消除噪声

    import cv2
    import numpy as np
    
    img = cv2.imread('./imgs/py_open.png')
    # kernel = np.ones((5, 5))
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 参数1 原图
    # 参数2 形态操作的类型
    # 参数3 核
    # 参数3 侵蚀次数
    open_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=1)
    # erode_img = cv2.erode(img, kernel, iterations=1)
    # open_img = cv2.dilate(erode_img, kernel, iterations=1)
    
    cv2.imshow('1', img)
    cv2.imshow('2', open_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    原图

    image.png

    开运算后

    image.png

    闭运算

    膨胀+侵蚀
    先膨胀后侵蚀,用于消除图像中小的暗点

    import cv2
    import numpy as np
    
    img = cv2.imread('./imgs/py_close.png')
    # kernel = np.ones((5, 5))
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 参数1 原图
    # 参数2 形态操作的类型
    # 参数3 核
    # 参数3 侵蚀次数
    close_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=1)
    # dilate_img = cv2.dilate(img, kernel, iterations=1)
    # close_img = cv2.erode(dilate_img, kernel, iterations=1)
    
    cv2.imshow('1', img)
    cv2.imshow('2', close_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    原图

    image.png

    闭运算后

    image.png

    形态学梯度

    原图 - 侵蚀 = 轮廓线

    import cv2
    import numpy as np
    
    img = cv2.imread('./imgs/py_black.png')
    # kernel = np.ones((5, 5))
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 参数1 原图
    # 参数2 形态操作的类型
    # 参数3 核
    # 参数3 侵蚀次数
    gradient_img = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel, iterations=1)
    
    cv2.imshow('1', img)
    cv2.imshow('2', gradient_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    原图

    image.png

    梯度后

    image.png

    顶帽运算

    原图 - 开运算(侵蚀+膨胀) = 外部噪点

    import cv2
    import numpy as np
    
    img = cv2.imread('./imgs/py_open.png')
    # kernel = np.ones((5, 5))
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 参数1 原图
    # 参数2 形态操作的类型
    # 参数3 核
    # 参数3 侵蚀次数
    tophat_img = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel, iterations=1)
    
    cv2.imshow('1', img)
    cv2.imshow('2', tophat_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    原图

    image.png

    顶帽后

    image.png

    黑帽运算

    原图 - 闭运算(膨胀+侵蚀) = 内部噪点

    import cv2
    import numpy as np
    
    img = cv2.imread('./imgs/py_close.png')
    # kernel = np.ones((5, 5))
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    # 参数1 原图
    # 参数2 形态操作的类型
    # 参数3 核
    # 参数3 侵蚀次数
    blackhat_img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel, iterations=1)
    
    cv2.imshow('1', img)
    cv2.imshow('2', blackhat_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    原图

    image.png

    黑帽后

    image.png

  • 相关阅读:
    【自学记录】深度学习入门——基于Python的理论与实现(第3章 神经网络)
    从Java源码探索哈希表的前世今生
    RabbitMQ 入门系列:8、扩展内容:接收信息时:可否根据RoutingKey过滤监听信息,答案是不能。
    离线部署 python 3.x 版本
    (九)mmdetection源码解读:训练过程中训练数据的调用DataLoader
    数字孪生技术如何赋能智慧工厂
    Elasticsearch7 单节点与集群部署
    计算机网络总结
    【计算机网络】MTU和MSS
    WinPcap4.1.3安装失败解决方法,A newer version of winpcap...
  • 原文地址:https://blog.csdn.net/weixin_44240478/article/details/136378455