Skip to content

形态学

形态学概述

  • 形态学是基于图像形态进行处理的一些基本方法
  • 这些处理方法基本是对二进制图像进行处理(黑白图像)
  • 卷积核决定着图像处理后的效果

形态学图像处理

  • 腐蚀与膨胀:腐蚀是让一块区域变小,膨胀是让一块区域变大
  • 开运算:腐蚀与膨胀的组合,先做腐蚀再做膨胀
  • 闭运算:腐蚀与膨胀的组合,先做膨胀再做腐蚀

图像全局二值化

  • 什么是二值化:将图像的每个像素变成两种值,如0, 255,将像素点要码变成白色要码变成黑色。
  • 全局二值化:比如自定义了一条线,全局 高于这条线就变成255,低于这条线就变成白色。弊端是由于光照不均匀及阴影的存在,只有一个阈值会使得在阴影处的白色被二值化成黑色
  • 局部二值化:全局二值化部分拆分成局部一小块一小块的做对比。
  • 全局二值化API:threshold(img, thresh, maxVal, type)

    1. img: 源,最好是灰度图
    2. thresh: 阈值
    3. maxVal: 超过阈值,替换成maxVal
    4. type: 二值化类型
      1. 二进制: THRESH_BINARY 和 THRESH_BINARY_INV
        • THRESH_BINARY 低于阈值就是0,高于阈值就是maxVal。
        • THRESH_BINARY_INV 低于阈值就是maxVal,高于阈值就是0。与THRESH_BINARY效果相反。
      2. THRESH_TRUNC
      3. THRESH_TOZERO 和 THRESH_TOZERO_INV

    import cv2
    
    img = cv2.imread('./fat.png')
    # 彩色转灰度
    img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 全局二值化
    ret, dst = cv2.threshold(img1, 180, 255, cv2.THRESH_BINARY)
    
    cv2.imshow('img', img)
    cv2.imshow('img1', img1)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)
    
    Image title

阈值类型

  • thresholdType
    Image title
    • truncate 削峰置平
    • threshold to zero, inverted 削峰置0
    • threshold to zero 非峰置0

自适应阈值二值化

  • API:adaptiveThreshold(img, maxVal, adaptiveMethod, type, blockSize, C)

    1. img: 源
    2. maxVal: 转换成的最大值是多少
    3. adaptiveMethod: 计算阈值的方法
      • ADAPTIVE_THRESH_MEAN_C: 计算邻近区域的平均值
      • ADAPTIVE_THRESH_GAUSSIAN_C: 高斯窗口加权平均值
    4. type: 只有两个THRESH_BINARYTHRESH_BINARY_INV
    5. blockSize: 邻近区域大小
    6. C: 常量,应从计算出的平均值或加权平均值中减去

    import cv2
    
    img = cv2.imread('math.png')
    img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    dst = cv2.adaptiveThreshold(img1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                            cv2.THRESH_BINARY, 11, 0)
    
    cv2.imshow('img', img)
    cv2.imshow('img1', img1)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)
    
    Image title

OpenCV腐蚀

  • 腐蚀的原理
    Image title
  • 腐蚀运算(3x3卷积核)
    Image title
  • 腐蚀效果
    Image title
  • 腐蚀API:erode(img, kernel, iterations=1)

    1. img: 源
    2. kernel: 卷积核
    3. iterations: 腐蚀次数

    import cv2
    import numpy as np
    
    img = cv2.imread('./j.png')
    kernel = np.ones((5, 5), np.uint8)
    
    dst = cv2.erode(img, kernel, iterations=1)
    
    cv2.imshow('img', img)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)
    
    Image title

获取形态学卷积核

  • 卷积核的类型
    • MORPH_RECT (通常情况下使用这个矩形,全部为1)
    • MORPH_ELLIPSE (椭圆形的,四个角变成0其余是1)
    • MORPH_CROSS (交叉轴十字架,横竖为1其余为0)
  • 获取卷积核
    • getStructuringElement(type, size)
      • type:为上面卷积核的类型
      • size:一般为(3,3) (5,5) (7,7)
        # 矩形
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
        print(kernel)
        '''
        [[1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]]
        '''
        
        # 椭圆
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
        print(kernel)
        '''
        [[0 0 0 1 0 0 0]
        [0 1 1 1 1 1 0]
        [1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]
        [1 1 1 1 1 1 1]
        [0 1 1 1 1 1 0]
        [0 0 0 1 0 0 0]]
        '''
        
        # 十字架
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
        print(kernel)
        '''
        [[0 0 0 1 0 0 0]
        [0 0 0 1 0 0 0]
        [0 0 0 1 0 0 0]
        [1 1 1 1 1 1 1]
        [0 0 0 1 0 0 0]
        [0 0 0 1 0 0 0]
        [0 0 0 1 0 0 0]]
        '''
        

