Wykrywanie twarzy Viola-Jones zapewnia 180k funkcji
Wdrażam adaptacjęAlgorytm wykrywania twarzy Viola-Jones. Technika ta polega na umieszczeniu podobrazka o rozdzielczości 24x24 pikseli w obrazie, a następnie umieszczeniu w nim prostokątnych elementów w każdej pozycji z każdym możliwym rozmiarem.
Funkcje te mogą składać się z dwóch, trzech lub czterech prostokątów. Poniższy przykład został przedstawiony.
Twierdzą, że wyczerpujący zestaw to ponad 180 tys. (Sekcja 2):
Biorąc pod uwagę, że rozdzielczość bazowa detektora wynosi 24x24, wyczerpujący zestaw funkcji prostokąta jest dość duży, ponad 180 000. Zauważ, że w przeciwieństwie do podstawy Haara, zestaw funkcji prostokąta jest zbyt duży.
Poniższe stwierdzenia nie są wyraźnie określone w pracy, więc są to założenia z mojej strony:
Istnieją tylko dwie funkcje dwóch prostokątów, 2 funkcje trzech prostokątów i 1 funkcja czterech prostokątów. Logika tego jest taka, że obserwujemyróżnica między wyróżnionymi prostokątami, nie jest to wyraźnie kolor ani luminancja, ani nic w tym rodzaju.Nie możemy zdefiniować typu elementu A jako bloku pikseli 1x1; musi mieć co najmniej 1x2 piksele. Ponadto typ D musi mieć co najmniej 2x2 piksele, a ta reguła jest zgodna z innymi funkcjami.Nie możemy zdefiniować typu elementu A jako bloku pikseli 1x3, ponieważ środkowy piksel nie może być podzielony na partycje, a odjęcie go od siebie jest identyczne z blokiem pikseli 1x2; ten typ funkcji jest zdefiniowany tylko dla parzystych szerokości. Ponadto szerokość typu elementu C musi być podzielna przez 3, a reguła ta jest zgodna z innymi cechami.Nie możemy zdefiniować elementu o szerokości i / lub wysokości 0. Dlatego iterujemyx iy do 24 minus rozmiar 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 to162 336.
Jedynym sposobem, w jaki stwierdziłem, że przybliża „ponad 180 000”, o których mówi Viola i Jones, jest odrzucenie założenia nr 4 i wprowadzenie błędów w kodzie. Obejmuje to zmianę odpowiednio czterech linii:
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
Wynik jest wtedy180 625. (Należy pamiętać, że skutecznie zapobiegnie to dotykaniu elementów z prawej i / lub dolnej części ramy pomocniczej).
Teraz oczywiście pytanie: czy oni popełnili błąd w ich realizacji? Czy ma sens rozważenie cech o powierzchni zero? Czy widzę to w niewłaściwy sposób?