详细原理描述参考《学习opencv3》第10章 卷积与滤波
形态学操作是根据图像形状进行的的简单操作。一般情况下对二值化图像的操作。需要输入两个参数,一个是原始图像,第二个称为结构化元素或核,它是用来决定操作的性质的。两个基本的形态学操作是腐蚀和膨胀。他们的变体构成了开运算,闭运算,梯度等。
腐蚀是一种卷积操作(基本上所有的图像处理都是用卷积实现),它将目标像素替换为卷积核覆盖区域的局部最小值。这个操作会把前景物体的边界腐蚀掉,使前景变小。这对于去除噪声很有用,也可以用来断开两个连在一起的物体。
与腐蚀相反,膨胀将目标像素替换为卷积核覆盖区域的局部最大值,所以这个操作会增加图像中白色区域(前景)。一般在去噪音时先腐蚀再膨胀,因为腐蚀再去掉白噪音的同时,也会使前景对象变小,所以我们再膨胀。这时噪音已经被去除,不会再回来了,但是前景还在并会增加,膨胀也可以用来连接两个分开的物体。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
%matplotlib qt5
#通道转换函数,用plt显示opencv读取的图像
def bgr2rgb(img):
h,w,c = img.shape
b,g,r = cv.split(img)
img_rgb=cv.merge([r,g,b])
return img_rgb
img = cv.imread("E:\\opencv2020\\picture\\erzhi1.jpg")
kernel = np.ones((5,5),np.uint8)
erosion = cv.erode(img,kernel)
dilate = cv.dilate(img,kernel)
imgs=[img,erosion,dilate]
titles= ["input","erosion","dilate"]
for i in range(3):
plt.subplot(1,3,i+1)
plt.imshow(imgs[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
输出图像
先进行腐蚀再进行膨胀就叫做开运算。被用来去除噪音
img = cv.imread("E:\\opencv2020\\picture\\girl.jpg")
kernel = np.ones((11,11),np.uint8)
closing = cv.morphologyEx(img,cv.MORPH_CLOSE,kernel)
imgs=[img,closing]
imgs=[bgr2rgb(i) for i in imgs]
titles= ["input","closing"]
for i in range(2):
plt.subplot(1,2,i+1)
plt.imshow(imgs[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
输出图像
先膨胀再腐蚀。被用来填充前景物体中的小洞,或者前景上的小黑点
img = cv.imread("E:\\opencv2020\\picture\\girl2.jpg")
kernel = np.ones((7,7),np.uint8)
closing = cv.morphologyEx(img,cv.MORPH_CLOSE,kernel)
imgs=[img,closing]
imgs=[bgr2rgb(i) for i in imgs]
titles= ["input","closing"]
for i in range(2):
plt.subplot(1,2,i+1)
plt.imshow(imgs[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
输出图像,可以看到女孩脸上的色斑少了
其实就是一幅图像膨胀与腐蚀的差别。结果看上去就像前景物体的轮廓。
img = cv.imread("E:\\opencv2020\\picture\\j20.jpg")
kernel = np.ones((7,7),np.uint8)
gradient = cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel)
imgs=[img,gradient]
imgs=[bgr2rgb(i) for i in imgs]
titles= ["input","gradient"]
for i in range(2):
plt.subplot(1,2,i+1)
plt.imshow(imgs[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
输出图像
原始图像与进行开运算之后得到的图像的差。
进行闭运算之后得到的图像与原始图像的差
腐蚀 cv.erode()
膨胀 cv.dilate()
通用形态学函数 cv.morphologyEx()
img = cv.imread("E:\\opencv2020\\picture\\j20.jpg")
kernel = np.ones((7,7),np.uint8)
tophat = cv.morphologyEx(img,cv.MORPH_TOPHAT,kernel)
blackhat = cv.morphologyEx(img,cv.MORPH_BLACKHAT,kernel)
imgs=[img,tophat,blackhat]
imgs=[bgr2rgb(i) for i in imgs]
titles= ["input","tophat","blackhat"]
for i in range(3):
plt.subplot(1,3,i+1)
plt.imshow(imgs[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
输出图像