Automatisch gezichtenalbum opbouwen uit video op de reComputer
Een edge-project voor automatische archivering van gezichtenalbums op basis van Hailo-8 / SCRFD / ArcFace.

U kunt de broncode van dit project bekijken op GitHub: https://github.com/doublelf/person_face_sign
1. Projectoverzicht
Person Face Sign is een project dat op een edge-apparaat (reComputer + Hailo-8 NPU) offline een "gezichtenalbum" opbouwt. Het hoofddoel is om alle gezichten die in een bewakings- of activiteitenvideo voorkomen automatisch aan de bijbehorende "identiteitsalbums" toe te wijzen, zodat ze eenvoudig kunnen worden teruggezocht, geteld of gearchiveerd.
Typische problemen die het oplost
- Bezoekersregistratie / receptiebeheer: geef enkele uren beeldmateriaal van de receptiecamera aan het script en het genereert automatisch "vandaag zijn 23 personen langsgekomen, elk met N afbeeldingen".
- Aanwezigheidsondersteuning voor lessen / vergaderingen: lesopnames worden per persoon gearchiveerd, als basis voor elektronische aanwezigheidsregistratie.
- Automatisch ordenen van eventfoto's: meerdere camera's en opnamehoeken op locatie worden samengevoegd en geclusterd om automatisch per persoon geordende albums te produceren.
- Secundair zoeken in videomateriaal: zoek op persoon, niet op tijdstempel.
Hoofdpipeline
Video (data/*.mp4)
│
▼
[VideoSampler] —— 1 frame per seconde (1280×720)
│
▼
[YOLOv8n] —— Personendetectie (640×640)
│
▼
[IoUTracker] —— Personentracking + gedempte gezichtsampling (uitschakelbaar)
│
▼
[SCRFD-10G] —— Gezichtsdetectie + 5-punts landmarks
│
▼
[FaceAlign 5pt] —— Affiene uitlijning naar 112×112
│
▼
[ArcFace MobileFaceNet] —— 512-d L2-norm embedding
│
▼
[AlbumCluster] —— pHash voorrang / Faiss HNSW als fallback → person_id toewijzen
│
▼
[AlbumStorage] —— Bestanden schrijven + dubbele dedup + manifest.json bijwerken
│
▼
[Web Browser :8080] —— Resultaat bladeren / doorzoeken2. Snel starten
Hieronder volgt een end-to-end procedure die in volgorde moet worden uitgevoerd om op de reComputer een doorbladerbaar gezichtenalbum op te bouwen.
2.1 Repository klonen
git clone https://github.com/doublelf/person_face_sign.git
cd person_face_sign2.2 Virtuele omgeving aanmaken
Het gebruik van venv wordt aanbevolen (in Python inbegrepen, geen extra installatie nodig).
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip2.3 Python-afhankelijkheden installeren
pip install -r requirements.txt2.4 Systeemafhankelijkheden installeren
build_album.py roept ffmpeg / ffprobe aan via subprocess voor het samplen van frames; deze moeten op systeemniveau worden geïnstalleerd:
# Debian / Ubuntu (inclusief reComputer)
sudo apt update
sudo apt install -y ffmpeg
# Verifiëren
ffmpeg -version | head -n 1
ffprobe -version | head -n 12.5 HEF-modelbestanden voorbereiden
person_face_sign/
└── models/
├── yolov8n.hef # ~4.3 MB
├── scrfd_10g.hef # ~10 MB
└── arcface_mobilefacenet.hef # ~5 MB| Doel | Model | Standaardpad (hard-coded in build_album.py) | Werkelijke bron |
|---|---|---|---|
| Personendetectie | YOLOv8n | <projectroot>/models/yolov8n.hef | Ingebouwd in de officiële Docker-image, pad in container /app/model/yolov8n.hef |
| Gezichtsdetectie | SCRFD-10G | <projectroot>/models/scrfd_10g.hef | Inbegrepen in het HailoRT-deb-pakket (kan naar models/ worden gekopieerd) |
| Gezichtsembedding | ArcFace MobileFaceNet | <projectroot>/models/arcface_mobilefacenet.hef | Inbegrepen in het HailoRT-deb-pakket (kan naar models/ worden gekopieerd) |
2.5.1 SCRFD + ArcFace verkrijgen (het eenvoudigst)
De HEFs van SCRFD-10G en ArcFace MobileFaceNet zijn door Hailo officieel voorgecompileerde modellen. Ze worden met het hailort-deb-pakket geïnstalleerd in /usr/local/hailo/resources/models/hailo8/ — kopieer ze eenvoudigweg naar de models/-directory van dit project:
sudo apt install hailort
ls /usr/local/hailo/resources/models/hailo8/
# Je zou moeten zien:
# arcface_mobilefacenet.hef
# scrfd_10g.hef
# en nog enkele andere officiële voorbeeldmodellen
# Kopieer naar de lokale models/-directory van het project
cp /usr/local/hailo/resources/models/hailo8/scrfd_10g.hef models/
cp /usr/local/hailo/resources/models/hailo8/arcface_mobilefacenet.hef models/
ls -lh models/2.5.2 YOLOv8n verkrijgen
Zie https://sensecraft.seeed.cc/ai-lab/en/models/yolov8/hailo-8. De YOLOv8n-HEF is reeds verpakt in ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest. Het pad binnen de container is /app/model/yolov8n.hef.
mkdir -p models
# 1. Haal de officiële image op
docker pull ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest
# 2. Maak met `create` een niet-draaiende containerinstantie aan (alleen om het bestand te verkrijgen)
docker create --name yolov8-temp ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest
# 3. Kopieer yolov8n.hef vanuit de container naar de models/-directory van het project
docker cp yolov8-temp:/app/model/yolov8n.hef models/yolov8n.hef
# 4. Verwijder de tijdelijke container
docker rm yolov8-temp
# 5. Verifiëren
ls -lh models/yolov8n.hef2.6 Gezichtenalbum opbouwen (hoofdstap)
De repository bevat een demovideo data/tex.mp4 (ca. 11 MB). Voer de volgende opdracht uit om het album te genereren:
python apps/build_album.py \
--video data/tex.mp4 \
--out data/album \
--no-tracker \
--scrfd-score 0.6 \
--cluster-thresh 0.85 \
--skip-dedupParameters:
| Parameter | Waarde | Beschrijving |
|---|---|---|
--video | data/tex.mp4 | Invoervideo; kan meerdere keren of kommagescheiden worden opgegeven |
--out | data/album | Uitvoerdirectory voor het album |
--no-tracker | flag | IoU-tracker uitschakelen; elk gezicht per frame samplen (aanbevolen voor korte samplevideo's) |
--scrfd-score | 0.6 | Betrouwbaarheidsdrempel voor SCRFD-gezichtsdetectie (standaard 0,60) |
--cluster-thresh | 0.85 | Lax clustering: cosinus-afstanddrempel; zie paragraaf 4.2 voor meer details |
--skip-dedup | flag | Sla pHash-/embedding-dubbele-dedup bij het schrijven over (pHash-voorrad-clustering blijft behouden) |
Na de build verschijnt onder data/album/:
data/album/
├── manifest.json
├── thumbnails/
│ ├── person_0001.jpg
│ ├── person_0002.jpg
│ └── ...
├── person_0001/
│ ├── representative.jpg
│ ├── info.json
│ ├── embeddings.npz
│ └── img_0001_ts_2.00s_score_0.78.jpg
│ └── img_0002_ts_5.00s_score_0.74.jpg
│ └── ...
├── person_0002/
└── ...2.7 Webalbum-browserservice starten
Open na de build een andere terminal en start de minimalistische webservice:
python apps/web_browser.py --port 8080Surf in de browser naar http://<reComputer-IP>:8080/:
- De bovenste statistiekenbalk toont het totale aantal personen, afbeeldingen en bronvideo's;
- Het hoofdraster toont volgens "1 afbeelding = 1 persoon" de miniaturen (afkomstig van
representative.jpg, gesorteerd op aflopend aantal afbeeldingen); - Klik op een persoon om naar de detailpagina te gaan met alle
img_*.jpgvan die persoon; - Klik op een afbeelding om de fullscreen-viewer te openen.
3. Resultaten interpreteren
3.1 Datadirectorystructuur
data/album/
├── manifest.json # Globale statistieken + personenlijst (databron van de Web UI)
├── thumbnails/
│ └── person_<id>.jpg # Miniatuur (kopie van representative.jpg)
└── person_<NNNN>/ # Eén directory per identiteit; NNNN is een zero-padded ID van 4 cijfers
├── info.json # Metadata per persoon: count / first_ts / last_ts / best_score / source_videos
├── embeddings.npz # Top-N-embeddings van deze persoon (standaard N=5, gesorteerd op score)
├── representative.jpg # Best scorende "coverafbeelding", ook gesynchroniseerd naar thumbnails/
└── img_<NNNN>_ts_<ts>s_score_<score>.jpg # Elke bewaarde gezichtsregel (na 112×112-uitlijning)Voorbeelden van naamconventies:
person_0001/img_0001_ts_2.00s_score_0.78.jpg: 1e afbeelding, 2,00 seconden, SCRFD-score = 0,78person_0001/img_0014_ts_18.50s_score_0.82.jpg: 14e afbeelding, 18,50 seconden
3.2 Sleutelvelden in manifest.json
{
"version": "1.0",
"created_at": "2026-09-26T10:23:11",
"updated_at": "2026-09-26T10:24:48",
"total_persons": 6,
"total_images": 142,
"source_videos": ["tex"],
"config": {
"interval_s": 1.0,
"cosine_distance_threshold": 0.85,
"min_face_size": [40, 40],
"min_face_score": 0.6,
"best_n_embeddings": 5,
"phash_max_dist": 4
},
"persons": [
{
"id": 1,
"count": 28,
"first_ts": 2.0,
"last_ts": 82.0,
"best_score": 0.85,
"source_videos": ["tex"],
"thumbnail": "thumbnails/person_0001.jpg"
},
...
]
}Veldbetekenissen:
| Veld | Betekenis |
|---|---|
total_persons | Totaal aantal geclusterde personen (stijgt monotoon bij incrementele builds) |
total_images | Totaal aantal gezichtsafbeeldingen (na deduplicatie) |
config | Snapshot van de parameters van deze build (teruggeschreven in het album voor traceerbaarheid) |
persons[].count | Aantal gezichtsafbeeldingen voor deze persoon |
persons[].first_ts / last_ts | Tijdstempel van de eerste / laatste verschijning (seconden) |
persons[].best_score | Hoogste SCRFD-detectiescore |
3.3 Interacties van de webinterface
De webfrontend gebruikt alleen http.server + statische HTML/CSS/JS, zonder database. Alle gegevens worden realtime gelezen uit manifest.json en het bestandssysteem.
Hoofdinteractiepaden:
- Startpagina (
/): haalt/manifest.jsonop en toont alle personenminiaturen in aflopende volgorde vancount; - Persoonsdetail openen: klik op miniatuur → backend globt
person_<id>/img_*.jpg→ toont alle afbeeldingen; - Afbeeldingsvoorvertoning: klik op een afbeelding →
<dialog>-fullscreenmodaal; - Vernieuwen: klik op
↻bovenaan ommanifest.jsonopnieuw te laden.