注意:这是一个跟踪库,而不是独立的头像操纵程序。我还在开发 VSeeFace,它允许使用 OpenSeeFace 跟踪对 VRM 和 VSFAvatar 3D 模型进行动画处理。 VTube Studio 使用 OpenSeeFace 进行基于网络摄像头的跟踪来制作 Live2D 模型动画。可以在此处找到 Godot 引擎的渲染器。
该项目实现了基于MobileNetV3的面部标志检测模型。
由于Pytorch 1.3 CPU在Windows上的推理速度很低,因此将模型转换为ONNX格式。使用 onnxruntime,它可以以 30 - 60 fps 的速度运行,跟踪单个脸部。有四种模型,以不同的速度来跟踪质量权衡。
如果有人好奇的话,这个名字是一个愚蠢的双关语,指的是公海和看到面孔。没有什么更深层次的意义。
您可以在此处找到最新的示例视频,其中显示了默认跟踪模型在不同噪声和光照水平下的性能。
由于 OpenSeeFace 使用的标志与其他方法使用的标志有点不同(它们接近 iBUG 68,嘴角少了两个点,并且是准 3D 面部轮廓,而不是遵循可见轮廓的面部轮廓),因此很难将其准确性与科学文献中常见的其他方法进行数值比较。跟踪性能也针对制作对动画化身动画有用的地标进行了更优化,而不是精确拟合面部图像。例如,只要眼睛标志显示眼睛是睁开还是闭上,即使它们的位置有些偏离,它们仍然可以用于此目的。
从一般观察来看,OpenSeeFace 在不利条件下(弱光、高噪声、低分辨率)表现良好,并且通过非常广泛的头部姿势持续跟踪人脸,并且地标位置的稳定性相对较高。与 MediaPipe 相比,OpenSeeFace 地标在具有挑战性的条件下保持更稳定,并且它准确地代表了更广泛的嘴部姿势。然而,眼睛区域的跟踪可能不太准确。
我在 Wood 等人的 3D Face Reconstruction with Dense Landmarks 视频演示中的示例剪辑上运行了 OpenSeeFace。将其与 MediaPipe 及其方法进行比较。您可以在此处查看结果。
您可以在此处找到基于 VRM 的头像动画的 Unity 示例项目。
面部跟踪本身是由facetracker.py
Python 3.7 脚本完成的。它是一个命令行程序,因此您应该从cmd手动启动它或编写批处理文件来启动它。如果您下载了一个版本并且使用的是 Windows,则可以在Binary
文件夹中运行facetracker.exe
,而无需安装 Python。您还可以使用Binary
文件夹中的run.bat
来进行跟踪器的基本演示。
该脚本将对网络摄像头输入或视频文件执行跟踪,并通过 UDP 发送跟踪数据。这种设计还允许在与使用跟踪信息的计算机不同的 PC 上进行跟踪。这对于提高性能并避免意外泄露摄像机镜头很有用。
提供的OpenSee
Unity 组件可以接收这些 UDP 数据包,并通过名为trackingData
的公共字段提供接收到的信息。 OpenSeeShowPoints
组件可以可视化检测到的人脸的标志点。这也可以作为一个例子。请查看它以了解如何正确使用OpenSee
组件。更多示例包含在Examples
文件夹中。 UDP 数据包在单独的线程中接收,因此任何使用OpenSee
组件的trackingData
字段的组件都应首先复制该字段并访问此副本,否则信息可能会在处理过程中被覆盖。这种设计还意味着即使OpenSee
组件被禁用,该字段也会不断更新。
使用--help
运行 python 脚本以了解您可以设置的可能选项。
python facetracker.py --help
通过在 Unity 中创建一个新场景,向其中添加一个空游戏对象以及OpenSee
和OpenSeeShowPoints
组件,可以实现简单的演示。当场景正在播放时,在视频文件上运行面部跟踪器:
python facetracker.py --visualize 3 --pnp-points 1 --max-threads 4 -c video.mp4
注意:如果使用诗歌安装依赖项,则必须从poetry shell
执行命令,或者必须以poetry run
为前缀。
这样,跟踪脚本将输出自己的跟踪可视化,同时还演示跟踪数据到 Unity 的传输。
随附的OpenSeeLauncher
组件允许从 Unity 启动面部跟踪器程序。它旨在与 pyinstaller 创建的可执行文件一起使用,该可执行文件分布在二进制发行包中。它提供了三个公共API函数:
public string[] ListCameras()
返回可用摄像机的名称。数组中相机的索引对应于它的cameraIndex
字段的ID。将cameraIndex
设置为-1
将禁用网络摄像头捕获。public bool StartTracker()
将启动跟踪器。如果它已经在运行,它将关闭正在运行的实例并使用当前设置启动一个新实例。public void StopTracker()
将停止跟踪器。当应用程序终止或OpenSeeLauncher
对象被销毁时,跟踪器会自动停止。 OpenSeeLauncher
组件使用 WinAPI 作业对象来确保如果应用程序崩溃或关闭而未先终止跟踪器进程,则跟踪器子进程也会终止。
其他自定义命令行参数应一一添加到commandlineArguments
数组的元素中。例如, -v 1
应作为两个元素添加,一个元素包含-v
,另一个元素包含1
,而不是单个元素包含这两个部分。
随附的OpenSeeIKTarget
组件可与 FinalIK 或其他 IK 解决方案结合使用,以制作头部运动动画。
可以将OpenSeeExpression
组件添加到与OpenSeeFace
组件相同的组件中,以检测特定的面部表情。它必须针对每个用户进行校准。它可以通过 Unity 编辑器中的复选框或通过其源代码中的等效公共方法进行控制。
要校准该系统,您必须收集每个表达式的示例数据。如果捕获过程进行得太快,您可以使用recordingSkip
选项来减慢速度。
大致流程如下:
要删除表达式捕获的数据,请输入其名称并勾选“清除”框。
要保存经过训练的模型和捕获的训练数据,请在“文件名”字段中输入包含完整路径的文件名,然后勾选“保存”框。要加载它,请输入文件名并勾选“加载”框。
--model 3
选择最高质量的模型,跟踪质量最低的最快模型是--model 0
。--scan-every
帧中运行。这可能会减慢速度,因此请尝试将--faces
设置为不高于您正在跟踪的实际面孔数量。包括四个预训练的面部标志模型。使用--model
开关,可以选择它们进行跟踪。给定的 fps 值适用于在单个 CPU 核心上的单面视频上运行模型。降低帧率会相应减少CPU使用率。
FPS 测量是在我的 CPU 的一个核心上运行的。
可以在此处找到与model.py
一起使用的 Pytorch 权重。可以在此处找到一些未优化的 ONNX 模型。
更多示例:Results3.png、Results4.png
地标模型在面部的大小和方向方面非常稳健,因此自定义面部检测模型比其他方法更粗糙的边界框。就该项目而言,它具有良好的速度与准确率。
此存储库的发布部分中的构建在Binary
文件夹中包含一个facetracker.exe
,该文件夹是使用pyinstaller
构建的,并包含所有必需的依赖项。
要运行它,至少models
文件夹必须放置在与facetracker.exe
相同的文件夹中。将其放在公共父文件夹中也应该可以。
分发它时,您还应该一起分发Licenses
文件夹,以确保您符合某些第三方库提出的要求。可以毫无问题地从重新分发的包中删除未使用的模型。
发布版本包含 ONNX 运行时的自定义版本,无需遥测。
可以使用 pip 安装所需的库:
pip install onnxruntime opencv-python pillow numpy
或者,可以使用诗歌在单独的虚拟环境中安装该项目的所有依赖项:
poetry install
可以使用 pip 安装所需的库:
pip install onnxruntime opencv-python pillow numpy
该模型在 LS3D-W 数据集的 66 点版本上进行训练。
@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}
}
在将 WFLW 数据集减少到 66 个点并将轮廓点和鼻尖替换为到目前为止训练的模型预测的点后,我们对 WFLW 数据集进行了额外的训练。这种额外的训练是为了改善眼睛和眉毛的贴合度。
@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}
}
为了训练凝视和眨眼检测模型,使用了 MPIIGaze 数据集。此外,训练期间使用了 UnityEyes 生成的约 125000 个合成眼睛。
应该指出的是,在训练过程中还使用了额外的自定义数据,并且原始数据集中的参考地标已以某些方式进行了修改以解决各种问题。仅使用原始 LS3D-W 和 WFLW 数据集可能无法重现这些模型,但附加数据不可重新分发。
基于热图回归的人脸检测模型在 WIDER FACE 数据集中的随机 224x224 裁剪上进行训练。
@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}
}
该算法的灵感来自于:
MobileNetV3 代码取自此处。
所有训练均使用自适应翼损的修改版本。
对于表达检测,使用 LIBSVM。
人脸检测是使用基于人脸检测模型或 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}
}
RetinaFace检测就是基于这个实现的。对预训练模型进行了修改,删除了不必要的地标检测,并将其转换为分辨率为 640x640 的 ONNX 格式。
非常感谢所有帮助我测试的人!
代码和模型根据 BSD 2 条款许可证分发。
您可以在Licenses
夹中找到用于二进制构建的第三方库的许可证。