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?

questionAnswers(5)

yourAnswerToTheQuestion