形态学
形态学概述
- 形态学是基于图像形态进行处理的一些基本方法
- 这些处理方法基本是对二进制图像进行处理(黑白图像)
- 卷积核决定着图像处理后的效果
形态学图像处理
- 腐蚀与膨胀:腐蚀是让一块区域变小,膨胀是让一块区域变大
- 开运算:腐蚀与膨胀的组合,先做腐蚀再做膨胀
- 闭运算:腐蚀与膨胀的组合,先做膨胀再做腐蚀
图像全局二值化
- 什么是二值化:将图像的每个像素变成两种值,如0, 255,将像素点要码变成白色要码变成黑色。
- 全局二值化:比如自定义了一条线,全局 高于这条线就变成255,低于这条线就变成白色。弊端是由于光照不均匀及阴影的存在,只有一个阈值会使得在阴影处的白色被二值化成黑色
- 局部二值化:全局二值化部分拆分成局部一小块一小块的做对比。
-
全局二值化API:
threshold(img, thresh, maxVal, type)
img
: 源,最好是灰度图thresh
: 阈值maxVal
: 超过阈值,替换成maxValtype
: 二值化类型- 二进制: THRESH_BINARY 和 THRESH_BINARY_INV
- THRESH_BINARY 低于阈值就是0,高于阈值就是maxVal。
- THRESH_BINARY_INV 低于阈值就是maxVal,高于阈值就是0。与THRESH_BINARY效果相反。
- THRESH_TRUNC
- THRESH_TOZERO 和 THRESH_TOZERO_INV
- 二进制: THRESH_BINARY 和 THRESH_BINARY_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)
阈值类型
自适应阈值二值化
-
API:
adaptiveThreshold(img, maxVal, adaptiveMethod, type, blockSize, C)
img
: 源maxVal
: 转换成的最大值是多少adaptiveMethod
: 计算阈值的方法- ADAPTIVE_THRESH_MEAN_C: 计算邻近区域的平均值
- ADAPTIVE_THRESH_GAUSSIAN_C: 高斯窗口加权平均值
type
: 只有两个THRESH_BINARY
、THRESH_BINARY_INV
blockSize
: 邻近区域大小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)
OpenCV腐蚀
- 腐蚀的原理
- 腐蚀运算(3x3卷积核)
- 腐蚀效果
-
腐蚀API:
erode(img, kernel, iterations=1)
img
: 源kernel
: 卷积核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)
获取形态学卷积核
- 卷积核的类型
- 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膨胀
- 膨胀效果
-
API:
dilate(img, kernel, iterations=1)
img
: 源kernel
: 卷积核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)
开运算
闭运算
形态学梯度
顶帽运算
- 什么是顶帽运算:顶帽 = 原图 - 开运算
- 顶帽运算效果:保留/去除指定噪点
- 顶帽运算API:
morphologyEx(img, MORPH_TOPHAT, kernel)
黑帽运算
- 什么是黑帽运算:顶帽 = 原图 - 闭运算
- 黑帽运算效果:一副图中求出小的噪点
- 黑帽运算API:
morphologyEx(img, MORPH_BLACKHAT, kernel)
总结
- 开运算,分腐蚀再膨胀,去除大图形外的小图形【MORPH_OPEN】
- 闭运算,先膨胀再腐蚀,去除大图形内的小图形【MORPH_CLOSE】
- 梯度,求图形的边缘【MORPH_GRADIENT】
- 顶帽,原图减去开运算,得到大图形外的小图形【MORPH_TOPHAT】
- 黑帽,原图减去闭运算,得到大图形内的小图形【MORPH_BLACKHAT】