图像预处理-形态学变换
针对二值化图像,其有两个输入,一个输出:输入为原图像、核(结构化元素),输出为形态学变换后的图像。基本操作有腐蚀和膨胀。
一.核
联想到之前的卷积核,也是一种核。
此时的核就跟卷积核不太一样了,有自己的计算规则,对应元素相乘后不一定求和。
下面是常见的几种核:
二.腐蚀
与卷积核一样的移动方式,核中心对应的就是目标元素,然后依次从左往右、从上往下移动。腐蚀操作,取的是核操作后的最小值,以达到“变瘦”的效果。
cv2.erode(src, kernel, iterations)
- src : 输入图像
- kernel : 核,基本是奇数大小的正方形矩阵
- iterations : 迭代次数,默认值为1,表示只进行一次腐蚀操作,大于1则再从头开始进行腐蚀。
# 养成好习惯,代码自己敲
import numpy as np
import cv2 as cv# 直接灰度化
img = cv.imread('../images/huofu.png', cv.IMREAD_GRAYSCALE)# 二值化
ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY)# 进行腐蚀
kernel = np.ones((5, 5), np.uint8)
eroded = cv.erode(th, kernel, iterations=1)cv.imshow('binary', th)
cv.imshow('eroded', eroded)
cv.waitKey(0)
cv.destroyAllWindows()
三.膨胀
膨胀操作,取的是核操作后的最大值,以达到“变胖”的效果。
cv2.dilate(src, kernel, iterations)
import numpy as np
import cv2 as cv# 直接灰度化
img = cv.imread('../images/huofu.png', cv.IMREAD_GRAYSCALE)# 二值化
ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY)# 进行膨胀
kernel = np.ones((5, 5), np.uint8)
dilate = cv.dilate(th, kernel, iterations=1)cv.imshow('binary', th)
cv.imshow('dilate', dilate)
cv.waitKey(0)
cv.destroyAllWindows()
四.开运算(cv2.MORPH_OPEN)
开运算是先腐蚀后膨胀,其作用是消除噪点,去除小的干扰块,而不影响原来的图像
它和下面的运算用的都是同一种函数,只不过传入的方法不一样。
cv.morphologyEx(src, method, kernel)
- src : 输入图像
- method : 运算的方法
import numpy as np
import cv2 as cv# 直接灰度化
img = cv.imread('../images/huofu.png', cv.IMREAD_GRAYSCALE)# 二值化
ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY)# 开运算
kernel = np.ones((5, 5), np.uint8)
opening = cv.morphologyEx(th, cv.MORPH_OPEN, kernel)cv.imshow('binary', th)
cv.imshow('open', opening)
cv.waitKey(0)
cv.destroyAllWindows()
五.闭运算(cv2.MORPH_CLOSE)
先膨胀后腐蚀,作用是消除“闭合”物体里面的孔洞
import numpy as np
import cv2 as cv# 直接灰度化
img = cv.imread('../images/huofu.png', cv.IMREAD_GRAYSCALE)# 二值化
ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)# 闭运算
kernel = np.ones((5, 5), np.uint8)
closing = cv.morphologyEx(th, cv.MORPH_CLOSE, kernel)cv.imshow('binary', th)
cv.imshow('close', closing)
cv.waitKey(0)
cv.destroyAllWindows()
六.顶帽运算(cv2.MORPH_TOPHAT)
原图像与“开运算“的结果图之差,得到白色噪点。
用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用礼帽运算进行背景提取
import numpy as np
import cv2 as cv# 直接灰度化
img = cv.imread('../images/huofu.png', cv.IMREAD_GRAYSCALE)# 二值化
ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY)# 顶帽运算
kernel = np.ones((5, 5), np.uint8)
top = cv.morphologyEx(th, cv.MORPH_TOPHAT, kernel)cv.imshow('binary', th)
cv.imshow('top', top)
cv.waitKey(0)
cv.destroyAllWindows()
七.黑帽运算
原图像与“闭运算“的结果图之差,得到黑色噪点。
用来分离比邻近点暗一些的斑块
import numpy as np
import cv2 as cv# 直接灰度化
img = cv.imread('../images/huofu.png', cv.IMREAD_GRAYSCALE)# 二值化
ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)# 黑帽运算
kernel = np.ones((5, 5), np.uint8)
black = cv.morphologyEx(th, cv.MORPH_BLACKHAT, kernel)cv.imshow('binary', th)
cv.imshow('black', black)
cv.waitKey(0)
cv.destroyAllWindows()
八.形态学梯度
通过比较原图像与膨胀图和腐蚀图之间的差异来突出图像边缘特征。对于图像中的每个像素点,其形态学梯度值是该像素点在膨胀后的图像值与其在腐蚀后的图像值之差
通常能够强化图像的边缘信息,并且对噪声有一定的抑制作用
import numpy as np
import cv2 as cv# 直接灰度化
img = cv.imread('../images/huofu.png', cv.IMREAD_GRAYSCALE)# 二值化
ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY)# 形态学梯度
kernel = np.ones((5, 5), np.uint8)
xtx = cv.morphologyEx(th, cv.MORPH_GRADIENT, kernel)cv.imshow('binary', th)
cv.imshow('xtx', xtx)
cv.waitKey(0)
cv.destroyAllWindows()