opencv 图像形态学转换
??学习不同的形态学操作,例如腐蚀,膨胀,开运算,闭运算等
??学习的函数有:cv2.erode(), cv2.dilate(), cv2.morphologyEx()等
原理
??形态学操作是根据图像形状进行的简单操作,一般情况下对二值化图像进行的操作。需要输入两个参数,一个是原始图像,第二个被称为结构化元素或核,它是用来决定操作的性质的。两个基本的形态学操作是腐蚀和膨胀。他们的变体构成了开运算,闭运算,梯度等。
1、腐蚀
??就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉,卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是 1,那么中心元素就保持原来的像素值,否则就变为零。根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为 0),所以前景物体会变小,这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。
??这里个例子,使用一个 5x5 的卷积核,其中所有的值都是1。
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('image/2.png')
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img, kernel,iterations=1)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(erosion),plt.title('erosion')
plt.xticks([]),plt.yticks([])
plt.show()
结果图:
文章图片
2、 膨胀
??与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是 1,中心元素的像素值就是 1。所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小,所以再对其进行膨胀,这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('image/2.png')
kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(img, kernel,iterations=1)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(dilation),plt.title('dilation')
plt.xticks([]),plt.yticks([])
plt.show()
结果图:
文章图片
3 、开运算 ??先进行腐蚀再进行膨胀就叫做开运算,被用来去除噪声。这里我们用到的函数是 cv2.morphologyEx()。
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('image/2.png')
kernel = np.ones((5,5),np.uint8)
for i in range(2000):
temp_x = np.random.randint(0,img.shape[0])
temp_y = np.random.randint(0,img.shape[1])
img[temp_x][temp_y] = 255
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(opening),plt.title('opening')
plt.xticks([]),plt.yticks([])
plt.show()
结果图:
文章图片
4、 闭运算 ??先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的小黑点。
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('image/3.png')
kernel = np.ones((5,5),np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(closing),plt.title('closing')
plt.xticks([]),plt.yticks([])
plt.show()
结果图:
文章图片
5 、形态学梯度
??其实就是一幅图像膨胀与腐蚀的差别,结果看上去就像前景物体的轮廓。
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('image/2.png')
kernel = np.ones((5,5),np.uint8)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(gradient),plt.title('gradient')
plt.xticks([]),plt.yticks([])
plt.show()
结果图:
文章图片
6、 礼帽 原始图像与进行开运算之后得到的图像的差。9*9核
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('image/2.png')
kernel = np.ones((9,9),np.uint8)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(tophat),plt.title('tophat')
plt.xticks([]),plt.yticks([])
plt.show()
结果图:
文章图片
7 、黑帽 进行闭运算之后得到的图像与原始图像的差。
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('image/2.png')
kernel = np.ones((9,9),np.uint8)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
plt.subplot(1,2,1),plt.imshow(img),plt.title('Original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,2,2),plt.imshow(blackhat),plt.title('blackhat')
plt.xticks([]),plt.yticks([])
plt.show()
结果图:
文章图片
8 、形态学操作之间的关系
【opencv 图像形态学转换】我们把以上集中形态学操作之间的关系列出来以供大家参考
文章图片
参考:OpenCV官方教程中文版(For Python)
推荐阅读
- opencv|opencv C++模板匹配的简单实现
- Java|Java OpenCV图像处理之SIFT角点检测详解
- ImageLoaders 加载图像
- JAVA图像处理系列(四)——噪声
- OpenCV|OpenCV-Python实战(18)——深度学习简介与入门示例
- 使用交叉点观察器延迟加载图像以提高性能
- OpenCV|OpenCV for Unity 通过WebCamTextureToMatHelper帮助类来获取摄像头的画面
- Figure|Figure 图像
- 【数组题】给定一个二进制矩阵|【数组题】给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。
- opencv学习