Недавно я изучаю некоторые классические методы компьютерного зрения по заметкам, и я считаю хорошей привычкой делать заметки, так что я здесь.
Я впервые пишу статью на Medium. Так что могут быть некоторые ошибки, и я буду очень рад, что вы укажете на них.
В этой статье я покажу вам математические детали метода Оцу и покажу вам пример, вы можете просмотреть Код Python здесь, хотя это действительно простой пример.

Введение

Метод Оцу можно использовать для преобразования изображения в градациях серого в двоичное изображение. Предполагается, что изображение содержит два класса пикселей, следующих за бимодальной гистограммой (пиксели переднего плана и пиксели фона). Суть в том, что этот метод может генерировать порог на основе гистограммы изображения.
Как видно из рисунка гистограммы, он находит порог t , который минимизирует взвешенную сумму внутригрупповых различий (мы обсудим это позже , обратите внимание, что это относится к вариациям, вызванным различиями внутри отдельных групп) для двух групп, которые возникают в результате разделения серые тона при значении t.

Итак, как мы можем найти правильный t? Прежде чем мы начнем, давайте познакомимся с некоторыми знаниями теории вероятностей.

Детали алгоритма

Дисперсия определяется как:

Это все, что нам нужно. :)

А внутригрупповая дисперсия определяется как:

где веса ω0 и ω1 - возможности каждой группы (интенсивность Grp0 меньше, чем t), σ0 и σ1 - дисперсии каждой группы. Предположим, у нас есть нормализованная гистограмма P с L ячейками. Математическое определение:

Итак, теперь мы знаем, как рассчитать внутригрупповую дисперсию, кажется, мы готовы, но есть некоторые уловки, позволяющие упростить алгоритм, чтобы он работал быстрее.
А вот и межгрупповая дисперсия, в отличие от внутригрупповой дисперсии, относится к вариациям, вызванным различиями между группами. Межгрупповая дисперсия - это разница между дисперсией общего распределения гистограммы и внутригрупповой дисперсией:

Таким образом, минимизация внутригрупповой дисперсии равносильна максимизации межгрупповой дисперсии.
Теперь давайте посмотрим на формулу межгрупповой дисперсии :

Вот как мы получаем эту формулу:

Имейте в виду, что:

если мы установим t = L, мы можем получить E (X).
Согласно определению E (x²) и E (X) легко найти:

и

So,

Теперь все, что нам нужно сделать, это получить два массива ω0 и E (X0), тогда мы сможем получить межгрупповую дисперсию. Наконец, мы используем argmax, чтобы получить правильный порог t.

Код

img_hist = np.histogram(img_flattened,bins=255)
brightness_list = img_hist[1][1:].astype(int) #ignore the first element
hist_counts = img_hist[0]
normed_hist_counts = hist_counts/hist_counts.sum()
weighted_prob = brightness_list*normed_hist_counts
omiga_arr = normed_hist_counts.cumsum()
Ex_arr = weighted_prob.cumsum()
def calculate_between_group_variance(threshold):
    eps = 1e-10 #avoid divide by zero
    omiga0 = omiga_arr[threshold-1]
    Ex0 = Ex_arr[threshold-1]
    between_group_variance = omiga0*(Ex0-EX)**2/(1-omiga0+eps)
    return between_group_variance
    
inter_class_variance_arr = np.array(list(map(calculate_between_group_variance,brightness_list)))

Пример:

Я получил исходное изображение в оттенках серого из wiki,

и гистограмма показана ниже (обратите внимание, что я установил число 255 как число 254, потому что небо переэкспонировано):

between_group_variance:

и окончательная двоичная карта:

Вот и все! Спасибо за ваше время! Если у вас есть какие-либо вопросы, не стесняйтесь обращаться ко мне. :)