• 【opencv图像处理】-- 5.形态学(膨胀、腐蚀、开闭运算、顶帽、黑帽、二值化)


    系列所有代码,复制粘贴即可运行。
    希望有能力的朋友还是拿C++运行一下。

    本节讨论图像的二值化,局部二值化,膨胀,腐蚀,开运算,闭运算,顶帽,黑帽等

    形态学

    仍然是利用卷积核,来测量或提取输入图像中相应的形状或特征,以便进一步进行图像分析和目标识别,基本操作有(基本都处理二进制图像):

    • 膨胀和腐蚀
    • 开运算
    • 闭运算
    • 顶帽
    • 黑帽

    • 形态学的魅力就在于可以获取各种形态的图形,感兴趣区域,噪点等

    1. 二值化

    1.1 图像全局二值化

    threshold(src, thresh, maxval, type[,dst])

    • src: 灰度图
    • thresh:阈值
    • maxval:最大值
    • type:操作类型,开窗,截断等
    import cv2
    import numpy as np
    
    img = cv2.imread('cat.jpeg')
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 阈值  处理后图片
    ret, dst = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)
    #print(dst)
    cv2.imshow('dog', np.hstack((gray, dst)))
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.2 自适应二值化

    同一图像上,不同部分具有不同亮度时。根据图像上每一个小区域计算与其对应的阈值,从而能在亮度不同的情况下得到更好的结果

    • adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])
      • adaptiveMethod:指定计算阈值的方法
        1. cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域平均值
        2. cv2.ADPTIBE_THRESH_GAUSSIAN_C:阈值取自相邻区域的加权和,权重为一高斯窗口
      • Block Size: 邻域(卷积核)大小
      • C: 阈值等于计算结果加上这个常数
    #自适应阈值只返回一个值,即二值化后的图像
    ##这里的kernel size仍然只是一个数
    dst = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,21,0)
    #print(dst)
    
    • 1
    • 2
    • 3
    • 4

    2. 腐蚀

    腐蚀操作也是用卷积核扫描图像,大部分腐蚀操作的卷积核内数字都是1,卷积操作就是相乘再相加

    • 核中1所在的位置:全白(255)才为白,有黑(0)则为黑
    • erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
    1. iterations是腐蚀操作的迭代次数,次数越多,效果越明显
    2. 腐蚀操作是放大暗部

    2.1 自定义kernel

    import cv2
    import numpy as np
    
    cat = cv2.imread('homework.jpg')
    img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
    
    #定义核
    kernel = np.ones((5,5), np.uint8)
    
    dst = cv2.erode(img, kernel, iterations=1)
    
    cv2.imshow('cat', np.hstack((img, dst)))
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.2 获取形态学kernel

    • getStructuringElement(shape, ksize[, anchor])
      • shape: 卷积核形状,不是长款,是卷积核中1的元素所形成的形状
        • MORPH_RECT 卷积核中1的形成矩形
        • MORPH_ELLIPSE 椭圆
        • MORPH_CROSS 十字
    import cv2
    import numpy as np
    
    cat = cv2.imread('homework.jpg')
    img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
    
    #自主获取的卷积核
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    
    dst = cv2.erode(img, kernel, iterations=1)
    
    cv2.imshow('cat', np.hstack((img, dst)))
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3. 膨胀

    膨胀是腐蚀的反操作,只要保证卷积核的锚点是非0值,周边值均变为非零值

    • 膨胀是放大白色
    • 核中1对应的位置:有白(255)则为白,全黑(0)才为黑/对锚点而言
    • dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
    import cv2
    import numpy as np
    
    cat = cv2.imread('homework.jpg')
    img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
    
    #定义核
    #kernel = np.ones((5,5), np.uint8)
    
    #自主获取的卷积核
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    
    
    dst = cv2.dilate(img, kernel, iterations=1)
    
    cv2.imshow('cat', np.hstack((img, dst)))
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4. 开运算

    • 开运算 = 先腐蚀 + 后膨胀
    • 适用: 黑背景 白噪点
    • morphologyEx(img, MORPH_OPEN, kernel)
      • MORPH_OPEN: 形态学的开运算
      • kernel 如果噪点较多 选择大一点的kernel,如果噪点较少,选择小点的kernel
    #开运算提供了另一种去噪声的思路
    cat = cv2.imread('cat.jpeg')
    img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
    
    #腐蚀
    #dst = cv2.erode(img, kernel, iterations=2)
    #膨胀
    #dst = cv2.dilate(img,kernel, iterations=2)
    
    #直接调用opencv提供的开运算
    dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=2)
    
    cv2.imshow('img', np.hstack((img, dst)))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    5. 闭运算

    • 闭运算 = 先膨胀 + 后腐蚀
    • 适用:白背景 黑噪点
    • morphologyEx(img, MORPH_CLOSE, kernel)
      • MORPH_CLOSE: 形态学的闭运算
      • kernel 如果噪点较多 选择大一点的kernel,如果噪点较少,选择小点的kernel
    
    cat = cv2.imread('cat.jpeg')
    img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
    
    #膨胀
    #dst = cv2.dilate(img,kernel, iterations=2)
    #腐蚀
    #dst = cv2.erode(img, kernel, iterations=2)
    
    
    #直接调用opencv提供的开运算
    dst = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=2)
    
    cv2.imshow('img', np.hstack((img, dst)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    6. 形态学梯度

    • 梯度 = 原图图像 - 腐蚀的图像
    • 腐蚀之后原图边缘变小了,做差后就可以得到腐蚀掉的部分,即边缘
    • morphologyEx(img, MORPH_GRADIENT, kernel)
      • MORPH_GRADIENT: 形态学梯度
    import cv2
    import numpy as np
    
    cat = cv2.imread('cat.jpeg')
    img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
    
    #调节kernel大小获得更清晰的边缘,腐蚀掉的东西
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    
    dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel, iterations=1)
    
    cv2.imshow('img', np.hstack((img, dst)))
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    7. 顶帽操作

    • 顶帽 = 原图 - 开运算
    • 黑图取被滤的白噪点
    • 开运算的效果是去除噪点,顶帽得到了去掉的噪点
    • morphologyEx(img, MORPH_TOPHAT, kernel)
      • MORPH_TOPHAT: 顶帽操作
    cat = cv2.imread('cat.jpeg')
    img = cv2.cvtColor(cat, cv2.COLOR_BGR2GRAY)
    
    #调节kernel大小以保留小图形
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19,19))
    
    
    dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel, iterations=1)
    
    cv2.imshow('img', np.hstack((img, dst)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    8. 黑帽操作

    • 黑帽 = 原图 - 闭运算
    • 白中取被滤的黑噪点
    • 闭运算的效果是去除图像内部的噪点,黑帽得到了图形内部去掉的噪点
    • morphologyEx(img, MORPH_BLACKHAT, kernel)
      • MORPH_BLACKHAT: 黑帽操作
  • 相关阅读:
    Modbus协议介绍及Modbus TCP
    信号与进程间通信
    云原生时代:从 Jenkins 到 Argo Workflows,构建高效 CI Pipeline
    centos7.9离线升级openssl和openssh9.2
    vue本地开发设置代理连接本地后台服务
    蓝牙技术|物联网的可穿戴设备新工作模式,蓝牙BLE助力新工作模式
    c++ 并发与多线程(12)线程安全的单例模式-1
    rust 快速一览
    希尔排序算法(思路分析) [数据结构][Java]
    美国DDoS服务器:如何保护你的网站免遭攻击?
  • 原文地址:https://blog.csdn.net/Eric_Sober/article/details/126053207