OpenCV膨胀

  • 膨胀效果
    Image title
  • API:dilate(img, kernel, iterations=1)

    1. img: 源
    2. kernel: 卷积核
    3. iterations: 膨胀次数

    import cv2
    import numpy as np
    
    img = cv2.imread('./j.png')
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
    # 膨胀
    dst = cv2.dilate(img, kernel, iterations=1)
    cv2.imshow('img', img)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)
    
    Image title

开运算

  • 什么是开运算:开运算 = 腐蚀 + 膨胀
  • 开运算的效果:去除噪音
    Image title
  • 开运算API:morphologyEx(img, MORPH_OPEN, kernel)
    1. img: 源
    2. MORPH_OPEN: 开运算
    3. kernel: 卷积核
      import cv2
      import numpy as np
      
      kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
      img = cv2.imread('./dotj.png')
      # 开运算
      dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
      cv2.imshow('img', img)
      cv2.imshow('dst', dst)
      cv2.waitKey(0)
      
      Image title

闭运算

  • 什么是闭运算:闭运算 = 膨胀 + 腐蚀
  • 闭运算的效果:去除内部噪点
    Image title
  • 闭运算API:morphologyEx(img, MORPH_CLOSE, kernel)
    1. img: 源
    2. MORPH_OPEN: 开运算
    3. kernel: 卷积核
      import cv2
      import numpy as np
      
      kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
      img = cv2.imread('./dotinj.png')
      # 闭运算
      dst = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
      cv2.imshow('img', img)
      cv2.imshow('dst', dst)
      cv2.waitKey(0)
      
      Image title

形态学梯度

  • 什么是形态学梯度:梯度 = 原图 - 腐蚀
  • 梯度效果:计算边缘的时候可以用
    Image title
  • 梯度API:morphologyEx(img, MORPH_GRADIENT, kernel)
    1. img: 源
    2. MORPH_GRADIENT: 梯度
    3. kernel: 卷积核
      import cv2
      import numpy as np
      
      kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
      img = cv2.imread('./j.png')
      # 梯度
      dst1 = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
      cv2.imshow('img', img)
      cv2.imshow('dst', dst)
      cv2.waitKey(0)
      
      Image title

顶帽运算

  • 什么是顶帽运算:顶帽 = 原图 - 开运算
  • 顶帽运算效果:保留/去除指定噪点
  • 顶帽运算API:morphologyEx(img, MORPH_TOPHAT, kernel)
    1. img: 源
    2. MORPH_TOPHAT: 顶帽
    3. kernel: 卷积核
      import cv2
      import numpy as np
      
      #顶帽
      img = cv2.imread('./tophat.png')
      kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19, 19))
      dst1 = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
      
      cv2.imshow('img', img)
      cv2.imshow('dst', dst)
      cv2.waitKey(0)
      
      Image title

黑帽运算

  • 什么是黑帽运算:顶帽 = 原图 - 闭运算
  • 黑帽运算效果:一副图中求出小的噪点
  • 黑帽运算API:morphologyEx(img, MORPH_BLACKHAT, kernel)
    1. img: 源
    2. MORPH_BLACKHAT: 黑帽
    3. kernel: 卷积核
      import cv2
      import numpy as np
      
      #黑帽
      img = cv2.imread('./dotinj.png')
      kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
      dst1 = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
      
      cv2.imshow('img', img)
      cv2.imshow('dst', dst)
      cv2.waitKey(0)
      
      Image title

总结

  • 开运算,分腐蚀再膨胀,去除大图形外的小图形【MORPH_OPEN】
  • 闭运算,先膨胀再腐蚀,去除大图形内的小图形【MORPH_CLOSE】
  • 梯度,求图形的边缘【MORPH_GRADIENT】
  • 顶帽,原图减去开运算,得到大图形外的小图形【MORPH_TOPHAT】
  • 黑帽,原图减去闭运算,得到大图形内的小图形【MORPH_BLACKHAT】