Python+OpenCV基於OTSU算法的局部二值化算法(失敗品)

大津法(otsu算法)是基於全局的閾值分割算法,極易受到光照不均的干擾,使圖像前景像素與背景像素分割不合理,達不到預期效果,故需要採用局部閾值分割的方法,本文采用以每列爲局部,將每列進行一次otsu算法,求出列閾值,以此類推,直至遍歷完所有的列。

代碼如下:

import cv2 as cv
import numpy as np

# 轉灰
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]
    otsuimg=np.zeros((h,w),np.uint8)
    for i in range(w):   # 遍歷列
        sigma=threshold=0   # 定義類間方差和最終閾值
        histogram=np.zeros(256,np.int32)   # 初始化各灰度級個數統計
        probability=np.zeros(256,np.float32)   # 初始化各灰度級概率分佈
        for j in range (h):   # 遍歷行,進行otsu算法
            s=img[j,i]
            histogram[s]+=1   # 統計灰度級中每個像素在整幅圖像中的個數
        for k in range (256):
            probability[k]=histogram[k]/h   # 統計每個灰度級佔圖像中的分佈
        for p in range (255):
            w0 = w1 = 0   # 定義前景像素點和背景像素點灰度級佔圖像中的分佈
            fgs = bgs = 0   # 定義前景像素點灰度級總和and背景像素點灰度級總和
            for q in range (256):
                if q<=p:   # 當前i爲分割閾值
                    w0+=probability[q]   # 前景像素點佔整幅圖像的比例累加
                    fgs+=q*probability[q]   # 前景像素點的平均灰度
                else:
                    w1+=probability[q]   # 背景像素點佔整幅圖像的比例累加
                    bgs+=q*probability[q]   # 背景像素點的平均灰度
            u0=fgs/w0
            u1=bgs/w1
            g=w0*w1*(u0-u1)**2   # 類間方差
            if g>=sigma:
                sigma=g
                threshold=p
        for j in range (h):   # 對某列的每一行進行二值化
            if img[j,i]>threshold:
                otsuimg[j,i]=255
            else:
                otsuimg[j,i]=0
    return otsuimg

image = cv.imread("D:/Testdata/a.png")
grayimage = rgb2gray(image)
otsuimage = otsu(grayimage)
cv.imshow("image", image)
cv.imshow("otsuimage", otsuimage)
cv.waitKey(0)
cv.destroyAllWindows()

實驗結果:
原圖
局部二值化圖
爲檢驗二值化效果,與otsu算法實驗結果比較:
otsu算法圖片
比較發現,這種基於otsu算法的局部二值化算法效果並不明顯,所以算是一個失敗品吧。

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