Remarque : Il s'agit d'une bibliothèque de suivi et non d'un programme de marionnettes d'avatar autonome. Je travaille également sur VSeeFace, qui permet d'animer des modèles 3D VRM et VSFAvatar en utilisant le tracking OpenSeeFace. VTube Studio utilise OpenSeeFace pour le suivi par webcam afin d'animer les modèles Live2D. Un moteur de rendu pour le moteur Godot peut être trouvé ici.
Ce projet implémente un modèle de détection de repères faciaux basé sur MobileNetV3.
La vitesse d'inférence du CPU Pytorch 1.3 sous Windows étant très faible, le modèle a été converti au format ONNX. En utilisant onnxruntime, il peut fonctionner entre 30 et 60 ips en suivant un seul visage. Il existe quatre modèles, avec des vitesses différentes pour suivre les compromis de qualité.
Si quelqu'un est curieux, le nom est un jeu de mots idiot sur le large et le fait de voir des visages. Il n'y a pas de sens plus profond.
Un exemple de vidéo à jour peut être trouvé ici, montrant les performances du modèle de suivi par défaut sous différents niveaux de bruit et de lumière.
Puisque les repères utilisés par OpenSeeFace sont un peu différents de ceux utilisés par d'autres approches (ils sont proches d'iBUG 68, avec deux points en moins dans les coins de la bouche et des contours de visage quasi-3D au lieu de contours de visage qui suivent le contour visible), il est Il est difficile de comparer numériquement sa précision à celle d’autres approches que l’on trouve couramment dans la littérature scientifique. Les performances de suivi sont également plus optimisées pour créer des repères utiles à l'animation d'un avatar que pour ajuster exactement l'image du visage. Par exemple, tant que les repères oculaires indiquent si les yeux sont ouverts ou fermés, même si leur emplacement est quelque peu décalé, ils peuvent toujours être utiles à cette fin.
D'après l'observation générale, OpenSeeFace fonctionne bien dans des conditions défavorables (faible luminosité, bruit élevé, faible résolution) et continue de suivre les visages dans une très large gamme de poses de tête avec une stabilité relativement élevée des positions de repère. Par rapport à MediaPipe, les repères OpenSeeFace restent plus stables dans des conditions difficiles et représentent avec précision un plus large éventail de poses buccales. Cependant, le suivi de la région oculaire peut être moins précis.
J'ai exécuté OpenSeeFace sur un exemple de clip de la présentation vidéo pour la reconstruction de visage 3D avec des repères denses par Wood et al. pour le comparer à MediaPipe et à leur approche. Vous pouvez regarder le résultat ici.
Un exemple de projet Unity pour l'animation d'avatar basée sur VRM peut être trouvé ici.
Le suivi du visage lui-même est effectué par le script facetracker.py
Python 3.7. Il s'agit d'un programme en ligne de commande, vous devez donc le démarrer manuellement à partir de cmd ou écrire un fichier batch pour le démarrer. Si vous avez téléchargé une version et que vous êtes sous Windows, vous pouvez exécuter facetracker.exe
dans le dossier Binary
sans avoir installé Python. Vous pouvez également utiliser le run.bat
dans le dossier Binary
pour une démonstration de base du tracker.
Le script effectuera le suivi sur l'entrée de la webcam ou sur le fichier vidéo et enverra les données de suivi via UDP. Cette conception permet également d'effectuer le suivi sur un PC distinct de celui qui utilise les informations de suivi. Cela peut être utile pour améliorer les performances et éviter de révéler accidentellement les images de la caméra.
Le composant OpenSee
Unity fourni peut recevoir ces paquets UDP et fournit les informations reçues via un champ public appelé trackingData
. Le composant OpenSeeShowPoints
peut visualiser les points de repère d'un visage détecté. Cela sert également d’exemple. Veuillez le consulter pour voir comment utiliser correctement le composant OpenSee
. D'autres exemples sont inclus dans le dossier Examples
. Les paquets UDP sont reçus dans un thread séparé, donc tous les composants utilisant le champ trackingData
du composant OpenSee
doivent d'abord copier le champ et accéder à cette copie, car sinon les informations pourraient être écrasées pendant le traitement. Cette conception signifie également que le champ continuera à être mis à jour, même si le composant OpenSee
est désactivé.
Exécutez le script python avec --help
pour en savoir plus sur les options possibles que vous pouvez définir.
python facetracker.py --help
Une démonstration simple peut être réalisée en créant une nouvelle scène dans Unity, en y ajoutant un objet de jeu vide et les composants OpenSee
et OpenSeeShowPoints
. Pendant la lecture de la scène, exécutez le suivi du visage sur un fichier vidéo :
python facetracker.py --visualize 3 --pnp-points 1 --max-threads 4 -c video.mp4
Remarque : Si les dépendances ont été installées à l'aide de la poésie, les commandes doivent être exécutées à partir d'un poetry shell
ou doivent être préfixées par poetry run
.
De cette façon, le script de suivi produira sa propre visualisation de suivi tout en démontrant également la transmission des données de suivi à Unity.
Le composant OpenSeeLauncher
inclus permet de démarrer le programme de suivi du visage depuis Unity. Il est conçu pour fonctionner avec l'exécutable créé par pyinstaller et distribué dans les bundles de versions binaires. Il fournit trois fonctions API publiques :
public string[] ListCameras()
renvoie les noms des caméras disponibles. L'index de la caméra dans le tableau correspond à son ID pour le champ cameraIndex
. Définir cameraIndex
sur -1
désactivera la capture par webcam.public bool StartTracker()
démarrera le tracker. S'il est déjà en cours d'exécution, il arrêtera l'instance en cours d'exécution et en démarrera une nouvelle avec les paramètres actuels.public void StopTracker()
arrêtera le tracker. Le tracker s'arrête automatiquement lorsque l'application est terminée ou que l'objet OpenSeeLauncher
est détruit. Le composant OpenSeeLauncher
utilise des objets de travail WinAPI pour garantir que le processus enfant de suivi est terminé si l'application se bloque ou se ferme sans mettre fin au processus de suivi au préalable.
Des arguments de ligne de commande personnalisés supplémentaires doivent être ajoutés un par un dans les éléments du tableau commandlineArguments
. Par exemple, -v 1
doit être ajouté sous forme de deux éléments, un élément contenant -v
et un autre contenant 1
, et non un seul contenant les deux parties.
Le composant OpenSeeIKTarget
inclus peut être utilisé conjointement avec FinalIK ou d'autres solutions IK pour animer le mouvement de la tête.
Le composant OpenSeeExpression
peut être ajouté au même composant que le composant OpenSeeFace
pour détecter des expressions faciales spécifiques. Il doit être calibré pour chaque utilisateur. Il peut être contrôlé soit via les cases à cocher dans l'éditeur Unity, soit via les méthodes publiques équivalentes que l'on peut trouver dans son code source.
Pour calibrer ce système, vous devez rassembler des exemples de données pour chaque expression. Si le processus de capture va trop vite, vous pouvez utiliser l'option recordingSkip
pour le ralentir.
Le processus général est le suivant :
Pour supprimer les données capturées pour une expression, saisissez son nom et cochez la case "Effacer".
Pour enregistrer à la fois le modèle entraîné et les données d'entraînement capturées, saisissez un nom de fichier incluant son chemin complet dans le champ "Nom de fichier" et cochez la case "Enregistrer". Pour le charger, entrez le nom du fichier et cochez la case "Charger".
--model 3
, le modèle le plus rapide avec la qualité de suivi la plus faible est --model 0
.--scan-every
. Cela peut ralentir les choses, alors essayez de définir --faces
pas plus haut que le nombre réel de visages que vous suivez. Quatre modèles de repères de visage pré-entraînés sont inclus. En utilisant le commutateur --model
, il est possible de les sélectionner pour le suivi. Les valeurs fps données servent à exécuter le modèle sur une vidéo à une seule face sur un seul cœur de processeur. Réduire la fréquence d’images réduirait l’utilisation du processeur d’un degré correspondant.
Les mesures FPS proviennent de l'exécution sur un cœur de mon processeur.
Les poids Pytorch à utiliser avec model.py
peuvent être trouvés ici. Certains modèles ONNX non optimisés peuvent être trouvés ici.
Plus d'échantillons : Results3.png, Results4.png
Le modèle de repère est assez robuste en ce qui concerne la taille et l'orientation des visages, de sorte que le modèle de détection de visage personnalisé s'en sort avec des cadres de délimitation plus grossiers que les autres approches. Il présente un rapport vitesse/précision favorable pour les besoins de ce projet.
Les versions de la section version de ce référentiel contiennent un facetracker.exe
dans un dossier Binary
qui a été construit à l'aide pyinstaller
et contient toutes les dépendances requises.
Pour l'exécuter, au moins le dossier models
doit être placé dans le même dossier que facetracker.exe
. Le placer dans un dossier parent commun devrait également fonctionner.
Lors de sa distribution, vous devez également distribuer le dossier Licenses
avec celui-ci pour vous assurer que vous vous conformez aux exigences énoncées par certaines bibliothèques tierces. Les modèles inutilisés peuvent être supprimés des packages redistribués sans problème.
Les versions de version contiennent une version personnalisée d'ONNX Runtime sans télémétrie.
Les bibliothèques requises peuvent être installées à l'aide de pip :
pip install onnxruntime opencv-python pillow numpy
Alternativement, la poésie peut être utilisée pour installer toutes les dépendances de ce projet dans un environnement virtuel distinct :
poetry install
Les bibliothèques requises peuvent être installées à l'aide de pip :
pip install onnxruntime opencv-python pillow numpy
Le modèle a été formé sur une version 66 points de l'ensemble de données LS3D-W.
@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}
}
Une formation supplémentaire a été effectuée sur l'ensemble de données WFLW après l'avoir réduit à 66 points et remplacé les points de contour et le bout du nez par des points prédits par le modèle entraîné jusqu'à présent. Cette formation supplémentaire vise à améliorer l'ajustement des yeux et des sourcils.
@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}
}
Pour la formation du modèle de détection du regard et des clignements, l'ensemble de données MPIIGaze a été utilisé. De plus, environ 125 000 yeux synthétiques générés avec UnityEyes ont été utilisés pendant la formation.
Il convient de noter que des données personnalisées supplémentaires ont également été utilisées au cours du processus de formation et que les repères de référence des ensembles de données d'origine ont été modifiés de certaines manières pour résoudre divers problèmes. Il n'est probablement pas possible de reproduire ces modèles avec uniquement les ensembles de données originaux LS3D-W et WFLW, mais les données supplémentaires ne sont pas redistribuables.
Le modèle de détection de visage basé sur la régression Heatmap a été formé sur des cultures aléatoires de 224 x 224 à partir de l'ensemble de données WIDER FACE.
@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}
}
L’algorithme s’inspire de :
Le code MobileNetV3 a été extrait d'ici.
Pour toute formation, une version modifiée de Adaptive Wing Loss a été utilisée.
Pour la détection d'expression, LIBSVM est utilisé.
La détection des visages est effectuée à l'aide d'un modèle de détection de visage personnalisé basé sur la régression de la carte thermique ou 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}
}
La détection RetinaFace est basée sur cette implémentation. Le modèle pré-entraîné a été modifié pour supprimer la détection de points de repère inutiles et converti au format ONNX pour une résolution de 640 x 640.
Un grand merci à tous ceux qui m'ont aidé à tester des choses !
Le code et les modèles sont distribués sous la licence BSD 2 clauses.
Vous pouvez trouver les licences des bibliothèques tierces utilisées pour les builds binaires dans le dossier Licenses
.