Ich habe eine Anpassung des Gesichtserkennungsalgorithmus von Viola-Jones implementiert . Die Technik beruht darauf, dass ein Teilrahmen mit 24 x 24 Pixeln in einem Bild platziert wird und anschließend rechteckige Merkmale an jeder Position mit jeder möglichen Größe darin platziert werden.
Diese Features können aus zwei, drei oder vier Rechtecken bestehen. Das folgende Beispiel wird vorgestellt.
Sie behaupten, dass der vollständige Satz mehr als 180.000 beträgt (Abschnitt 2):
Angesichts der Grundauflösung des Detektors von 24 x 24 ist der erschöpfende Satz von Rechteckmerkmalen mit über 180.000 recht groß. Beachten Sie, dass im Gegensatz zur Haar-Basis der Satz von Rechteckmerkmalen übervollständig ist.
Die folgenden Aussagen werden in dem Papier nicht explizit angegeben, daher handelt es sich um Annahmen meinerseits:
- Es gibt nur 2 Zwei-Rechteck-Features, 2 Drei-Rechteck-Features und 1 Vier-Rechteck-Feature. Die Logik dahinter ist, dass wir den Unterschied zwischen den hervorgehobenen Rechtecken beobachten, nicht explizit die Farbe oder Luminanz oder irgendetwas in dieser Art.
- Wir können den Feature-Typ A nicht als 1x1-Pixelblock definieren. Es muss mindestens 1x2 Pixel betragen. Außerdem muss Typ D mindestens 2 x 2 Pixel groß sein, und diese Regel gilt entsprechend für die anderen Merkmale.
- Wir können den Merkmalstyp A nicht als 1x3-Pixelblock definieren, da das mittlere Pixel nicht partitioniert werden kann und das Subtrahieren von sich selbst mit einem 1x2-Pixelblock identisch ist. Dieser Feature-Typ ist nur für gerade Breiten definiert. Außerdem muss die Breite des Merkmalstyps C 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 wir x und y bis 24 abzüglich der Größe des Features.
Basierend auf diesen Annahmen habe ich die erschöpfende 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 ist 162.336 .
Der einzige Weg, den ich gefunden habe, um die "über 180.000", von denen Viola & Jones sprechen, zu approximieren, besteht darin, die Annahme Nr. 4 fallen zu lassen und Fehler in den Code einzuführen. Dies beinhaltet das Ändern von vier Zeilen in:
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
Das Ergebnis ist dann 180.625 . (Beachten Sie, dass dadurch effektiv verhindert wird, dass die Features jemals die rechte und / oder untere Seite des Hilfsrahmens berühren.)
Nun natürlich die Frage: Haben sie einen Fehler bei ihrer Implementierung gemacht? Ist es sinnvoll, Features mit einer Oberfläche von Null zu berücksichtigen? Oder sehe ich das falsch?
quelle
x < size
mit der Annahme Nr. 4 zu tun: Ich möchte, dass das Feature innerhalb des Subframes bleibt, aber eine Dimension von mindestens 1x1 hat. Nun, vielleicht ist dies auch eine Annahme, ob sich die Dimension des Features nicht außerhalb des Hilfsrahmens erstrecken soll.x < size - 1
, sodass es keinen Gewinn gibt.Antworten:
Bei näherer Betrachtung sieht Ihr Code für mich korrekt aus. was einen wundern lässt, ob die ursprünglichen Autoren einen Fehler nach dem anderen hatten. Ich denke, jemand sollte sich ansehen, wie OpenCV es implementiert!
Ein Vorschlag, der das Verständnis erleichtert, besteht darin, die Reihenfolge der for- Schleifen umzudrehen, indem zuerst alle Größen und dann die möglichen Positionen in Anbetracht der Größe durchlaufen werden:
mit den gleichen Ergebnissen wie die vorherigen
162336
Um dies zu überprüfen, habe ich den Fall eines 4x4-Fensters getestet und alle Fälle manuell überprüft (einfach zu zählen, da die Formen 1x2 / 2x1 und 1x3 / 3x1 nur um 90 Grad gedreht gleich sind):
quelle
alles. Es gibt immer noch einige Verwirrung in den Papieren von Viola und Jones.
In ihrem CVPR'01-Papier wird klargestellt, dass
In der IJCV'04-Zeitung wird genau dasselbe gesagt. Also insgesamt 4 Features . Aber seltsamerweise gaben sie diesmal an, dass der umfassende Funktionsumfang 45396 beträgt! Dies scheint nicht die endgültige Version zu sein. Hier wurden vermutlich einige zusätzliche Einschränkungen eingeführt, wie z. B. min_width, min_height, width / height ratio und sogar position.
Beachten Sie, dass beide Artikel auf seiner Webseite heruntergeladen werden können .
quelle
Nachdem ich nicht die ganze Zeitung gelesen habe, fällt mir der Wortlaut Ihres Zitats auf
"Der Satz von Rechteckmerkmalen ist übervollständig" "Vollständiger Satz"
Es klingt für mich wie ein Setup, bei dem ich erwarte, dass der Papierschreiber eine Erklärung dafür abgibt, wie er den Suchraum auf ein effektiveres Set reduziert, indem er beispielsweise triviale Fälle wie Rechtecke mit Null beseitigt Oberfläche.
edit: oder mit einer Art maschinellem Lernalgorithmus, wie die Zusammenfassung andeutet. Vollständiges Set beinhaltet alle Möglichkeiten, nicht nur "vernünftige".
quelle
Es gibt keine Garantie dafür, dass ein Autor eines Papiers in all seinen Annahmen und Ergebnissen korrekt ist. Wenn Sie der Meinung sind, dass die Annahme Nr. 4 gültig ist, behalten Sie diese Annahme bei und probieren Sie Ihre Theorie aus. Sie sind möglicherweise erfolgreicher als die ursprünglichen Autoren.
quelle
Ziemlich gute Beobachtung, aber sie könnten den 24x24-Frame implizit auf Null setzen oder "überlaufen" und die ersten Pixel verwenden, wenn sie außerhalb der Grenzen liegen, wie bei Rotationsverschiebungen oder wie Breton sagte, sie könnten einige Features als "triviale Features" betrachten. und verwerfen Sie sie dann mit dem AdaBoost.
Außerdem habe ich Python- und Matlab-Versionen Ihres Codes geschrieben, damit ich den Code selbst testen kann (einfacher zu debuggen und für mich zu befolgen), und ich poste sie hier, wenn jemand sie irgendwann nützlich findet.
Python:
Matlab:
quelle
In ihrer ursprünglichen Arbeit von 2001 geben sie nur an, dass drei Arten von Merkmalen verwendet werden:
Ebenfalls
Da jede Art zwei Ausrichtungen hat, ist anzunehmen, dass sie insgesamt 6 Merkmale verwenden (zumindest für die Berechnung der Gesamtzahl der Merkmale): 2 Merkmale mit zwei Rechtecken, 2 Merkmale mit drei Rechtecken und 2 Merkmale mit vier Rechtecken. Mit dieser Annahme gibt es tatsächlich über 180.000 Merkmale:
Wenn Sie einen Feature-Typ mit vier Rechtecken löschen (was in der späteren Veröffentlichung der Fall zu sein scheint), beträgt die Gesamtzahl der Features 162.336.
quelle