Die Gesichtserkennung von Viola-Jones weist 180.000 Merkmale auf

Ich habe eine Anpassung von implementiertViola-Jones Gesichtserkennungsalgorithmus. Die Technik basiert auf dem Platzieren eines Teilrahmens mit 24 x 24 Pixeln in einem Bild und dem anschließenden Platzieren rechteckiger Merkmale in jeder Position mit jeder möglichen Größe.

Diese Features können aus zwei, drei oder vier Rechtecken bestehen. Das folgende Beispiel wird vorgestellt.

Sie behaupten, dass die Gesamtmenge mehr als 180.000 beträgt (Abschnitt 2):

Angesichts der Grundauflösung des Detektors von 24x24 ist die Gesamtheit der Rechteckmerkmale mit über 180.000 recht groß. Beachten Sie, dass im Gegensatz zur Haar-Basis die Menge der Rechteck-Features zu vollständig ist.

Die folgenden Aussagen werden in dem Papier nicht ausdrücklich erwähnt, daher sind sie Annahmen meinerseits:

Es gibt nur 2 Features mit zwei Rechtecken, 2 Features mit drei Rechtecken und 1 Feature mit vier Rechtecken. Die Logik dahinter ist, dass wir das beobachtenUnterschied zwischen den hervorgehobenen Rechtecken, nicht explizit die Farbe oder Luminanz oder irgendetwas dieser Art.Wir können Feature-Typ A nicht als 1x1-Pixel-Block definieren. es muss mindestens 1x2 Pixel sein. Außerdem muss Typ D mindestens 2x2 Pixel haben, und diese Regel gilt entsprechend für die anderen Funktionen.Wir können Feature-Typ A nicht als 1x3-Pixel-Block definieren, da das mittlere Pixel nicht partitioniert werden kann. Das Subtrahieren von sich selbst ist identisch mit einem 1x2-Pixel-Block. Dieser Feature-Typ ist nur für gerade Breiten definiert. Auch die Breite des Merkmalstyps C muss durch 3 teilbar sein, und diese Regel gilt entsprechend für die anderen Merkmale.Wir können kein Feature mit einer Breite und / oder Höhe von 0 definieren. Daher iterieren wirx undy bis 24 minus der Größe des Features.

Basierend auf diesen Annahmen habe ich die vollständige Menge gezählt:

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++;
                }
            }
        }
    }
}

Das Ergebnis ist162,336.

Der einzige Weg, den ich gefunden habe, um die "über 180.000" zu schätzen, von denen Viola & Jones sprechen, besteht darin, die Annahme Nr. 4 fallen zu lassen und Fehler in den Code einzuführen. Dazu müssen jeweils vier Zeilen geändert werden, um:

for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)

Das Ergebnis ist dann180,625. (Beachten Sie, dass dadurch effektiv verhindert wird, dass die Funktionen jemals die rechte und / oder untere Seite des Hilfsrahmens berühren.)

Nun natürlich die Frage: Haben sie einen Fehler bei der Umsetzung gemacht? Ist es sinnvoll, Features mit einer Oberfläche von Null zu berücksichtigen? Oder sehe ich das falsch?

Antworten auf die Frage(5)

Ihre Antwort auf die Frage