- Python 100%
| .gitignore | ||
| batch_cleanup.py | ||
| build_dataset.py | ||
| download_photos.py | ||
| LICENSE | ||
| qwen_cleanup_workflow.json | ||
| README.md | ||
| requirements.txt | ||
| train_config_test.yaml | ||
| train_wan22_images.yaml | ||
| train_wan22_video.yaml | ||
| validate_dataset.py | ||
face-dataset-builder
Automatischer Dataset-Builder und -Filter fuer Face-LoRA-Training. Extrahiert Gesichter aus Videos und Fotos, erstellt trainingsfertige Crops in mehreren Varianten mit passenden KI-Captions, und filtert automatisch nach Qualitaet.
Entwickelt fuer die Verwendung mit ai-toolkit (FLUX, Qwen Image, WAN 2.2 LoRA Training).
Features
- Videos + Fotos als Eingabequellen
- Gesichtserkennung via OpenCV YuNet (schnell, CPU oder GPU)
- Referenzgesicht-Matching via SFace -- filtert nach einer bestimmten Person
- 4 Crop-Varianten pro erkanntem Gesicht: close, medium, wide, full
- KI-Captions via Joy-Caption Alpha Two (natuerlicher, casual Stil)
- Qualitaetsfilter: Gesichts-Confidence, Schaerfe, Duplikat-Erkennung, Belichtung
- Automatisches Filtern: Behaelt nur die besten N Einzelbilder (Intra-Set-Deduplizierung, ausgeglichene Crop-Verteilung)
- Progressbars fuer alle langwierigen Schritte (tqdm)
- GPU-Beschleunigung via OpenCL (AMD, Intel, NVIDIA)
- Personenentfernung via YOLO11n-seg + LaMa Inpainting
- Textentfernung via PP-OCR + LaMa Inpainting (Untertitel, Wasserzeichen)
Voraussetzungen
- Python 3.10+
- OpenCV mit DNN-Modul
- Optional: ONNX Runtime (fuer
--remove-people,--remove-text) - Optional: PyTorch + Transformers (fuer
--caption)
Installation
git clone https://github.com/swissYoshi/face-dataset-builder.git
cd face-dataset-builder
python -m venv venv
source venv/bin/activate # Linux/Mac
# oder: venv\Scripts\activate # Windows
pip install -r requirements.txt
Verzeichnisstruktur
face-dataset-builder/
├── download_photos.py # Fotos aus Immich herunterladen
├── build_dataset.py # Dataset-Builder (Haupttool)
├── batch_cleanup.py # Batch-Bildbereinigung via ComfyUI + Qwen Image Edit
├── qwen_cleanup_workflow.json # ComfyUI API-Workflow fuer batch_cleanup.py
├── validate_dataset.py # Dataset-Validator und -Filter
├── requirements.txt
├── dataset/
│ ├── videos/ # Eingabe: Videos (mp4, mov, mkv, ...)
│ ├── photos/ # Eingabe: Rohe Einzelbilder (jpg, png, ...)
│ ├── cleaned/ # Ausgabe: Bereinigte Bilder (nach batch_cleanup.py)
│ ├── reference.jpg # Optional: Referenzgesicht
│ ├── <name>/ # Ausgabe: Crops + Captions (pro Durchlauf)
│ └── _rejected/
│ └── <name>/ # Vom Filter aussortierte Bilder (ausserhalb des Trainingsordners)
├── models/ # Wird automatisch erstellt
└── output/ # Training-Output
Verwendung
0a. Fotos aus Immich herunterladen (optional)
Laedt alle Fotos einer erkannten Person direkt aus der Immich-Bibliothek herunter.
Voraussetzungen: Immich-Server erreichbar, API-Key konfiguriert (via --api-key, IMMICH_API_KEY env, oder .immich_api_key Datei).
# Alle Personen anzeigen
python download_photos.py --list
# Fotos einer Person herunterladen
python download_photos.py "Yoshi"
# Mit Optionen
python download_photos.py "Yoshi" --skip-existing --min-size 1024 --limit 200
Optionen:
name Name der Person in Immich
--server URL Immich Server (default: http://192.168.2.214:2283)
--api-key KEY API-Key
--output ORDNER Ausgabe-Ordner (default: dataset/photos)
--list Alle erkannten Personen mit Foto-Anzahl anzeigen
--skip-existing Bereits vorhandene Bilder ueberspringen
--min-size PIXEL Mindestaufloesung kuerzeste Seite (default: 0 = alle)
--limit N Max. Anzahl Downloads (default: 0 = alle)
0b. Bilder bereinigen (optional, via ComfyUI + Qwen Image Edit)
Entfernt Text/Emojis/Personen, verbessert Beleuchtung und schaerft Gesichter per KI-Bildbearbeitung.
Voraussetzungen: ComfyUI muss laufen (python main.py im ComfyUI-Verzeichnis).
# Standard: dataset/photos/ -> dataset/cleaned/
python batch_cleanup.py
# Eigene Pfade
python batch_cleanup.py --input dataset/photos --output dataset/cleaned
# Bereits verarbeitete Bilder ueberspringen
python batch_cleanup.py --skip-existing
# Eigener Cleanup-Prompt
python batch_cleanup.py --prompt "Remove background clutter and improve lighting"
Pipeline:
Immich (Personen-Gesichtserkennung)
| download_photos.py "Name"
v
dataset/photos/ (Rohe Fotos)
| batch_cleanup.py (ComfyUI API -> Qwen Image Edit)
v
dataset/cleaned/ (Bereinigte Fotos)
| build_dataset.py --photos dataset/cleaned --name <name>
v
dataset/<name>/ (Trainings-Dataset mit Crops + Captions)
Optionen:
--input ORDNER Eingabe-Ordner (default: dataset/photos)
--output ORDNER Ausgabe-Ordner (default: dataset/cleaned)
--workflow JSON Workflow-Datei (default: qwen_cleanup_workflow.json)
--server URL ComfyUI Server (default: http://127.0.0.1:8188)
--prompt TEXT Positiver Prompt
--negative TEXT Negativer Prompt
--skip-existing Bereits verarbeitete Bilder ueberspringen
--timeout SEKUNDEN Timeout pro Bild (default: 300)
1. Dataset erstellen
Lege Videos in dataset/videos/ und/oder Fotos in dataset/photos/ ab.
# Grundlegend (Template-Captions)
python build_dataset.py --name flux1_v1
# Mit KI-Captions (empfohlen)
python build_dataset.py --name flux1_v1 --caption
# Mit KI-Captions, quantisiert (~10GB statt ~17GB VRAM)
python build_dataset.py --name flux1_v1 --caption --caption-quantize
# Vollstaendig: Referenzgesicht, Personenentfernung, Textentfernung, KI-Captions
python build_dataset.py --name flux1_v1 --reference mein_foto.jpg --remove-people --remove-text --caption --verbose
Der --name Parameter ist Pflicht und bestimmt den Output-Ordner: dataset/<name>/.
2. Dataset validieren
python validate_dataset.py
Prueft: Schaerfe, Aufloesung, Belichtung, Gesichtserkennung, Gesichtswinkel-Verteilung, Duplikate, Captions, Gesamtscore.
3. Dataset filtern
# Vorschau: zeigt was gefiltert wuerde (mit Zusammenfassung)
python build_dataset.py --only-filter --name flux1_v1 --keep 80 --dry-run
# Filtern: behaelt die besten 80 Bilder (default)
python build_dataset.py --only-filter --name flux1_v1 --keep 80
# Oder ueber validate_dataset.py direkt:
python validate_dataset.py --filter --keep 50
python validate_dataset.py --dry-run --keep 50
# Mit Belichtungs-Filter
python validate_dataset.py --filter --filter-exposure
Der Filter waehlt die besten Einzelbilder aus dem gesamten Pool (nicht set-basiert). Redundante Varianten innerhalb eines Sets werden automatisch eliminiert, und die Crop-Groessen werden gleichmaessig verteilt. Aussortierte Bilder landen in dataset/_rejected/<name>/ und koennen bei Bedarf wiederhergestellt werden.
Filter-Pipeline (4 Stufen):
- Harte Ausschluesse: Kein Gesicht erkannt (ausser full-Variante), optional stark unter-/ueberbelichtete Bilder (
--filter-exposure) - Intra-Set Deduplizierung: Pro Quellbild werden visuell zu aehnliche Varianten eliminiert (>92% Histogramm-Korrelation). Z.B. wenn bei einem Portrait close/medium/wide fast identisch aussehen, wird nur die beste behalten.
- Inter-Set Duplikate: Zwischen verschiedenen Quellbildern wird bei Duplikaten das schlechtere entfernt
- Top-N mit Bucket-Filling: Die besten N Bilder werden mit ausgeglichener Verteilung ueber Crop-Groessen gewaehlt. Jede Variante (close/medium/wide/full) erhaelt einen gleichen Basis-Anteil, Restplaetze werden nach globalem Score aufgefuellt.
Score-Gewichtung (pro Einzelbild):
| Kriterium | Punkte | Beschreibung |
|---|---|---|
| Gesichts-Confidence | 0-30 | YuNet-Confidence (verdeckte Gesichter = niedriger) |
| Schaerfe | 0-25 | Laplacian-Varianz |
| Gesichtsgroesse | 0-15 | Anteil des Gesichts am Bild |
| Belichtung | 0-10 | Optimal bei 100-160 Helligkeit |
| Gesichtswinkel | 0-10 | Frontal > 3/4 > Profil |
| Aufloesung | 0-10 | Minimale Seitenlaenge |
Statistiken: Nach jedem Filter-Lauf (auch ohne --dry-run) wird eine Zusammenfassung ausgegeben: Score-Bereich, Ablehnungsgruende, Crop-Verteilung als Balkendiagramm, Quellen-Abdeckung, und die 5 besten/schlechtesten behaltenen Bilder.
4. Training starten
cd /pfad/zu/ai-toolkit
python run.py /pfad/zu/train_config.yaml
Crop-Varianten
Jeder erkannte Frame erzeugt bis zu 4 Crop-Varianten:
| Variante | Face-Factor | Beschreibung | Caption |
|---|---|---|---|
close |
55% | Nahaufnahme Gesicht | a close up photo of <trigger> |
medium |
30% | Portrait | a portrait photo of <trigger> |
wide |
18% | Oberkoerper | a photo of <trigger> |
full |
-- | Ganzes Bild, proportional skaliert | a full body photo of <trigger> |
Die full-Variante behält das gesamte Bild mit originalem Seitenverhältnis (kein quadratischer Crop).
Bei Verwendung von --caption werden die Template-Captions durch KI-generierte, natuerliche Beschreibungen ersetzt.
Optionen: build_dataset.py
Eingabe:
--name NAME Name fuer diesen Durchlauf (Output: dataset/<name>/)
--videos ORDNER Ordner mit Videos (default: dataset/videos)
--photos ORDNER Ordner mit Einzelbildern (default: dataset/photos)
--output ORDNER Basis-Ausgabeordner (default: dataset/)
Gesichtserkennung:
--reference BILD Referenzbild fuer Gesichtsfilterung
--threshold FLOAT Aehnlichkeitsschwelle (default: 0.35)
Video-Extraktion:
--interval SEKUNDEN Abstand zwischen Frame-Checks (default: 1.0)
--max-frames N Max Frames pro Video (default: 50)
--min-sharpness FLOAT Minimale Schaerfe (default: 30)
--min-similarity FLOAT Duplikat-Schwelle (default: 0.97)
Crops:
--size PIXEL Crop-Groesse (default: 1024)
--variants LISTE Crop-Varianten (default: close,medium,wide,full)
--trigger WORT Trigger-Wort fuer Captions (default: y0sh1face)
Bereinigung:
--remove-people Andere Personen aus Bildern entfernen
--remove-text Text-Overlays entfernen (Untertitel, Wasserzeichen)
KI-Captions:
--caption KI-Captions via Joy-Caption generieren
--caption-quantize Joy-Caption mit NF4-Quantisierung (~10 GB statt ~17 GB)
--caption-prompt TEXT Eigener Captioning-Prompt
--caption-max-tokens N Max. Tokens pro Caption (default: 256)
Filterung:
--no-filter Automatisches Filtern nach Extraktion deaktivieren
--only-filter Nur filtern (keine Extraktion), auf bestehendes Dataset
--dry-run Zeigt was gefiltert wuerde (mit --only-filter)
--keep N Maximale Anzahl Bilder die behalten werden (default: 80)
Sonstiges:
--no-gpu GPU-Beschleunigung deaktivieren
--verbose Debug-Ausgabe
Optionen: validate_dataset.py
Validierung:
--dataset ORDNER Dataset-Ordner (default: dataset/images)
--trigger WORT Trigger-Wort (default: y0sh1face)
--min-images N Minimale Anzahl guter Bilder (default: 15)
--ideal-images N Ideale Anzahl Bilder (default: 50)
Filterung:
--filter Schlechte Bilder nach _rejected/ verschieben
--dry-run Zeigt was gefiltert wuerde (ohne Aenderungen)
--keep N Maximale Anzahl Bilder die behalten werden (default: 80)
--filter-exposure Stark unter-/ueberbelichtete Bilder filtern
Beispiele
# Schneller Test mit wenigen Frames
python build_dataset.py --name test_v1 --interval 2.0 --max-frames 10
# Nur close und medium Crops
python build_dataset.py --name test_v1 --variants close,medium
# Nur Full-Body fuer WAN 2.2 Training
python build_dataset.py --name wan_v1 --variants full --caption
# Strenge Qualitaet: hohe Schaerfe, geringe Duplikat-Toleranz
python build_dataset.py --name flux_v2 --min-sharpness 50 --min-similarity 0.90 --reference foto.jpg
# Komplett-Pipeline
python build_dataset.py --name flux_v2 --reference foto.jpg --remove-people --remove-text \
--caption --caption-quantize --keep 60 --verbose
# Nur bestehendes Dataset filtern (ohne Neuextraktion)
python build_dataset.py --only-filter --name flux_v2 --keep 80 --dry-run
python build_dataset.py --only-filter --name flux_v2 --keep 80
Modelle
Die Modelle werden beim ersten Start automatisch heruntergeladen:
| Modell | Groesse | Zweck |
|---|---|---|
| YuNet | 227 KB | Gesichtserkennung |
| SFace | 37 MB | Gesichts-Identifikation (mit --reference) |
| YOLO11n-seg | 11 MB | Personen-Segmentierung (--remove-people) |
| LaMa | 198 MB | Inpainting (--remove-people, --remove-text) |
| PP-OCR v3 | 2.3 MB | Texterkennung (--remove-text) |
| Joy-Caption | ~17 GB | KI-Captions (--caption, ~10 GB mit --caption-quantize) |
Fuer batch_cleanup.py (via ComfyUI):
| Modell | Groesse | Zweck |
|---|---|---|
| Qwen Image Edit GGUF (Q6_K) | ~16 GB | Bildbearbeitung |
| Qwen 2.5 VL 7B fp8 | ~7 GB | Text-Encoder |
| Qwen Image VAE | ~100 MB | VAE |
| Qwen Image Lightning LoRA | ~200 MB | 4-8 Steps statt 30 |
Hardware
Getestet auf:
- AMD Radeon RX 7900 XTX (24GB VRAM) mit ROCm
- OpenCL GPU-Beschleunigung fuer Face-Detection
- Joy-Caption benoetigt ~10-17 GB VRAM
Lizenz
MIT