全局阈值处理方法前提:当物体和背景像素的灰度分布十分明显时,可以用适用于整个图像的单个(全局)阈值。即可使用全局阈值处理。
算法思路:
(1)输入原图,转化为灰度图;
(2)对于灰度图,为全局阈值T0选择一个初始估计值(本人选择为0~255中值127);
(3)迭代(4)(5)(6)(7)步骤,迭代次数可自行选择;
(4)用T0分割灰度图,将其分为两组像素,G1由灰度值大于T0的所有像素组成,G2由所有小于T的所有像素组成;
(5)对G1和G2的像素分别计算平均灰度值m1和m2;
(6)计算一个新的阈值:T1=1/2(m1+m2);
(7)如果T1-T0=0,则为二值图阈值,否则继续迭代。
代码如下:
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,2]
return img1
# 计算新阈值
def threshold(img,T):
h=img.shape[0]
w=img.shape[1]
G1=G2=0
g1=g2=0
for i in range (h):
for j in range (w):
if img[i,j]>T:
G1+=img[i,j]
g1+=1
else:
G2+=img[i,j]
g2+=1
m1=int(G1/g1)
m2=int(G2/g2) # m1,m2计算两组像素均值
T0=int((m1+m2)/2) # 据公式计算新的阈值
return T0
def decide(img,T):
h=img.shape[0]
w=img.shape[1]
img1=np.zeros((h,w),np.uint8)
T0=T
T1=threshold(img,T0)
for k in range (100): # 迭代次数为经验值,可据实际情况选定
if abs(T1-T0)==0: # 若新阈值减旧阈值差值为零,则为二值图最佳阈值
for i in range (h):
for j in range (w):
if img[i,j]>T1:
img1[i,j]=255
else:
img1[i,j]=0
break
else:
T2=threshold(img,T1)
T0=T1
T1=T2 # 变量转换,保证if条件为新阈值减旧阈值
return img1
image=cv.imread("D:/Testdata/grow.tif")
grayimage=rgb2gray(image)
thresholdimage=decide(grayimage,127)
cv.imshow("image",image)
cv.imshow("grayimage",grayimage)
cv.imshow("thresholdimage",thresholdimage)
cv.waitKey(0)
cv.destroyAllWindows()
此方法为最基本二值化图像方法,在实际应用中会从在诸多不足,但确是阈值分割的基础,需要了解掌握。