Лучший способ рассчитать лучший порог с P. Viola, M. Jones Framework

Я пытаюсь внедрить фреймворк P. Viola и M. Jones в С++ (вначале просто классификатор последовательности - не каскадная версия). Я думаю, что я разработал все необходимые классы и модули (например, интегральные изображения, функции Haar), несмотря на один - самый важный: основной алгоритм AdaBoost.

Я прочитал оригинальную статью П. Виолы и М. Джонса и многие другие публикации. К сожалению, я до сих пор не понимаю, как я должен найти лучший порог для одного слабого классификатора? Я нашел лишь небольшие ссылки на алгоритмы "взвешенного медианного" и "гауссовского распределения" и множество частей математических формул...

Я пытался использовать источники OpenCV Train Cascade в качестве шаблона, но он настолько всеобъемлющий, что сделать обратную разработку кода очень трудоемко. Я также закодировал свой собственный простой код, чтобы понять идею Adaptive Boosting.

Вопрос: не могли бы вы объяснить мне лучший способ рассчитать лучший порог для одного слабого классификатора?

Ниже я представляю псевдо-код AdaBoost, переписанный из образца, найденного в Google, но я не уверен, правильно ли он подходит. Вычисление одного слабого классификатора происходит очень медленно (несколько часов), и я сомневаюсь в методе вычисления наилучшего порога.

(1) AdaBoost::FindNewWeakClassifier
(2) AdaBoost::CalculateFeatures
(3) AdaBoost::FindBestThreshold
(4) AdaBoost::FindFeatureError
(5) AdaBoost::NormalizeWeights
(6) AdaBoost::FindLowestError
(7) AdaBoost::ClassifyExamples
(8) AdaBoost::UpdateWeights

DESCRIPTION (1)
-Generates all possible arrangement of features in detection window and put to the vector
DO IN LOOP
    -Runs main calculating function (2)
END

DESCRIPTION(2)
-Normalizes weights (5)
DO FOR EACH HAAR FEATURE
    -Puts sequentially next feature from list on all integral images
    -Finds the best threshold for each feature (3)
    -Finds the error for each the best feature in current iteration (4)
    -Saves errors for each the best feature in current iteration in array
    -Saves threshold for each the best feature in current iteration in array
    -Saves the threshold sign for each the best feature in current iteration in array
END LOOP
-Finds for classifier index with the lowest error selected by above loop (6)
-Gets the value of error from the best feature
-Calculates the value of the best feature in the all integral images (7)
-Updates weights (8)
-Adds new, weak classifier to vector

DESCRIPTION (3)
-Calculates an error for each feature threshold on positives integral images - seperate for "+" and "-" sign (4)
-Returns threshold and sign of the feature with the lowest error

DESCRIPTION(4)
- Returns feature error for all samples, by calculating inequality f(x) * sign < sign * threshold

DESCRIPTION (5)
-Ensures that samples weights are probability distribution

DESCRIPTION (6)
-Finds the classifier with the lowest error

DESCRIPTION (7)
-Calculates a value of the best features at all integral images
-Counts false positives number and false negatives number

DESCRIPTION (8)
-Corrects weights, depending on classification results

Спасибо за любую помощь

Ответ 1

В оригинальной бумаге альт-Джонса здесь, раздел 3.1 "Изучающая дискуссия" (абзац 4, если быть точным), вы узнаете процедуру найти оптимальный порог.

Я подведу ниже метод быстро.


Оптимальное пороговое значение для каждой функции зависит от веса образца и, следовательно, рассчитывается в самой итерации adaboost. Лучший слабый порог классификатора сохраняется, как указано в псевдокоде.

В каждом раунде для каждого слабого классификатора вам необходимо организовать N обучающих образцов в соответствии с значением функции. Помещение порога разделит эту последовательность на 2 части. Обе части будут иметь либо положительные, либо отрицательные образцы в большинстве вместе с несколькими образцами другого типа.

  • T+: общая сумма положительных весов пробы
  • T-: общая сумма отрицательных весов пробы
  • S+: сумма положительных весов пробы ниже порогового значения
  • S-: сумма отрицательных весов образцов ниже порога

Ошибка для данного порога -

e = MIN((S+) + (T-) - (S-), (S-) + (T+) - (S+))

Почему минимум? здесь пример:
Если образцы и порог подобны этому -

+ + + + + - - | + + - - - - -

В первом раунде, если все веса равны (= w), взятие минимума даст вам ошибку 4*w вместо 10*w.

Вы вычисляете эту ошибку для всех N возможных способов разделения образцов.
Минимальная ошибка даст вам диапазон пороговых значений. Фактический порог, вероятно, является средним значением смежных значений признаков (я не уверен, хотя, сделайте некоторые исследования по этому вопросу).
Это был второй шаг в вашем цикле DO FOR EACH HAAR FEATURE.
Каскады, предоставленные вместе с OpenCV, были созданы Райнером Ленхартом, и я не знаю, какой метод он использовал. Вы можете внимательно следить за исходными кодами OpenCV, чтобы получить дополнительные улучшения в этой процедуре.