原理分析:
Bernsens算法是一種典型的局部閾值算法,其將窗口中各個四昂素灰度級最大值和最小值的平均值作爲一個窗口的中心像素的閾值,因此此方法不存在預定閾值,適應性較整體閾值法廣,不受非均勻光照條件等情況的影響。
設圖像在像素點 (i,j) 處的灰度值 f(i,j) ,考慮以像素點(i,j)爲中心的 (2w+1)*(2w+1) 窗口,其中2w+1表示窗口的邊長,則Bernsen算法可以描述爲:
計算圖像中各個像素點 (i,j) 的閾值 T(i,j)
圖像中各個像素點 (i,j)用 b(i,j) 值逐點進行二值化
以上內容摘自論文《局部自適應二值化方法研究》(王序哲)
編程思路:
(1)輸入圖像並轉灰;
(2)對灰度圖進行像素點遍歷:
(3)以遍歷到的像素點爲中心,以3*3矩陣爲局部窗口,找出窗口中像素級最大值和最小值之和的均值,將其計爲窗口閾值;
(4)比較遍歷到的像素點灰度級與窗口閾值大小,並進行二值化。
代碼:
import cv2 as cv
import numpy as np
def rgb2gray(img):
h=img.shape[0]
w=img.shape[1]
grayimg=np.zeros((h,w),np.uint8)
for i in range (h):
for j in range (w):
grayimg[i,j]=0.144*img[i,j,0]+0.587*img[i,j,1]+0.299*img[i,j,2]
return grayimg
def bernsens(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):
matrix=np.zeros((3,3),np.uint8)
for k in range (-1,2):
for l in range (-1,2):
matrix[k+1,l+1]=img[i+k,j+l]
threshold=(np.max(matrix)+np.min(matrix))/2
if img[i,j]>=threshold:
img1[i,j]=255
else:
img1[i,j]=0
return img1
image=cv.imread("D:/Testdata/a.png")
grayimage=rgb2gray(image)
thresholdimage=bernsens(grayimage)
cv.imshow("image",image)
cv.imshow("grayimage",grayimage)
cv.imshow("thresholdimage",thresholdimage)
cv.waitKey(0)
cv.destroyAllWindows()
實驗結果:
灰度圖如下:
二值化圖如下:
Bernsens算法相較其它局部自適應二值化算法相對簡單,而且對圖像處理不受光照影響,但效果顯而易見,干擾點較多,看着並不理想,總之還算比較實用吧。