Wdrażałem adaptację algorytmu wykrywania twarzy Violi-Jonesa . Technika ta polega na umieszczeniu w obrazie podramki o wymiarach 24x24 pikseli, a następnie umieszczeniu wewnątrz niej prostokątnych elementów w każdym położeniu o każdym możliwym rozmiarze.
Te elementy mogą składać się z dwóch, trzech lub czterech prostokątów. Przedstawiono następujący przykład.
Twierdzą, że wyczerpujący zestaw to ponad 180 tysięcy (sekcja 2):
Biorąc pod uwagę, że podstawowa rozdzielczość detektora to 24x24, wyczerpujący zestaw cech prostokąta jest dość duży, ponad 180 000. Zwróć uwagę, że w przeciwieństwie do podstawy Haar, zestaw elementów prostokąta jest zbyt kompletny.
Poniższe stwierdzenia nie są wyraźnie podane w artykule, więc są to założenia z mojej strony:
- Istnieją tylko 2 obiekty dwuprostokątne, 2 elementy trójprostokątne i 1 element czterokątny. Logika tego polega na tym, że obserwujemy różnicę między podświetlonymi prostokątami, a nie wyraźnie kolor, luminancję czy cokolwiek w tym rodzaju.
- Nie możemy zdefiniować elementu typu A jako bloku 1x1 piksela; musi mieć co najmniej 1 x 2 piksele. Ponadto typ D musi mieć co najmniej 2 x 2 piksele i ta zasada obowiązuje odpowiednio do innych funkcji.
- Nie możemy zdefiniować elementu typu A jako bloku 1 x 3 piksele, ponieważ środkowy piksel nie może być podzielony na partycje, a odjęcie go od siebie jest identyczne jak w bloku 1 x 2 piksele; ten typ elementu jest definiowany tylko dla parzystych szerokości. Ponadto szerokość cechy typu C musi być podzielna przez 3 i ta zasada obowiązuje odpowiednio do innych cech.
- Nie możemy zdefiniować funkcję o szerokości i / lub wysokości 0. Dlatego iterate x i y do 24 minus wielkość funkcji.
Na podstawie tych założeń policzyłem wyczerpujący zestaw:
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++;
}
}
}
}
}
Wynik to 162.336 .
Jedynym sposobem, w jaki znalazłem przybliżenie „ponad 180 000”, o których mówią Viola i Jones, jest porzucenie założenia nr 4 i wprowadzenie błędów w kodzie. Wymaga to odpowiednio zmiany czterech wierszy na:
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
Wynik to 180 625 . (Zwróć uwagę, że skutecznie zapobiegnie to kiedykolwiek dotykaniu elementów prawej i / lub dolnej części ramy pomocniczej).
Teraz oczywiście pytanie: czy popełnili błąd w swojej implementacji? Czy rozważenie cech o powierzchni zerowej ma sens? A może źle to widzę?