Nota : Esta é uma biblioteca de rastreamento, não um programa independente de marionetes de avatar. Também estou trabalhando no VSeeFace, que permite animar modelos 3D VRM e VSFAvatar usando rastreamento OpenSeeFace. VTube Studio usa OpenSeeFace para rastreamento baseado em webcam para animar modelos Live2D. Um renderizador para o mecanismo Godot pode ser encontrado aqui.
Este projeto implementa um modelo de detecção de pontos de referência facial baseado em MobileNetV3.
Como a velocidade de inferência da CPU do Pytorch 1.3 no Windows é muito baixa, o modelo foi convertido para o formato ONNX. Usando onnxruntime, ele pode rodar de 30 a 60 fps rastreando um único rosto. Existem quatro modelos, com velocidades diferentes para rastrear compensações de qualidade.
Se alguém estiver curioso, o nome é um trocadilho bobo com mar aberto e ver rostos. Não há significado mais profundo.
Um exemplo de vídeo atualizado pode ser encontrado aqui, mostrando o desempenho do modelo de rastreamento padrão sob diferentes níveis de ruído e luz.
Como os pontos de referência usados pelo OpenSeeFace são um pouco diferentes daqueles usados por outras abordagens (eles são próximos ao iBUG 68, com dois pontos a menos nos cantos da boca e contornos faciais quase 3D em vez de contornos faciais que seguem o contorno visível), é difícil comparar numericamente sua precisão com outras abordagens comumente encontradas na literatura científica. O desempenho do rastreamento também é mais otimizado para criar pontos de referência úteis para animar um avatar do que para ajustar exatamente a imagem do rosto. Por exemplo, desde que os pontos de referência dos olhos mostrem se os olhos estão abertos ou fechados, mesmo que a sua localização esteja um pouco errada, eles ainda podem ser úteis para este propósito.
A partir da observação geral, o OpenSeeFace funciona bem em condições adversas (pouca luz, alto ruído, baixa resolução) e continua rastreando rostos através de uma ampla variedade de poses de cabeça com estabilidade relativamente alta de posições de referência. Em comparação com o MediaPipe, os pontos de referência OpenSeeFace permanecem mais estáveis em condições desafiadoras e representam com precisão uma gama mais ampla de poses de boca. No entanto, o rastreamento da região ocular pode ser menos preciso.
Executei o OpenSeeFace em um clipe de amostra da apresentação em vídeo de 3D Face Reconstruction with Dense Landmarks de Wood et al. para compará-lo com o MediaPipe e sua abordagem. Você pode assistir o resultado aqui.
Um exemplo de projeto Unity para animação de avatar baseada em VRM pode ser encontrado aqui.
O rastreamento facial em si é feito pelo script facetracker.py
Python 3.7. É um programa de linha de comando, então você deve iniciá-lo manualmente a partir do cmd ou escrever um arquivo em lote para iniciá-lo. Se você baixou uma versão e está no Windows, pode executar o facetracker.exe
dentro da pasta Binary
sem ter o Python instalado. Você também pode usar run.bat
dentro da pasta Binary
para uma demonstração básica do rastreador.
O script realizará o rastreamento na entrada da webcam ou arquivo de vídeo e enviará os dados de rastreamento por UDP. Este design também permite que o rastreamento seja feito em um PC separado daquele que utiliza as informações de rastreamento. Isso pode ser útil para melhorar o desempenho e evitar a revelação acidental de imagens da câmera.
O componente OpenSee
Unity fornecido pode receber esses pacotes UDP e fornecer as informações recebidas por meio de um campo público chamado trackingData
. O componente OpenSeeShowPoints
pode visualizar os pontos de referência de um rosto detectado. Também serve de exemplo. Por favor, dê uma olhada para ver como usar corretamente o componente OpenSee
. Outros exemplos estão incluídos na pasta Examples
. Os pacotes UDP são recebidos em um thread separado, portanto, qualquer componente que use o campo trackingData
do componente OpenSee
deve primeiro copiar o campo e acessar esta cópia, caso contrário, as informações poderão ser substituídas durante o processamento. Este design também significa que o campo continuará sendo atualizado, mesmo se o componente OpenSee
estiver desabilitado.
Execute o script python com --help
para saber mais sobre as opções possíveis que você pode definir.
python facetracker.py --help
Uma demonstração simples pode ser obtida criando uma nova cena no Unity, adicionando um objeto de jogo vazio e os componentes OpenSee
e OpenSeeShowPoints
a ele. Enquanto a cena está sendo reproduzida, execute o rastreador facial em um arquivo de vídeo:
python facetracker.py --visualize 3 --pnp-points 1 --max-threads 4 -c video.mp4
Nota : Se as dependências foram instaladas usando poesia, os comandos devem ser executados a partir de um poetry shell
ou devem ser prefixados com poetry run
.
Dessa forma, o script de rastreamento produzirá sua própria visualização de rastreamento, ao mesmo tempo que demonstra a transmissão de dados de rastreamento para o Unity.
O componente OpenSeeLauncher
incluído permite iniciar o programa rastreador facial do Unity. Ele foi projetado para funcionar com o executável criado pelo pyinstaller distribuído nos pacotes de lançamento binário. Ele fornece três funções de API públicas:
public string[] ListCameras()
retorna os nomes das câmeras disponíveis. O índice da câmera no array corresponde ao seu ID para o campo cameraIndex
. Definir cameraIndex
como -1
desativará a captura da webcam.public bool StartTracker()
iniciará o rastreador. Se já estiver em execução, encerrará a instância em execução e iniciará uma nova com as configurações atuais.public void StopTracker()
irá parar o rastreador. O rastreador é interrompido automaticamente quando o aplicativo é encerrado ou o objeto OpenSeeLauncher
é destruído. O componente OpenSeeLauncher
usa objetos de trabalho WinAPI para garantir que o processo filho do rastreador seja encerrado se o aplicativo travar ou fechar sem encerrar o processo do rastreador primeiro.
Argumentos de linha de comando personalizados adicionais devem ser adicionados um por um aos elementos da matriz commandlineArguments
. Por exemplo -v 1
deve ser adicionado como dois elementos, um elemento contendo -v
e outro contendo 1
, e não um único contendo ambas as partes.
O componente OpenSeeIKTarget
incluído pode ser usado em conjunto com FinalIK ou outras soluções IK para animar o movimento da cabeça.
O componente OpenSeeExpression
pode ser adicionado ao mesmo componente que o componente OpenSeeFace
para detectar expressões faciais específicas. Ele deve ser calibrado por usuário. Ele pode ser controlado através das caixas de seleção no Editor Unity ou através dos métodos públicos equivalentes que podem ser encontrados em seu código-fonte.
Para calibrar este sistema, é necessário coletar dados de exemplo para cada expressão. Se o processo de captura estiver muito rápido, você pode usar a opção recordingSkip
para retardá-lo.
O processo geral é o seguinte:
Para excluir os dados capturados de uma expressão, digite seu nome e marque a caixa “Limpar”.
Para salvar o modelo treinado e os dados de treinamento capturados, digite um nome de arquivo incluindo seu caminho completo no campo “Nome do arquivo” e marque a caixa “Salvar”. Para carregá-lo, digite o nome do arquivo e marque a caixa “Carregar”.
--model 3
, o modelo mais rápido com a menor qualidade de rastreamento é --model 0
.--scan-every
. Isso pode tornar as coisas mais lentas, então tente definir --faces
não superior ao número real de rostos que você está rastreando. Quatro modelos de pontos de referência faciais pré-treinados estão incluídos. Usando a opção --model
, é possível selecioná-los para rastreamento. Os valores de fps fornecidos são para executar o modelo em um vídeo de face única em um único núcleo de CPU. A redução da taxa de quadros reduziria o uso da CPU em um grau correspondente.
As medições de FPS são executadas em um núcleo da minha CPU.
Os pesos Pytorch para uso com model.py
podem ser encontrados aqui. Alguns modelos ONNX não otimizados podem ser encontrados aqui.
Mais amostras: Results3.png, Results4.png
O modelo de referência é bastante robusto em relação ao tamanho e à orientação dos rostos, de modo que o modelo personalizado de detecção de rosto funciona com caixas delimitadoras mais grosseiras do que outras abordagens. Possui uma relação velocidade/precisão favorável para os fins deste projeto.
As compilações na seção de lançamento deste repositório contêm um facetracker.exe
dentro de uma pasta Binary
que foi construída usando pyinstaller
e contém todas as dependências necessárias.
Para executá-lo, pelo menos a pasta models
deve ser colocada na mesma pasta que facetracker.exe
. Colocá-lo em uma pasta pai comum também deve funcionar.
Ao distribuí-lo, você também deve distribuir a pasta Licenses
junto com ele para garantir que está em conformidade com os requisitos estabelecidos por algumas bibliotecas de terceiros. Modelos não utilizados podem ser removidos de pacotes redistribuídos sem problemas.
As compilações de lançamento contêm uma compilação personalizada do ONNX Runtime sem telemetria.
As bibliotecas necessárias podem ser instaladas usando pip:
pip install onnxruntime opencv-python pillow numpy
Alternativamente, a poesia pode ser usada para instalar todas as dependências deste projeto em um ambiente virtual separado:
poetry install
As bibliotecas necessárias podem ser instaladas usando pip:
pip install onnxruntime opencv-python pillow numpy
O modelo foi treinado em uma versão de 66 pontos do conjunto de dados 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}
}
Treinamento adicional foi feito no conjunto de dados WFLW após reduzi-lo para 66 pontos e substituir os pontos de contorno e ponta do nariz por pontos previstos pelo modelo treinado até este ponto. Este treinamento adicional é feito para melhorar o ajuste aos olhos e sobrancelhas.
@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}
}
Para o treinamento do modelo de detecção de olhar e piscar, foi utilizado o conjunto de dados MPIIGaze. Além disso, cerca de 125.000 olhos sintéticos gerados com UnityEyes foram usados durante o treinamento.
Deve-se notar que dados personalizados adicionais também foram usados durante o processo de treinamento e que os pontos de referência dos conjuntos de dados originais foram modificados de certas maneiras para abordar vários problemas. Provavelmente não é possível reproduzir esses modelos apenas com os conjuntos de dados LS3D-W e WFLW originais, no entanto, os dados adicionais não são redistribuíveis.
O modelo de detecção facial baseado em regressão de mapa de calor foi treinado em cortes aleatórios de 224x224 do conjunto de dados 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}
}
O algoritmo é inspirado em:
O código MobileNetV3 foi retirado daqui.
Para todos os treinos foi utilizada uma versão modificada do Adaptive Wing Loss.
Para detecção de expressão, LIBSVM é usado.
A detecção de rosto é feita usando um modelo de detecção de rosto baseado em regressão de mapa de calor personalizado 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}
}
A detecção do RetinaFace é baseada nesta implementação. O modelo pré-treinado foi modificado para remover a detecção desnecessária de pontos de referência e convertido para o formato ONNX para uma resolução de 640x640.
Muito obrigado a todos que me ajudaram a testar as coisas!
O código e os modelos são distribuídos sob a licença BSD de 2 cláusulas.
Você pode encontrar licenças de bibliotecas de terceiros usadas para compilações binárias na pasta Licenses
.