形态学处理【一】
- 形态学概念,腐蚀,膨胀
- 相关函数有:cv2.erode(),cv2.dilate(),cv2.getStructuringElement()
一、形态学
-
形态学(morphology)常应用在生物学中,研究动植物的形态和结构;
-
图像形态学即数学形态学(Mathematical morphology)是一门建立在格伦和拓扑学基础上的图像分析学科,是数学形态学图像处理的基本理论;
-
常见图像形态学运算:腐蚀、膨胀、开运算、闭运算、骨架抽取、极线腐蚀、击中击不中变换、Top-hat变换、颗粒分析、流域变换、形态学梯度等;
膨胀和腐蚀概念
-
最基本的形态学操作是:膨胀(dilation)和腐蚀(erosion);
-
形态学操作是根据图像形状进行的简单操作。一般情况下对二值化图像进行的操作。需要输入两个参数,一个是原始图像,第二个被称为结构化元素或核,它是用来决定操作的性质的。
-
形态学操作其实就是改变物体的形状,比如腐蚀就是”变瘦”,膨胀就是”变胖”。
-
腐蚀和膨胀是对像素值大的部分而言的,即高亮白部分而不是黑色部分;
-
膨胀就是图像中的高亮部分进行膨胀,效果图拥有比原图更大的高亮区域。
-
腐蚀就是原图中的高亮部分被腐蚀,效果图拥有比原图更小的高亮区域。
膨胀和腐蚀的主要用途:
-
消除噪声;
-
分割出独立的图像元素,在图像中连接相邻的元素;
-
寻找图像中明显的极大值或极小值区;
-
求出图像的梯度;
二、结构元素
-
膨胀或者腐蚀操作可以看做 将图像(或图像的一部分区域,我们称之为A)与核(我们称之为B)进行卷积。
-
核可以是任何的形状和大小,它拥有一个单独定义出来的参考点,我们称其为锚点(anchorpoint)。多数情况下,核是一个小的中间带有参考点和实心正方形或者圆盘,其实,我们可以把核视为模板或者掩码。
-
这个核也叫结构元素,因为形态学操作其实也是应用卷积来实现的。结构元素可以是矩形/椭圆/十字形,可以用cv2.getStructuringElement()来生成不同形状的结构元素,比如:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 矩形结构
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # 椭圆结构
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) # 十字结构
三、腐蚀
-
就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉(但是前景仍然是白色)。这是怎么做到的呢?卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是 1,那么中心元素就保持原来的像素值,否则就变为零。 这回产生什么影响呢?根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为 0),所以前景物体会变小,整幅图像的白色区域会减少。这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。
-
腐蚀是图像中的高亮部分被腐蚀掉,效果图拥有比原图更小的高亮区域;
-
腐蚀可以简单理解为消除物体A所有边界点的过程。
OpenCV中用cv2.erode()函数进行腐蚀,只需要指定核的大小就行:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('tiger.jpg',1)
# 通过numpy构建矩形结构元素
kernel = np.ones((10,10),np.uint8)
# cv2.getStructuringElement()来生成不同形状的结构元素
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10)) # 矩形结构
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) # 椭圆结构
kernel3 = cv2.getStructuringElement(cv2.MORPH_CROSS, (10, 10)) # 十字结构
# 腐蚀
erosion = cv2.erode(img,kernel,iterations = 1)
erosion1 = cv2.erode(img,kernel1,iterations = 1)
erosion2 = cv2.erode(img,kernel2,iterations = 1)
erosion3 = cv2.erode(img,kernel3,iterations = 1)
# 显示图像
plt.figure(figsize = (20,15))
plt.subplot(151),plt.imshow(img),plt.title('Original'),plt.xticks([]), plt.yticks([])
plt.subplot(152),plt.imshow(erosion),plt.title('ones'),plt.xticks([]), plt.yticks([])
plt.subplot(153),plt.imshow(erosion1),plt.title('RECT'),plt.xticks([]), plt.yticks([])
plt.subplot(154),plt.imshow(erosion2),plt.title('ELLIPSE'),plt.xticks([]), plt.yticks([])
plt.subplot(155),plt.imshow(erosion3),plt.title('CROSS'),plt.xticks([]), plt.yticks([])
plt.show()
四、膨胀
与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是 1,中心元素的像素值就是 1。所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小。所以我们再对他进行膨胀。这时噪声已经被去除了,不会再回来了,但前景还在并会增加。膨胀也可以用来连接两个分开的物体。
膨胀是图像中的高亮部分进行膨胀,效果图拥有比原图更大的高亮区域;
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('tiger.jpg',1)
# 通过numpy构建矩形结构元素
kernel = np.ones((10,10),np.uint8)
# cv2.getStructuringElement()来生成不同形状的结构元素
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10)) # 矩形结构
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) # 椭圆结构
kernel3 = cv2.getStructuringElement(cv2.MORPH_CROSS, (10, 10)) # 十字结构
# 腐蚀
dilation = cv2.dilate(img,kernel,iterations = 1)
dilation1 = cv2.dilate(img,kernel1,iterations = 1)
dilation2 = cv2.dilate(img,kernel2,iterations = 1)
dilation3 = cv2.dilate(img,kernel3,iterations = 1)
# 显示图像
plt.figure(figsize = (20, 15))
plt.subplot(151),plt.imshow(img),plt.title('Original'),plt.xticks([]), plt.yticks([])
plt.subplot(152),plt.imshow(dilation),plt.title('ones'),plt.xticks([]), plt.yticks([])
plt.subplot(153),plt.imshow(dilation1),plt.title('RECT'),plt.xticks([]), plt.yticks([])
plt.subplot(154),plt.imshow(dilation2),plt.title('ELLIPSE'),plt.xticks([]), plt.yticks([])
plt.subplot(155),plt.imshow(dilation3),plt.title('CROSS'),plt.xticks([]), plt.yticks([])
plt.show()
参考
- https://zhuanlan.zhihu.com/p/60770435?utm_source=wechat_session&utm_medium=social&utm_oi=825629365701332992
- https://blog.csdn.net/qq_40855366/article/details/81177174
- https://www.jianshu.com/p/fc07d3065cf1
- https://blog.csdn.net/fishmemory/article/details/53113746