Python+OpenCV腐蝕膨脹源代碼編寫

對於圖像的每個像素,取其一定的鄰域,計算最大值/最小值作爲新圖像對應像素位置的像素值。其中,取最大值就是膨脹,取最小值就是腐蝕。(摘自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()

實驗結果:
從左至右共五幅圖,分別是原圖(裁剪過後),灰度圖,二值化圖,腐蝕圖,膨脹圖
從左至右共五幅圖,分別是原圖(裁剪過後),灰度圖,二值化圖,腐蝕圖,膨脹圖。以上便是對圖像的腐蝕和膨脹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章