Обнаружение лица 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, (Обратите внимание, что это эффективно предотвратит соприкосновение элементов с правой и / или нижней частью подрамника.)
Теперь, конечно, вопрос: допустили ли они ошибку в своей реализации? Имеет ли смысл рассматривать объекты с нулевой поверхностью? Или я вижу это неправильно?