Hinweis : Dies ist eine Tracking-Bibliothek, kein eigenständiges Avatar-Puppenspielprogramm. Ich arbeite auch an VSeeFace, das die Animation von VRM- und VSFAvatar-3D-Modellen mithilfe von OpenSeeFace-Tracking ermöglicht. VTube Studio verwendet OpenSeeFace für Webcam-basiertes Tracking, um Live2D-Modelle zu animieren. Einen Renderer für die Godot-Engine finden Sie hier.
Dieses Projekt implementiert ein Modell zur Erkennung von Gesichtsmarkierungen basierend auf MobileNetV3.
Da die CPU-Inferenzgeschwindigkeit von Pytorch 1.3 unter Windows sehr niedrig ist, wurde das Modell in das ONNX-Format konvertiert. Mit onnxruntime kann es mit 30–60 fps laufen und ein einzelnes Gesicht verfolgen. Es gibt vier Modelle mit unterschiedlicher Geschwindigkeit bei der Verfolgung von Qualitätskompromissen.
Falls jemand neugierig ist: Der Name ist ein albernes Wortspiel über die offene See und das Sehen von Gesichtern. Es gibt keinen tieferen Sinn.
Ein aktuelles Beispielvideo finden Sie hier, das die Leistung des Standard-Tracking-Modells bei unterschiedlichen Lärm- und Lichtverhältnissen zeigt.
Da sich die von OpenSeeFace verwendeten Orientierungspunkte ein wenig von denen anderer Ansätze unterscheiden (sie ähneln iBUG 68, mit zwei Punkten weniger in den Mundwinkeln und quasi-3D-Gesichtskonturen anstelle von Gesichtskonturen, die dem sichtbaren Umriss folgen), ist dies der Fall Es ist schwierig, seine Genauigkeit numerisch mit der anderer in der wissenschaftlichen Literatur häufig vorkommender Ansätze zu vergleichen. Die Tracking-Leistung ist außerdem eher für die Erstellung von Orientierungspunkten optimiert, die für die Animation eines Avatars nützlich sind, als für die exakte Anpassung des Gesichtsbilds. Solange beispielsweise die Augenmarkierungen anzeigen, ob die Augen geöffnet oder geschlossen sind, können sie für diesen Zweck dennoch nützlich sein, auch wenn ihre Position etwas abweicht.
Aus allgemeiner Sicht schneidet OpenSeeFace auch unter widrigen Bedingungen (wenig Licht, starkes Rauschen, niedrige Auflösung) gut ab und verfolgt Gesichter über ein sehr breites Spektrum an Kopfhaltungen hinweg mit relativ hoher Stabilität der Orientierungspunktpositionen. Im Vergleich zu MediaPipe bleiben OpenSeeFace-Landmarken auch unter schwierigen Bedingungen stabiler und stellen eine größere Bandbreite an Mundhaltungen präzise dar. Allerdings kann die Verfolgung der Augenregion ungenauer sein.
Ich habe OpenSeeFace auf einem Beispielclip aus der Videopräsentation für 3D Face Reconstruction with Dense Landmarks von Wood et al. ausgeführt. um es mit MediaPipe und ihrem Ansatz zu vergleichen. Das Ergebnis können Sie hier ansehen.
Ein Beispiel-Unity-Projekt für VRM-basierte Avatar-Animation finden Sie hier.
Die Gesichtsverfolgung selbst erfolgt durch das Python 3.7-Skript facetracker.py
. Da es sich um ein Befehlszeilenprogramm handelt, sollten Sie es manuell über cmd starten oder eine Batchdatei schreiben, um es zu starten. Wenn Sie eine Version heruntergeladen haben und unter Windows arbeiten, können Sie facetracker.exe
im Binary
ausführen, ohne dass Python installiert ist. Sie können auch die run.bat
im Binary
für eine grundlegende Demonstration des Trackers verwenden.
Das Skript führt das Tracking für Webcam-Eingaben oder Videodateien durch und sendet die Tracking-Daten über UDP. Dieses Design ermöglicht auch die Verfolgung auf einem anderen PC als dem, der die Tracking-Informationen verwendet. Dies kann nützlich sein, um die Leistung zu verbessern und zu verhindern, dass Kameraaufnahmen versehentlich angezeigt werden.
Die bereitgestellte OpenSee
Unity-Komponente kann diese UDP-Pakete empfangen und stellt die empfangenen Informationen über ein öffentliches Feld namens trackingData
bereit. Die OpenSeeShowPoints
Komponente kann die Orientierungspunkte eines erkannten Gesichts visualisieren. Es dient auch als Beispiel. Bitte schauen Sie sich diese an, um zu erfahren, wie Sie die OpenSee
Komponente richtig nutzen. Weitere Beispiele finden Sie im Examples
. Die UDP-Pakete werden in einem separaten Thread empfangen. Daher sollten alle Komponenten, die das Feld trackingData
der OpenSee
-Komponente verwenden, zunächst das Feld kopieren und auf diese Kopie zugreifen, da die Informationen sonst bei der Verarbeitung möglicherweise überschrieben werden. Dieses Design bedeutet auch, dass das Feld weiterhin aktualisiert wird, auch wenn die OpenSee
-Komponente deaktiviert ist.
Führen Sie das Python-Skript mit --help
aus, um mehr über die möglichen Optionen zu erfahren, die Sie festlegen können.
python facetracker.py --help
Eine einfache Demonstration kann erreicht werden, indem eine neue Szene in Unity erstellt und ein leeres Spielobjekt sowie die Komponenten OpenSee
und OpenSeeShowPoints
hinzugefügt werden. Während die Szene abgespielt wird, führen Sie den Face-Tracker für eine Videodatei aus:
python facetracker.py --visualize 3 --pnp-points 1 --max-threads 4 -c video.mp4
Hinweis : Wenn Abhängigkeiten mithilfe von Poetry installiert wurden, müssen die Befehle über eine poetry shell
ausgeführt werden oder ihnen muss poetry run
vorangestellt werden.
Auf diese Weise gibt das Tracking-Skript seine eigene Tracking-Visualisierung aus und demonstriert gleichzeitig die Übertragung von Tracking-Daten an Unity.
Die enthaltene OpenSeeLauncher
Komponente ermöglicht das Starten des Face-Tracker-Programms von Unity aus. Es ist für die Zusammenarbeit mit der von Pyinstaller erstellten ausführbaren Datei konzipiert, die in den Binärversionspaketen verteilt ist. Es bietet drei öffentliche API-Funktionen:
public string[] ListCameras()
gibt die Namen der verfügbaren Kameras zurück. Der Index der Kamera im Array entspricht ihrer ID für das Feld cameraIndex
. Wenn Sie den cameraIndex
auf -1
setzen, wird die Webcam-Aufnahme deaktiviert.public bool StartTracker()
startet den Tracker. Wenn es bereits ausgeführt wird, wird die laufende Instanz heruntergefahren und eine neue mit den aktuellen Einstellungen gestartet.public void StopTracker()
stoppt den Tracker. Der Tracker wird automatisch gestoppt, wenn die Anwendung beendet wird oder das OpenSeeLauncher
-Objekt zerstört wird. Die OpenSeeLauncher
-Komponente verwendet WinAPI-Jobobjekte, um sicherzustellen, dass der untergeordnete Tracker-Prozess beendet wird, wenn die Anwendung abstürzt oder geschlossen wird, ohne zuvor den Tracker-Prozess zu beenden.
Zusätzliche benutzerdefinierte Befehlszeilenargumente sollten nacheinander den Elementen des commandlineArguments
Arrays hinzugefügt werden. Beispielsweise sollte -v 1
als zwei Elemente hinzugefügt werden, wobei ein Element -v
und eines 1
enthält, und nicht ein einzelnes, das beide Teile enthält.
Die enthaltene OpenSeeIKTarget
Komponente kann in Verbindung mit FinalIK oder anderen IK-Lösungen verwendet werden, um Kopfbewegungen zu animieren.
Die OpenSeeExpression
-Komponente kann zur gleichen Komponente wie die OpenSeeFace
-Komponente hinzugefügt werden, um bestimmte Gesichtsausdrücke zu erkennen. Es muss individuell für jeden Benutzer kalibriert werden. Es kann entweder über die Kontrollkästchen im Unity-Editor oder über die entsprechenden öffentlichen Methoden gesteuert werden, die im Quellcode zu finden sind.
Um dieses System zu kalibrieren, müssen Sie Beispieldaten für jeden Ausdruck sammeln. Wenn der Aufnahmevorgang zu schnell abläuft, können Sie ihn mit der Option recordingSkip
verlangsamen.
Der allgemeine Ablauf ist wie folgt:
Um die erfassten Daten für einen Ausdruck zu löschen, geben Sie seinen Namen ein und aktivieren Sie das Kontrollkästchen „Löschen“.
Um sowohl das trainierte Modell als auch die erfassten Trainingsdaten zu speichern, geben Sie einen Dateinamen einschließlich des vollständigen Pfads in das Feld „Dateiname“ ein und aktivieren Sie das Kontrollkästchen „Speichern“. Um es zu laden, geben Sie den Dateinamen ein und aktivieren Sie das Kontrollkästchen „Laden“.
--model 3
ausgewählt, das schnellste Modell mit der niedrigsten Trackingqualität ist --model 0
.--scan-every
-Frame ausgeführt. Dies kann die Geschwindigkeit verlangsamen. Versuchen Sie daher, --faces
nicht höher einzustellen als die tatsächliche Anzahl der Gesichter, die Sie verfolgen. Vier vorab trainierte Gesichts-Landmark-Modelle sind enthalten. Mithilfe des Schalters --model
ist es möglich, diese für die Nachverfolgung auszuwählen. Die angegebenen fps-Werte gelten für die Ausführung des Modells auf einem einseitigen Video auf einem einzelnen CPU-Kern. Eine Verringerung der Bildrate würde die CPU-Auslastung entsprechend reduzieren.
FPS-Messungen stammen von der Ausführung auf einem Kern meiner CPU.
Pytorch-Gewichte zur Verwendung mit model.py
finden Sie hier. Einige nicht optimierte ONNX-Modelle finden Sie hier.
Weitere Beispiele: Results3.png, Results4.png
Das Landmark-Modell ist in Bezug auf die Größe und Ausrichtung der Gesichter recht robust, sodass das benutzerdefinierte Gesichtserkennungsmodell mit gröberen Begrenzungsrahmen auskommt als andere Ansätze. Für die Zwecke dieses Projekts verfügt es über ein günstiges Verhältnis von Geschwindigkeit zu Genauigkeit.
Die Builds im Release-Bereich dieses Repositorys enthalten eine facetracker.exe
in einem Binary
, der mit pyinstaller
erstellt wurde und alle erforderlichen Abhängigkeiten enthält.
Um es auszuführen, muss mindestens der models
-Ordner im selben Ordner wie facetracker.exe
abgelegt werden. Es sollte auch funktionieren, es in einem gemeinsamen übergeordneten Ordner abzulegen.
Wenn Sie es verteilen, sollten Sie auch den Ordner Licenses
mit verteilen, um sicherzustellen, dass Sie den Anforderungen einiger Bibliotheken von Drittanbietern entsprechen. Nicht verwendete Modelle können problemlos aus neu verteilten Paketen entfernt werden.
Die Release-Builds enthalten einen benutzerdefinierten Build von ONNX Runtime ohne Telemetrie.
Die benötigten Bibliotheken können mit pip installiert werden:
pip install onnxruntime opencv-python pillow numpy
Alternativ kann Poetry verwendet werden, um alle Abhängigkeiten für dieses Projekt in einer separaten virtuellen Umgebung zu installieren:
poetry install
Die benötigten Bibliotheken können mit pip installiert werden:
pip install onnxruntime opencv-python pillow numpy
Das Modell wurde auf einer 66-Punkte-Version des LS3D-W-Datensatzes trainiert.
@inproceedings{bulat2017far,
title={How far are we from solving the 2D & 3D Face Alignment problem? (and a dataset of 230,000 3D facial landmarks)},
author={Bulat, Adrian and Tzimiropoulos, Georgios},
booktitle={International Conference on Computer Vision},
year={2017}
}
Der WFLW-Datensatz wurde zusätzlich trainiert, nachdem er auf 66 Punkte reduziert und die Konturpunkte und die Nasenspitze durch Punkte ersetzt wurden, die von dem bis zu diesem Punkt trainierten Modell vorhergesagt wurden. Dieses zusätzliche Training wird durchgeführt, um die Anpassung an Augen und Augenbrauen zu verbessern.
@inproceedings{wayne2018lab,
author = {Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},
title = {Look at Boundary: A Boundary-Aware Face Alignment Algorithm},
booktitle = {CVPR},
month = June,
year = {2018}
}
Für das Training des Blick- und Blinzelerkennungsmodells wurde der MPIIGaze-Datensatz verwendet. Darüber hinaus wurden im Training rund 125.000 mit UnityEyes generierte synthetische Augen verwendet.
Es ist zu beachten, dass während des Trainingsprozesses auch zusätzliche benutzerdefinierte Daten verwendet wurden und dass die Referenzpunkte aus den Originaldatensätzen auf bestimmte Weise geändert wurden, um verschiedene Probleme zu beheben. Es ist wahrscheinlich nicht möglich, diese Modelle nur mit den ursprünglichen LS3D-W- und WFLW-Datensätzen zu reproduzieren, die zusätzlichen Daten sind jedoch nicht weiterverteilbar.
Das auf Heatmap-Regression basierende Gesichtserkennungsmodell wurde auf zufälligen 224x224-Ausschnitten aus dem WIDER FACE-Datensatz trainiert.
@inproceedings{yang2016wider,
Author = {Yang, Shuo and Luo, Ping and Loy, Chen Change and Tang, Xiaoou},
Booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
Title = {WIDER FACE: A Face Detection Benchmark},
Year = {2016}
}
Der Algorithmus ist inspiriert von:
Der MobileNetV3-Code wurde von hier übernommen.
Für alle Trainings wurde eine modifizierte Version von Adaptive Wing Loss verwendet.
Zur Ausdruckserkennung wird LIBSVM verwendet.
Die Gesichtserkennung erfolgt mithilfe eines benutzerdefinierten, auf Heatmap-Regression basierenden Gesichtserkennungsmodells oder RetinaFace.
@inproceedings{deng2019retinaface,
title={RetinaFace: Single-stage Dense Face Localisation in the Wild},
author={Deng, Jiankang and Guo, Jia and Yuxiang, Zhou and Jinke Yu and Irene Kotsia and Zafeiriou, Stefanos},
booktitle={arxiv},
year={2019}
}
Die RetinaFace-Erkennung basiert auf dieser Implementierung. Das vorab trainierte Modell wurde modifiziert, um unnötige Orientierungspunkterkennung zu entfernen, und für eine Auflösung von 640 x 640 in das ONNX-Format konvertiert.
Vielen Dank an alle, die mir beim Testen geholfen haben!
Der Code und die Modelle werden unter der BSD-2-Klausel-Lizenz vertrieben.
Im Ordner Licenses
finden Sie Lizenzen von Bibliotheken Dritter, die für Binär-Builds verwendet werden.