Otsu阈值发现返回的值太高

时间:2018-10-30 01:19:57

标签: python image image-processing colors image-segmentation

我试图使用otsu的方法来将背景与这张照片的前景分开。我这样做是通过将图片分解成颜色分量,然后找到绿色和红色分量的阈值来实现的。稍后,我将通过查看某事物是否具有足够高的绿色值而又具有足够低的红色值来确定该事物是否为前景。问题在于,我不断获得大约245的阈值,如果您查看我的直方图,我觉得这应该不是阈值。 enter image description here

我觉得阈值应该在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)

Image I am trying to find thresholds for

0 个答案:

没有答案