提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
形态学,是图像处理中应用最为广泛的技术之一,主要用于从图像中提取对表达和描绘区域形状有意义的图像分量,使后续的识别工作能够抓住目标对象最为本质的形状特征。
图像的膨胀(Dilation)和腐蚀(Erosion)是两种基本的形态学运算,其中膨胀类似于“领域扩张”,将图像中的白色部分进行扩张,其运行结果图比原图的白色区域更大;腐蚀类似于“领域被蚕食”,将图像中白色部分进行缩减细化,其运行结果图比原图的白色区域更小。
下图:(原图,腐蚀,膨胀)
该公式表示图像A用卷积模板B来进行腐蚀处理,通过模板B与图像A进行卷积计算,得出B覆盖 区域的像素点最小值,并用这个最小值来替代参考点的像素值。
1.cv2.erode()函数
函数:
ero = cv2.erode(src,kernel,anchor,iterations)
参数1:src,原图像
参数2:kernel,腐蚀操作的内核,默认为一个简单的 3x3 矩
参数3:anchor,默认为Point(-1,-1),内核中心点
参数4:iterations,腐蚀次数,默认值1
#1.读取图片
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread("/kaggle/input/morphology/morphology.png", cv2.IMREAD_UNCHANGED)
plt.imshow(img)
plt.axis('off')#关闭坐标系
plt.show()
#2.图片灰度化(已经是灰度图片则不用做这一步)
def rgb2gray(rgb):#灰度化
"""
rgb 2 gray
Args:
rgb image
Returns:
gray image
"""
gray = rgb[:, :, 0] * 0.299 + rgb[:, :, 1] * 0.587 + rgb[:, :, 2] * 0.114
return gray
img = rgb2gray(img)
#2.灰度图片二值化
def thre_bin(gray_image, threshold=170): #二值化
"""
binary image
Args:
gray_image:image with gray scale
threshold:the split standard
Returns:
bin image
"""
threshold_image = np.zeros(shape=(gray_image.shape[0], gray_image.shape[1]), dtype=np.uint8)
# loop for every pixel
for i in range(gray_image.shape[0]):
for j in range(gray_image.shape[1]):
if gray_image[i][j] > threshold:
threshold_image[i][j] = 1
else:
threshold_image[i][j] = 0
return threshold_image
bin_image = thre_bin(img)
#3.腐蚀(写法1)
#定义一个3*3的卷积核
kernel=np.ones((3,3),np.uint8)
#图像腐蚀:cv2.erode(输入图像,卷积核,iterations=腐蚀的次数)
erosion = cv2.erode(bin_image, kernel,iterations=1)
plt.imshow(erosion,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show()
#3.腐蚀(写法2)#效果和方法1完全相同的,原理式写法
def erode_bin_image(img):#输入x为二值图像;#腐蚀
K_size = 3
#kernle
K= np.array([[1, 1, 1],[1, 1, 1], [1, 1,1]],dtype=int)
H, W = img.shape
# zero padding
pad = K_size // 2
out = np.ones((H + pad * 2, W + pad * 2), dtype=np.int)*255
out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
tmp = out.copy()
# filtering
for y in range(H):
for x in range(W):
out[pad + y, pad + x] = np.min(K * (tmp[y: y + K_size, x: x + K_size]))
#out = np.clip(out, 0, 255) # 将值限制在给定的上下界
out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
return out
erode_image=erode_bin_image(bin_image)
plt.imshow(erode_image,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show() #效果和方法1完全相同
膨胀的运算符是“⊕”,其定义如下:
该公式表示用B来对图像A进行膨胀处理,其中B是一个卷积模板或卷积核,其形状可以为正方形或圆形,通过模板B与图像A进行卷积计算,得出B覆盖区域的像素点最大值,并用该值替换参考点的像素值实现膨胀。
cv2.dilate()函数
函数:
dst = cv2.dilate(src, kernel, iterations)
参数:
dst表示处理的结果,
src表示原图像,
kernel表示卷积核,
iterations表示迭代次数。
注意:迭代次数默认是1,表示进行一次膨胀,也可以根据需要进行多次迭代,进行多次膨胀。通常进行1次膨胀即可。
#1.写法1
#此处bin_image是二值图像,如果输入图像不是二值图像,可用上面的代码处理
kernel=np.ones((3,3),np.uint8)
dilation=cv2.dilate(bin_image,kernel,iterations=1)
plt.imshow(dilation,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show()
#写法2,#效果和方法1完全相同的,原理式写法
def dilate_bin_image(img):#输入x为二值图像;#膨胀
K_size = 3
#kernle
K= np.array([[1, 1, 1],[1, 1, 1], [1, 1,1]],dtype=int)
H, W = img.shape
# zero padding
pad = K_size // 2
out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
tmp = out.copy()
# filtering
for y in range(H):
for x in range(W):
out[pad + y, pad + x] = np.max(K * (tmp[y: y + K_size, x: x + K_size]))
#out = np.clip(out, 0, 255) # 将值限制在给定的上下界
out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
return out
dilate_image=dilate_bin_image(bin_image)
plt.imshow(dilate_image,cmap="gray")
plt.axis('off')#关闭坐标系
plt.show() #效果和方法1完全相同
开运算 = 先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了)
开运算总结:
闭运算 = 先膨胀运算,再腐蚀运算(看上去将两个细微连接的图块封闭在一起)
闭运算总结:
闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
闭运算是通过填充图像的凹角来滤波图像的。
结构元素大小的不同将导致滤波效果的不同。
不同结构元素的选择导致了不同的分割。
本文总结了腐蚀和膨胀的cv2函数写法和原理式python代码写法。并总结了开运算和闭运算的原理和作用。
python图像处理(八)——形态学运算之图像腐蚀与图像膨胀
基于Python和遥感图像的膨胀与腐蚀操作