我试图使用otsu的方法来将背景与这张照片的前景分开。我这样做是通过将图片分解成颜色分量,然后找到绿色和红色分量的阈值来实现的。稍后,我将通过查看某事物是否具有足够高的绿色值而又具有足够低的红色值来确定该事物是否为前景。问题在于,我不断获得大约245的阈值,如果您查看我的直方图,我觉得这应该不是阈值。
我觉得阈值应该在150点左右的2个绿色峰值之前?
谢谢
def otsu_helper(counts):
'''
Does the arithmetic of the otsu method
:param counts: An array recording how many pixels are in each bin
:return: A threshold found by minimizing the weighted sum of group variances σ^(2)w(t)
'''
# variables for otsu's method
m1t = 0 # mean prob for first group
q1t = 0 # prob that a given greylevel < t
s21t = 0 # variace for the group of values less that t
tot = 0 #keep track of the total amount of pixels captured to bins so far
pix = sum(counts) #The total number of pixels
print(counts)
group1 = np.zeros(shape=(256,2))
#Calculate the mean probability and variances for group1 for all values of t
for i in range(0,256):
j = i+1
bin = counts\[i\]
#print(i,":",bin)
tot += bin
pi = bin/pix
q1t += tot/pix
if (q1t != 0):
m1t += (j * pi )/q1t
s21t += ( (j - m1t)**2 * pi )/q1t
group1\[i\] = \[q1t,s21t\] # Store the probability and variance for later use in finding the sum of group variances
else:
group1\[i\] = \[None,None\]
tot = 0
q2t = 0 # prob that a given greylevel > t
m2t = 0 # mean prob for second group
s22t = 0 # variace for the group of values greater than t
group2 = np.zeros(shape=(256,2))
group2\[255\] = \[None,None\] #At threshold 256, there are no values greater than t
# Calculate the mean probability and variances for group2 for all values of t
for i in range(254, -1, -1):
j = i+1
bin = counts\[j\] #Because all the values from t+1 to G are summed
tot += bin
pi = (bin / pix)
q2t += tot / pix
if (q2t != 0):
m2t += (j*pi)/q2t
s22t += ((j - m2t)**2 * pi)/q2t
group2\[i\] = \[q2t, s22t\]
else:
group2\[i\] = \[None, None\]
s2w = 999999999999 # Weight sum of group variances
t = 0 #The optimal threshold value
#Calculate the weighted sum of group variances for all values of t and save the minimum
for i in range(0,256):
if (not np.isnan(group1\[i,1\]) and not np.isnan(group2\[i:1\])):
s2wt = group1\[i,0\]*group1\[i,1\] + group2\[i,0\]*group2\[i,1\]
print(i,":","{0:.{1}e}".format(s2wt, 1))
if s2w > s2wt:
s2w = s2wt
t = i
return t
def otsu(I):
'''
Finds the optimal threshold of an image
:param I: Input image to find the threshold
:return:A tuple of values that minimizes weighted sum of group variances σ^(2)w(t) for the red and green channel
'''
#Isolating the colour channels and placing them in bins
red = 256 * I\[:, :, 0\] # Zero out contribution from green
green = 256 * I\[:, :, 1\]
blue = 256 * I\[:, :, 2\]
#red, green, blue = np.moveaxis(I, -1, 0)
bins = np.array(range(0,257))
g_counts,pixels = np.histogram(green,bins)
r_counts,pixels = np.histogram(red, bins)
b_counts,pixels = np.histogram(blue,bins)
print('gt = otsu_helper(g_counts)')
gt = otsu_helper(g_counts)
print('rt = otsu_helper(r_counts)')
rt = otsu_helper(r_counts)
# return (gt,rt)
# Creating a histogram of the green colour channel
pixels = pixels\[:-1\]
plt.bar(pixels, g_counts, align='center')
plt.xlim(-1, 256)
plt.show()
return (gt,rt)