Sto implementando un adattamento dell'algoritmo di rilevamento dei volti di Viola-Jones . La tecnica si basa sul posizionamento di un subframe di 24x24 pixel all'interno di un'immagine e successivamente sul posizionamento di elementi rettangolari al suo interno in ogni posizione con ogni dimensione possibile.
Queste caratteristiche possono essere costituite da due, tre o quattro rettangoli. Viene presentato il seguente esempio.
Affermano che il set completo è più di 180k (sezione 2):
Dato che la risoluzione di base del rilevatore è 24x24, l'insieme esauriente di funzioni rettangolari è piuttosto ampio, oltre 180.000. Si noti che a differenza della base Haar, l'insieme di elementi rettangolari è troppo completo.
Le seguenti affermazioni non sono esplicitamente dichiarate nel documento, quindi sono ipotesi da parte mia:
- Ci sono solo 2 elementi a due rettangoli, 2 elementi a tre rettangoli e 1 elementi a quattro rettangoli. La logica alla base di questo è che stiamo osservando la differenza tra i rettangoli evidenziati, non esplicitamente il colore o la luminanza o qualcosa del genere.
- Non possiamo definire il tipo di elemento A come un blocco di pixel 1x1; deve essere almeno 1x2 pixel. Inoltre, il tipo D deve essere almeno 2x2 pixel e questa regola vale di conseguenza per le altre funzionalità.
- Non possiamo definire il tipo di elemento A come un blocco di 1x3 pixel poiché il pixel centrale non può essere partizionato e sottraendolo da se stesso è identico a un blocco di 1x2 pixel; questo tipo di caratteristica è definito solo per larghezze pari. Inoltre, la larghezza dell'elemento di tipo C deve essere divisibile per 3 e questa regola vale di conseguenza per gli altri elementi.
- Non possiamo definire una caratteristica di larghezza e / o altezza di 0. Pertanto, iterare x di e y a 24 meno la dimensione della funzione.
Sulla base di questi presupposti, ho contato il set completo:
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++;
}
}
}
}
}
Il risultato è 162.336 .
L'unico modo che ho trovato per approssimare gli "oltre 180.000" di cui parlano Viola & Jones è stato quello di eliminare l'ipotesi n. 4 e di introdurre bug nel codice. Ciò comporta la modifica di quattro righe rispettivamente in:
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
Il risultato è quindi 180.625 . (Notare che questo impedirà efficacemente alle caratteristiche di toccare mai la destra e / o la parte inferiore del telaio ausiliario.)
Ora ovviamente la domanda: hanno commesso un errore nella loro implementazione? Ha senso considerare elementi con una superficie pari a zero? O la vedo nel modo sbagliato?