face-clustering-rk3588./README.md

558 lines
10 KiB
Markdown

# Face Clustering RK3588
Toolkit C++ riutilizzabile per il rilevamento dei volti, la generazione di
embedding facciali e il futuro clustering tramite HDBSCAN su dispositivi
Rockchip RK3588.
Il progetto usa RKNN per eseguire sulla NPU:
- SCRFD per il rilevamento dei volti;
- SFace per la generazione degli embedding;
- normalizzazione L2 degli embedding;
- confronto tramite cosine similarity.
Il motore non dipende da database, server o applicazioni specifiche e può
essere integrato in altri programmi C++ oppure utilizzato tramite il
programma `face_scan` e il relativo output JSON.
## Stato del progetto
Funzionalità attualmente disponibili:
- caricamento delle immagini RGB;
- rilevamento facciale tramite SCRFD;
- confidence score per ogni volto;
- bounding box;
- cinque landmark facciali;
- non-maximum suppression;
- allineamento del volto a 112 x 112 pixel;
- generazione di embedding SFace a 128 dimensioni;
- conversione dell'output in float32;
- normalizzazione L2;
- confronto tramite cosine similarity;
- output JSON per applicazioni esterne;
- compilazione tramite Makefile.
Funzionalità pianificate:
- ricerca kNN tramite OpenCL;
- TOPK uguale a 32;
- core distance;
- mutual reachability distance;
- minimum spanning tree;
- condensed tree;
- clustering HDBSCAN;
- assegnazione di un cluster a ogni embedding facciale.
## Pipeline facciale
```text
Immagine
|
v
Caricamento RGB
|
v
Resize proporzionale
|
v
Input SCRFD 640 x 640
|
v
SCRFD su RKNN/NPU
|
+-- confidence score
+-- bounding box
+-- cinque landmark
|
v
Non-maximum suppression
|
v
Similarity transform
|
v
Volto allineato 112 x 112
|
v
SFace su RKNN/NPU
|
v
Embedding float32[128]
|
v
Normalizzazione L2
```
Poiché gli embedding sono normalizzati, la cosine similarity tra due
embedding corrisponde al loro prodotto scalare.
## Programmi disponibili
### face_recognition
`face_recognition` è il programma dimostrativo con output leggibile
da una persona.
Può analizzare una singola immagine oppure confrontare tutti i volti trovati
in due immagini.
Scansione di una singola immagine:
```bash
./bin/face_recognition test/image.jpg
```
Confronto tra due immagini:
```bash
./bin/face_recognition \
test/reference.jpg \
test/query.jpg
```
Per ogni volto il programma mostra:
- confidence score;
- bounding box;
- cinque landmark.
Nel confronto fra due immagini calcola la cosine similarity tra ogni volto
della prima immagine e ogni volto della seconda.
La soglia dimostrativa attuale è:
```text
0.363
```
Questa soglia deve essere validata sul dataset reale dell'applicazione.
### face_scan
`face_scan` è destinato all'integrazione con altri programmi.
Accetta il percorso di una singola immagine:
```bash
./bin/face_scan test/image.jpg
```
Scrive:
- il risultato JSON su standard output;
- errori e diagnostica su standard error;
- exit code 0 in caso di successo;
- exit code diverso da 0 in caso di errore.
Per salvare il risultato:
```bash
./bin/face_scan \
test/image.jpg \
> result.json
```
Per verificare e formattare il JSON:
```bash
python3 -m json.tool result.json
```
Il JSON contiene:
- percorso dell'immagine;
- larghezza e altezza originali;
- elenco dei volti;
- indice sequenziale del volto;
- confidence score;
- bounding box;
- cinque landmark;
- embedding di 128 valori.
Il formato completo è documentato in
`docs/json-format.md`.
## Requisiti
- Linux AArch64;
- Rockchip RK3588 o piattaforma RKNN compatibile;
- compilatore con supporto C++17;
- GNU Make;
- runtime RKNN;
- modello SCRFD in formato RKNN;
- modello SFace in formato RKNN;
- Python 3 per la validazione dei test JSON.
## File locali richiesti
### Modelli RKNN
Copiare i modelli nella directory `models`:
```text
models/SCRFD_500M_KPS_640.rknn
models/face_recognition_sface_2021dec.rknn
```
### Runtime RKNN
Copiare la libreria runtime in:
```text
lib/librknnrt.so
```
I modelli RKNN e la libreria runtime sono esclusi dal repository tramite
`.gitignore`.
Prima di distribuire questi file, verificare le rispettive condizioni di
licenza e redistribuzione.
## Compilazione
Dalla directory principale del repository:
```bash
make
```
Compilazione parallela:
```bash
make -j"$(nproc)"
```
I programmi vengono creati in:
```text
bin/face_recognition
bin/face_scan
```
Per effettuare una compilazione pulita:
```bash
make clean
make -j"$(nproc)"
```
## Test
Le immagini di test locali devono essere copiate nella directory
`test`.
Per eseguire i test automatici:
```bash
make test
```
Il test:
1. esegue `face_recognition`;
2. esegue `face_scan`;
3. salva temporaneamente il JSON;
4. valida la sintassi JSON tramite Python.
Le immagini sono escluse dal repository tramite `.gitignore`.
## Utilizzo da un altro programma C++
Includere l'header pubblico:
```cpp
#include "face_engine.h"
```
Inizializzare il motore:
```cpp
FaceEngine engine;
if (!engine.init(
"models/SCRFD_500M_KPS_640.rknn",
"models/face_recognition_sface_2021dec.rknn")) {
return 1;
}
```
Elaborare un'immagine:
```cpp
std::vector<Face> faces;
int image_width = 0;
int image_height = 0;
if (!engine.process_image(
"image.jpg",
faces,
image_width,
image_height)) {
return 1;
}
```
Ogni elemento `Face` contiene:
- `score`, confidence del detector;
- `x1`, `y1`, `x2` e `y2`;
- cinque elementi `kps`;
- un embedding L2-normalizzato di 128 elementi.
Esempio di accesso ai risultati:
```cpp
for (const Face& face : faces) {
std::cout
<< "score=" << face.score
<< " bbox="
<< face.x1 << ","
<< face.y1 << ","
<< face.x2 << ","
<< face.y2
<< "\n";
if (face.embedding.size() == 128) {
std::cout << "Embedding valido\n";
}
}
```
## Utilizzo da altri linguaggi
Programmi Node.js, Python, Java, Dart o scritti in altri linguaggi possono
eseguire `bin/face_scan` come processo figlio.
Il contratto di integrazione è:
```text
Input percorso di una singola immagine
stdout oggetto JSON completo
stderr diagnostica ed errori
exit 0 scansione completata
exit != 0 errore
```
Un'immagine valida senza volti produce comunque exit code 0 e:
```json
{
"image": {
"path": "image.jpg",
"width": 1920,
"height": 1080
},
"faces": []
}
```
## Formato dell'embedding
Ogni embedding contiene:
```text
Dimensione logica 128
Tipo nel motore float32
Norma L2 circa 1.0
Valori tutti finiti
```
Se salvato come sequenza binaria float32:
```text
128 x 4 byte = 512 byte
```
Questo formato sarà utilizzabile direttamente dai futuri moduli OpenCL.
## Struttura del repository
```text
face-clustering-rk3588/
|-- Makefile
|-- README.md
|-- include/
| |-- face_config.h
| |-- face_engine.h
| |-- rknn_api.h
| `-- stb_image.h
|-- src/
| |-- face_engine.cc
| |-- face_recognition.cc
| `-- face_scan.cc
|-- docs/
| |-- architecture.md
| `-- json-format.md
|-- models/
| `-- README.md
|-- lib/
| `-- README.md
|-- test/
| `-- README.md
|-- modules/
| |-- knn-opencl/
| |-- mutual-reachability/
| |-- mst/
| `-- hdbscan/
|-- build/
`-- bin/
```
## Architettura del motore
Il codice è diviso in tre componenti principali.
### face_engine
Implementa:
- caricamento immagine;
- resize bilineare;
- conversione float32 e float16;
- inferenza SCRFD;
- decodifica dei risultati;
- non-maximum suppression;
- allineamento facciale;
- inferenza SFace;
- normalizzazione dell'embedding.
### face_recognition
Fornisce un programma dimostrativo e permette di verificare visivamente:
- volti rilevati;
- bounding box;
- landmark;
- similarità fra embedding.
### face_scan
Fornisce un'interfaccia machine-readable tramite JSON.
Il programma non scrive log su standard output, così l'output può essere
letto direttamente con un parser JSON.
## Pipeline futura di clustering
Il repository verrà esteso con questa pipeline:
```text
Embedding SFace float32[N][128]
|
v
OpenCL brute-force kNN
|
v
TOPK=32
|
+-- indices[N][32]
`-- scores[N][32]
|
v
Core distance
|
v
Mutual reachability graph
|
v
Minimum spanning tree
|
v
Single linkage hierarchy
|
v
Condensed tree
|
v
HDBSCAN cluster assignment
```
## Moduli futuri
### knn-opencl
Calcolerà i 32 vicini più prossimi per ogni embedding usando il prodotto
scalare tra vettori L2-normalizzati.
### mutual-reachability
Calcolerà:
```text
mrd(i,j) =
max(
core_distance(i),
core_distance(j),
distance(i,j)
)
```
### mst
Costruirà il minimum spanning tree del grafo di mutual reachability.
### hdbscan
Produrrà:
- gerarchia single linkage;
- condensed tree;
- stabilità dei cluster;
- assegnazione finale dei cluster;
- identificazione del rumore.
## Roadmap
```text
Face detection e embedding completato
Confronto cosine completato
Output JSON completato
Makefile completato
Documentazione completato
OpenCL kNN TOPK=32 pianificato
Core distance pianificato
Mutual reachability pianificato
Minimum spanning tree pianificato
HDBSCAN condensed tree pianificato
Cluster assignment pianificato
```
## Licenze e componenti esterni
Il repository contiene o utilizza componenti esterni, inclusi:
- stb_image;
- header API RKNN;
- runtime RKNN;
- modelli SCRFD;
- modello SFace.
Prima della pubblicazione o redistribuzione verificare separatamente le
condizioni di licenza di ogni componente.
I modelli e il runtime non vengono inseriti automaticamente nel repository.
## Obiettivo finale
L'obiettivo è fornire una pipeline indipendente e riutilizzabile:
```text
Immagini
|
v
Volti e embedding
|
v
Grafo kNN
|
v
HDBSCAN
|
v
Cluster di identità facciali
```
Il server o l'applicazione che utilizza il toolkit rimane responsabile della
persistenza, dell'interfaccia utente e dell'eventuale associazione dei
cluster a persone reali.