Обнаружение лица Viola-Jones требует 180 тыс. Функций

Я осуществлял адаптациюАлгоритм обнаружения лиц Виолы-Джонса, Этот метод основан на размещении подкадра 24x24 пикселей на изображении и последующем размещении прямоугольных элементов внутри него в каждой позиции с любым возможным размером.

Эти функции могут состоять из двух, трех или четырех прямоугольников. Следующий пример представлен.

Они утверждают, что исчерпывающий набор составляет более 180 КБ (раздел 2):

Учитывая, что базовое разрешение детектора составляет 24x24, исчерпывающий набор прямоугольных элементов довольно велик - более 180 000. Обратите внимание, что в отличие от основы Хаара, набор элементов прямоугольника является слишком полным.

Следующие утверждения прямо не изложены в документе, поэтому они являются предположениями с моей стороны:

Есть только 2 объекта с двумя прямоугольниками, 2 объекта с тремя прямоугольниками и 1 объект с четырьмя прямоугольниками. Логика этого заключается в том, что мы наблюдаемразница между выделенными прямоугольниками, а не явно цветом или яркостью или чем-то в этом роде.Мы не можем определить тип объекта A как блок пикселей 1x1; он должен быть не менее 1х2 пикселей. Кроме того, тип D должен быть не менее 2x2 пикселей, и это правило соответствует другим функциям.Мы не можем определить тип объекта A как блок пикселей 1x3, так как средний пиксель не может быть разделен, и вычитание его из себя идентично блоку пикселей 1x2; этот тип объекта определен только для четной ширины. Кроме того, ширина типа объекта C должна делиться на 3, и это правило выполняется в соответствии с другими объектами.Мы не можем определить объект с шириной и / или высотой 0. Поэтому мы повторяемx а такжеy до 24 минус размер функции.

Основываясь на этих предположениях, я насчитал исчерпывающий набор:

const int frameSize = 24;
const int features = 5;
// All five feature types:
const int feature[features][2] = {{2,1}, {1,2}, {3,1}, {1,3}, {2,2}};

int count = 0;
// Each feature:
for (int i = 0; i < features; i++) {
    int sizeX = feature[i][0];
    int sizeY = feature[i][1];
    // Each position:
    for (int x = 0; x <= frameSize-sizeX; x++) {
        for (int y = 0; y <= frameSize-sizeY; y++) {
            // Each size fitting within the frameSize:
            for (int width = sizeX; width <= frameSize-x; width+=sizeX) {
                for (int height = sizeY; height <= frameSize-y; height+=sizeY) {
                    count++;
                }
            }
        }
    }
}

Результат162336.

Единственный способ приблизиться к тому, о чем говорят Viola & Jones «более 180 000», - это отказаться от предположения № 4 и внести ошибки в код. Это предполагает изменение четырех строк соответственно:

for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)

Результат тогда180625, (Обратите внимание, что это эффективно предотвратит соприкосновение элементов с правой и / или нижней частью подрамника.)

Теперь, конечно, вопрос: допустили ли они ошибку в своей реализации? Имеет ли смысл рассматривать объекты с нулевой поверхностью? Или я вижу это неправильно?

Ответы на вопрос(5)

Ваш ответ на вопрос