原理分析:
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算法相较其它局部自适应二值化算法相对简单,而且对图像处理不受光照影响,但效果显而易见,干扰点较多,看着并不理想,总之还算比较实用吧。