對於圖像的每個像素,取其一定的鄰域,計算最大值/最小值作爲新圖像對應像素位置的像素值。其中,取最大值就是膨脹,取最小值就是腐蝕。(摘自CSDN其他博客)
腐蝕膨脹算法步驟:
(1)將輸入圖像轉化爲灰度圖;
(2)將灰度圖進行二值化處理,此處本人用otsu算法(參考前面本人博客);
(3)對二值化圖像進行腐蝕(取像素點鄰域最小值賦於像素點)和膨脹(取像素點鄰域最大值賦於像素點)處理;
腐蝕膨脹算法如下:
import cv2 as cv
import numpy as np
# 如果圖像過大處理速度慢,可採用以下函數裁剪圖像大小
def caijian(img):
h=img.shape[0]
w=img.shape[1]
print("原圖像大小爲:",h,w)
img1=cv.resize(img, (300, 300), interpolation=cv.INTER_CUBIC)
h1=img1.shape[0]
w1=img1.shape[1]
print("裁剪後圖像大小爲:",h1,w1)
return img1
def rgb2gray(img):
h=img.shape[0]
w=img.shape[1]
img1=np.zeros((h,w),np.uint8)
for i in range(h):
for j in range(w):
img1[i,j]=0.144*img[i,j,0]+0.587*img[i,j,1]+0.299*img[i,j,1]
return img1
# 二值化
def otsu(img):
h=img.shape[0]
w=img.shape[1]
m=h*w # 圖像像素點總和
otsuimg=np.zeros((h,w),np.uint8)
threshold_max=threshold=0 # 定義臨時閾值和最終閾值
histogram=np.zeros(256,np.int32) # 初始化各灰度級個數統計參數
probability=np.zeros(256,np.float32) # 初始化各灰度級佔圖像中的分佈的統計參數
for i in range (h):
for j in range (w):
s=img[i,j]
histogram[s]+=1 # 統計灰度級中每個像素在整幅圖像中的個數
for k in range (256):
probability[k]=histogram[k]/m # 統計每個灰度級佔圖像中的分佈
for i in range (255):
w0 = w1 = 0 # 定義前景像素點和背景像素點灰度級佔圖像中的分佈
fgs = bgs = 0 # 定義前景像素點灰度級總和and背景像素點灰度級總和
for j in range (256):
if j<=i: # 當前i爲分割閾值
w0+=probability[j] # 前景像素點佔整幅圖像的比例累加
fgs+=j*probability[j]
else:
w1+=probability[j] # 背景像素點佔整幅圖像的比例累加
bgs+=j*probability[j]
u0=fgs/w0 # 前景像素點的平均灰度
u1=bgs/w1 # 背景像素點的平均灰度
g=w0*w1*(u0-u1)**2 # 類間方差
if g>=threshold_max:
threshold_max=g
threshold=i
print(threshold)
for i in range (h):
for j in range (w):
if img[i,j]>threshold:
otsuimg[i,j]=255
else:
otsuimg[i,j]=0
return otsuimg
# 圖像腐蝕
def etch(img):
h=img.shape[0]
w=img.shape[1]
img1=np.zeros((h,w),np.uint8)
for i in range (1,h-1):
for j in range (1,w-1):
min=img[i,j]
for k in range (i-1,i+2):
for l in range (j-1,j+2):
if k<0|k>=h-1|l<0|l>=w-1:
continue
if img[k,l]<min:
min=img[k,l]
img1[i,j]=min
return img1
# 圖像膨脹
def expand(img):
h=img.shape[0]
w=img.shape[1]
img1=np.zeros((h,w),np.uint8)
for i in range (1,h-1):
for j in range (1,w-1):
max=img[i,j]
for k in range (i-1,i+2):
for l in range (j-1,j+2):
if k<0|k>=h-1|l<0|l>=w-1:
continue
if img[k,l]>max:
max=img[k,l]
img1[i,j]=max
return img1
image = cv.imread("D:/Testdata/jiantou.jpg") # 輸入圖像,根據實際情況而改變路徑
caijianimage=caijian(image) # 裁剪圖像大小
grayimage = rgb2gray(caijianimage) # 轉灰
otsuimage = otsu(grayimage) # 二值化
etchimage=etch(otsuimage) # 腐蝕
expandimage=expand(otsuimage) # 膨脹
cv.imshow("caijianimage",caijianimage) # 輸出裁剪圖像相當於原圖
cv.imshow("grayimage",grayimage) # 輸出灰度圖
cv.imshow("otsuimage",otsuimage) # 輸出二值化圖像
cv.imshow("etch",etchimage) # 輸出腐蝕圖像
cv.imshow("expandimage",expandimage) # 輸出膨脹圖像
cv.waitKey(0)
cv.destroyAllWindows()
實驗結果:
從左至右共五幅圖,分別是原圖(裁剪過後),灰度圖,二值化圖,腐蝕圖,膨脹圖。以上便是對圖像的腐蝕和膨脹。