Распознавание лиц Виолы-Джонса утверждает характеристики 180к
я осуществлял адаптацию алгоритм обнаружения лица Виолы-Джонса. Этот метод основан на размещении подкадра размером 24x24 пикселя внутри изображения и последующем размещении прямоугольных объектов внутри него в каждом положении с любым возможным размером.
эти функции могут состоять из двух, трех или четырех прямоугольников. Ниже приведен пример.
Они утверждают, что исчерпывающий набор составляет более 180k (раздел 2):
учитывая, что базовое разрешение детектора составляет 24x24, исчерпывающий набор функций прямоугольника довольно большой, более 180 000 . Обратите внимание, что в отличие от базиса Хаара, набор прямоугольников особенности является чрезмерным.
следующие утверждения явно не изложены в статье, поэтому они являются предположениями с моей стороны:
- есть только 2 функции с двумя прямоугольниками, 2 функции с тремя прямоугольниками и 1 функция с четырьмя прямоугольниками. Логика этого заключается в том, что мы наблюдаем разница между выделенными прямоугольниками, явно не цвет или яркость или что-нибудь в этом роде.
- мы не можем определить тип объекта A как блок пикселей 1x1; он должен быть не менее 1x2 пикселей. Кроме того, тип 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++;
}
}
}
}
}
результат 162,336.
единственный способ, который я нашел, чтобы приблизиться к" более чем 180,000 " Viola & Jones говорят, это отбросить предположение №4 и ввести ошибки в код. Это включает в себя изменение четырех строк соответственно:
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
результат 180,625. (Отметим, что это будет эффективно предотвращать возможности не касаясь правой и/или нижней части подрамник.)
теперь конечно вопрос: допустили ли они ошибку в своей реализации? Имеет ли смысл рассматривать объекты с нулевой поверхностью? Или я вижу это неправильно?
5 ответов:
при ближайшем рассмотрении ваш код выглядит правильным для меня; что заставляет задуматься, были ли у оригинальных авторов ошибка off-by-one. Я думаю, кто-то должен посмотреть, как OpenCV реализует его!
тем не менее, одно предложение, чтобы сделать его легче понять, чтобы перевернуть порядок на петли, перейдя сначала по всем размерам, а затем зацикливаясь на возможных местах с учетом размера:
#include <stdio.h> int main() { int i, x, y, sizeX, sizeY, width, height, count, c; /* All five shape types */ const int features = 5; const int feature[][2] = {{2,1}, {1,2}, {3,1}, {1,3}, {2,2}}; const int frameSize = 24; count = 0; /* Each shape */ for (i = 0; i < features; i++) { sizeX = feature[i][0]; sizeY = feature[i][1]; printf("%dx%d shapes:\n", sizeX, sizeY); /* each size (multiples of basic shapes) */ for (width = sizeX; width <= frameSize; width+=sizeX) { for (height = sizeY; height <= frameSize; height+=sizeY) { printf("\tsize: %dx%d => ", width, height); c=count; /* each possible position given size */ for (x = 0; x <= frameSize-width; x++) { for (y = 0; y <= frameSize-height; y++) { count++; } } printf("count: %d\n", count-c); } } } printf("%d\n", count); return 0; }
С теми же результатами, как и предыдущий
162336
чтобы проверить это, я проверил случай окна 4x4 и вручную проверил все случаи (легко подсчитать, так как формы 1x2/2x1 и 1x3/3x1 одинаковы только на 90 градусов):
2x1 shapes: size: 2x1 => count: 12 size: 2x2 => count: 9 size: 2x3 => count: 6 size: 2x4 => count: 3 size: 4x1 => count: 4 size: 4x2 => count: 3 size: 4x3 => count: 2 size: 4x4 => count: 1 1x2 shapes: size: 1x2 => count: 12 +-----------------------+ size: 1x4 => count: 4 | | | | | size: 2x2 => count: 9 | | | | | size: 2x4 => count: 3 +-----+-----+-----+-----+ size: 3x2 => count: 6 | | | | | size: 3x4 => count: 2 | | | | | size: 4x2 => count: 3 +-----+-----+-----+-----+ size: 4x4 => count: 1 | | | | | 3x1 shapes: | | | | | size: 3x1 => count: 8 +-----+-----+-----+-----+ size: 3x2 => count: 6 | | | | | size: 3x3 => count: 4 | | | | | size: 3x4 => count: 2 +-----------------------+ 1x3 shapes: size: 1x3 => count: 8 Total Count = 136 size: 2x3 => count: 6 size: 3x3 => count: 4 size: 4x3 => count: 2 2x2 shapes: size: 2x2 => count: 9 size: 2x4 => count: 3 size: 4x2 => count: 3 size: 4x4 => count: 1
все. В бумагах Виолы и Джонса все еще есть некоторая путаница.
в их статье CVPR'01 четко указано, что
"в частности, мы используем три виды функций. Значение функция двух прямоугольников разница между суммой пиксели в пределах двух прямоугольных областей. Регионы имеют одинаковый размер и форма и горизонтально или вертикально (см. рис. 1). функция с тремя прямоугольниками вычисляет сумму в пределах двух снаружи прямоугольники вычитаются из суммы в центральный прямоугольник. Наконец-то a четырехугольник функция".
в статье IJCV'04 говорится то же самое. так что в целом, 4 функции. Но как ни странно, на этот раз они заявили, что исчерпывающий набор функций-45396! Это, кажется, не окончательный вариант.Вот И Я предположим, что там были введены некоторые дополнительные ограничения, такие как min_width, min_height, отношение ширины/высоты и даже положение.
обратите внимание, что оба документа можно загрузить по его веб-страницы.
не прочитав всю статью, формулировка вашей цитаты торчит у меня
учитывая, что базовое разрешение детектор 24x24, исчерпывающий набор из прямоугольных объектов довольно большой, более 180 000 . Обратите внимание, что в отличие от Базис Хаара, множество прямоугольников особенности является чрезмерным.
" набор функций прямоугольника является чрезмерно сложным" "Полный набор"
Это звучит для меня как настройка, где я ожидаю бумагу писатель, чтобы продолжить объяснение того, как они отбирают пространство поиска до более эффективного набора, например, избавляясь от тривиальных случаев, таких как прямоугольники с нулевой площадью поверхности.
edit: или используя какой-то алгоритм машинного обучения, как абстрактные намеки. Исчерпывающий набор подразумевает все возможности, а не только "разумные".
нет никакой гарантии, что любой автор любой статьи прав во всех своих предположениях и выводах. Если вы считаете, что предположение №4 справедливо, то сохраните это предположение и попробуйте свою теорию. Вы можете быть более успешными, чем оригинальные авторы.
довольно хорошее наблюдение, но они могут неявно обнулить кадр 24x24 или "переполнить" и начать использовать первые пиксели, когда он выходит за пределы, как при вращательных сдвигах, или, как сказал Бретон, они могут рассматривать некоторые функции как "тривиальные функции", а затем отбросить их с помощью AdaBoost.
кроме того, я написал Python и Matlab версии вашего кода, чтобы я мог проверить код сам (легче отлаживать и следовать за мной), и поэтому я публикую их здесь, Если кто-нибудь найдет их полезными некогда.
Python:
frameSize = 24; features = 5; # All five feature types: feature = [[2,1], [1,2], [3,1], [1,3], [2,2]] count = 0; # Each feature: for i in range(features): sizeX = feature[i][0] sizeY = feature[i][1] # Each position: for x in range(frameSize-sizeX+1): for y in range(frameSize-sizeY+1): # Each size fitting within the frameSize: for width in range(sizeX,frameSize-x+1,sizeX): for height in range(sizeY,frameSize-y+1,sizeY): count=count+1 print (count)
Matlab:
frameSize = 24; features = 5; % All five feature types: feature = [[2,1]; [1,2]; [3,1]; [1,3]; [2,2]]; count = 0; % Each feature: for ii = 1:features sizeX = feature(ii,1); sizeY = feature(ii,2); % Each position: for x = 0:frameSize-sizeX for y = 0:frameSize-sizeY % Each size fitting within the frameSize: for width = sizeX:sizeX:frameSize-x for height = sizeY:sizeY:frameSize-y count=count+1; end end end end end display(count)