Порог обнаружения Оцу, возвращающий слишком высокое значение - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь использовать метод Оцу, чтобы отделить фон от переднего плана этой картинки. Я делаю это, разбивая изображение на его цветовые компоненты, а затем нахожу пороговые значения для зеленого и красного компонентов. Позже я решу, является ли что-то на переднем плане, увидев, имеет ли оно достаточно высокое значение зеленого, но достаточно низкое значение красного. Проблема в том, что я продолжаю получать пороговые значения около 245, которые, как мне кажется, не такие, какими они должны быть, если вы посмотрите на мою гистограмму. enter image description here

Я чувствую, что пороги должны быть до 2 зеленых пиков в районе 150?

Спасибо-вы

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

...