JavaScript/WebGL设计用于增强现实面部滤镜的轻量且稳健的面部跟踪库
这个JavaScript库可以从使用WebRTC捕获的摄像头视频流中实时检测和跟踪面部。然后,可以为增强现实应用覆盖3D内容。我们使用主要的WebGL 3D引擎提供了各种演示。在这个库中,我们已经包含了与特定版本一起工作的3D引擎的发布版本(它们位于/libs/<引擎名称>/
中)。
这个库是轻量级的,它不包含任何3D引擎或第三方库。我们想保持它的框架无关性,因此库的输出是原始的数据:是否检测到面部、检测到的面部的位置和大小以及旋转的欧拉角。但是,感谢所提供的帮助工具、示例和样板,您可以快速处理更高级别的上下文(用于运动头部跟踪、面部滤镜或面部替换...)。我们不断增加新的演示,所以请保持关注!
目录
特性
以下是库的主要特性:
- 面部检测,
- 面部跟踪,
- 面部旋转检测,
- 嘴部张开检测,
- 多面部检测和跟踪,
- 在所有光照条件下都非常稳健,
- 支持HD视频的视频采集,
- 移动友好,
- 与THREE.JS、BABYLON.JS、A-FRAME等3D引擎接口,
- 与如CANVAS、CSS3D等更易访问的API接口。
架构
/demos/
:演示的源代码,根据使用的2D/3D引擎分类,/dist/
:库的核心脚本:jeelizFaceFilter.js
:主要的压缩脚本,jeelizFaceFilter.module.js
:作为模块使用(使用import
或require
)的主要压缩脚本,
/neuralNets
:训练的神经网络模型:NN_DEFAULT.json
:存储神经网络参数的文件,由主要脚本加载,NN_<xxx>.json
:替代神经网络模型,
/helpers/
:在某些特定用例中帮助使用此库的脚本,/libs/
:演示中使用的第三方库和3D引擎,/reactThreeFiberDemo/
:NPM/React/Webpack/Three-Fiber脚手架。
演示和应用
包含在这个库中
这些演示包含在这个库中。因此,它们是根据FaceFilter许可发布的。您可能会在其中找到构建您自己基于面部的增强现实应用的完美起点:
-
REACT/THREE FIBER脚手架: /reactThreeFiberDemo
-
基于BABYLON.JS的演示:
-
基于THREE.JS的演示—— 关于THREE.js演示问题的特定README:
-
脚手架:
-
AR 3D演示:
-
面部绘画或变形:
-
与教程相关的演示:
-
杂项:
-
-
基于A-FRAME的演示:
-
基于CSS3D的演示:
-
基于Canvas2D的演示:
-
基于CESIUM.JS的演示:
-
人脸替换演示:
-
头部运动控制:
一些截图视频可在YouTube上观看。你也可以订阅Jeeliz YouTube频道或@WebARRocks Twitter账号,以便了解我们最新的开发情况。
第三方
以下这些精彩的应用程序依赖此库进行人脸检测和跟踪:
-
由Movable Ink制作的应用程序:
-
Halloween masks: 由Thorsten Bux制作的精彩万圣节面具体验。代码在Github上发布:ThorstenBux/halloween-masks。
-
GazeFilter: 准确跟踪瞳孔位置的库。有一个很好的眼动追踪演示,包括FaceFilter输出的调试视图在这里。
-
SnapChat Clone: 由Towhid Kashem制作的精彩工作。该库已被封装以构建一个Snapchat克隆。查看Github源代码库,尝试实时演示或阅读Reddit帖子。
-
Facepaint: 使用这个由Patricia Arnedo开发的创意网络应用程序绘制你自己的面部滤镜 - 关于演示的Medium文章
-
Virtual Fighter: 发现与你相似的Virtual Fighter(SEGA视频游戏)。该实验的第一部分依赖于face-api.js来检测你的脸和标记。然后点击PUSH,一个虚拟战士的3D面部滤镜将使用该库和Three.js应用到你的脸上。
-
Are you a true wizard? 尝试在这个由Level 30 Wizards制作的演示中佩戴奇妙的巫师帽
-
Vertebrae VTO: Vertebrae依赖该库进行一些虚拟试穿产品的人脸检测和跟踪。你可以在以下网站查看:
- Moscot: 点击产品图片左上方的VIRTUAL TRY-ON按钮,
- Goodr: 点击产品图片左上方的VIRTUAL TRY-ON按钮,
- Tenth Street: 点击Try it on按钮。
如果你使用此库开发了应用程序或有趣的演示,我们很乐意看到并在这里插入链接!只需在Twitter @WebARRocks或LinkedIn上联系我们
规格
这里描述如何使用该库。虽然我们计划增加新功能,但我们会保持向后兼容。
开始使用
在你的HTML页面中,你首先需要在<head>
和</head>
标签之间包含主脚本:
<script src="dist/jeelizFaceFilter.js"></script>
然后你应该在DOM中<body>
和</body>
标签之间包含一个<canvas>
HTML元素。<canvas>
元素的width
和height
属性应被设置。它们定义了画布的分辨率,最终渲染将使用这个分辨率进行计算。请注意,不要在不增加分辨率的情况下通过其CSS属性过多地放大画布尺寸,否则可能会显得模糊或像素化。我们建议将分辨率固定为实际的画布大小。如果在初始化步骤后调整了画布大小,请不要忘记调用JEELIZFACEFILTER.resize()
。我们强烈建议你使用我们的助手/helpers/JeelizResizer.js
来设置画布的宽度和高度(请参阅优化/画布和视频分辨率部分)。
<canvas width="600" height="600" id='jeeFaceFilterCanvas'></canvas>
这个画布将被WebGL用于计算和3D渲染。当你的页面加载时,你应该启动这个函数:
JEELIZFACEFILTER.init({
canvasId: 'jeeFaceFilterCanvas',
NNCPath: '../../../neuralNets/', // JSON神经网络模型的路径(默认为NN_DEFAULT.json)
callbackReady: function(errCode, spec){
if (errCode){
console.log('发生错误。错误代码 =', errCode);
return;
}
// [init scene with spec...]
console.log('信息: JEELIZFACEFILTER 已准备好');
}, //结束 callbackReady()
// 在每次渲染迭代时被调用(绘制循环)
callbackTrack: function(detectState){
// 在这里渲染你的场景
// [... do something with detectState]
} //结束 callbackTrack()
});
可选初始化参数
<boolean> followZRot
: 允许绕深度轴完全旋转。默认值:false
。请参阅Issue 42了解更多详情,<integer> maxFacesDetected
: 仅用于多脸检测 - 可以检测和跟踪的最大面数。应在1
(无多重检测)和8
之间,<integer> animateDelay
: 仅在正常渲染模式(非慢速渲染模式)下使用。通过这个语句,你可以准确地设置渲染循环末尾浏览器在开始另一个检测之前等待的毫秒数。如果你使用该库的画布作为辅助元素(例如在PACMAN或地球导航示例中),你应该设置一个较小的animateDelay
值(例如2毫秒),以避免渲染延迟。<function> onWebcamAsk
: 在请求用户允许访问其摄像头之前启动的函数,<function> onWebcamGet
: 在用户接受共享其视频后启动的函数。它以视频元素作为参数调用,<dict> videoSettings
: 覆盖WebRTC指定的视频设置,默认值为:
{
'videoElement' // 默认未设置。使用的<video>元素
// 警告:如果你指定了这个参数,
// 1. 所有其他设置将无效
// 2. 这意味着你完全处理视频方面的问题
// 3. 如果使用网络摄像头设备,请确保初始化在`videoElement`的`loadeddata`事件之后进行,
// 否则人脸检测器将生成非常低的`detectState.detected`值
// (为了更加确定,也等待第一个`timeupdate`事件)
'deviceId' // 默认未设置
'facingMode': 'user', // 要使用后置摄像头,请设置为'environment'
'idealWidth': 800, // 理想的视频宽度(像素)
'idealHeight': 600, // 理想的视频高度(像素)
'minWidth': 480, // 最小视频宽度(像素)
'maxWidth': 1920, // 最大视频宽度(像素)
'minHeight': 480, // 最小视频高度(像素)
'maxHeight': 1920, // 最大视频高度(像素)
'rotate': 0, // 旋转度数可能的值:0,90,-90,180
'flipX': false // 是否水平翻转视频。默认值:false
},
如果用户使用的是处于纵向显示模式的移动设备,则这些参数的宽度和高度会在首次请求摄像头时自动互换。如果不成功,我们会互换宽度和高度。
<dict> scanSettings
:覆盖面部扫描设置 - 查看set_scanSettings(...)
方法了解更多信息。<dict> stabilizationSettings
:覆盖跟踪稳定设置 - 查看set_stabilizationSettings(...)
方法了解更多信息。<boolean> isKeepRunningOnWinFocusLost
:即使用户切换浏览器标签或最小化浏览器窗口,是否继续运行检测循环。默认值为false
。此选项对视频会议应用程序非常有用,在FaceFilter的窗口不是激活状态时仍需计算面部遮罩。即使启用此选项,当FaceFilter窗口不激活时面部跟踪仍会变慢。
错误代码
初始化函数(代码片段中的 callbackReady
)将通过错误代码(errCode
)调用。它可以有以下值:
false
:没有发生错误,"GL_INCOMPATIBLE"
:WebGL不可用,或此WebGL配置不够(没有WebGL2,或者只有不带OES_TEXTURE_FLOAT或OES_TEXTURE_HALF_FLOAT扩展的WebGL1),"ALREADY_INITIALIZED"
:库已经初始化过,"NO_CANVASID"
:没有指定画布或画布ID,"INVALID_CANVASID"
:在DOM中找不到<canvas>
元素,"INVALID_CANVASDIMENSIONS"
:未指定画布的宽度和高度,"WEBCAM_UNAVAILABLE"
:无法获得相机访问权限(用户没有相机,或没有同意共享设备,或相机已经被占用),"GLCONTEXT_LOST"
:WebGL上下文丢失。如果在初始化之后上下文丢失,callbackReady
函数将第二次以此值作为错误代码被调用,"MAXFACES_TOOHIGH"
:由可选初始化参数maxFacesDetected
指定的最大检测和跟踪面部数量过高。
返回的对象
我们在此详述诸如 callbackReady
或 callbackTrack
回调函数的参数。这些对象的引用不会改变以进行内存优化。所以如果您希望在回调函数作用域之外保持它们不变,则应复制它们的属性值。
初始化返回的对象
如果没有错误,初始化回调函数(代码片段中的 callbackReady
)将通过第二个参数 spec
调用。spec
是一个具有以下属性的字典:
<WebGLRenderingContext> GL
:WebGL上下文。渲染3D引擎应使用此WebGL上下文,<canvas> canvasElement
:<canvas>
元素,<WebGLTexture> videoTexture
:显示相机视频的WebGL纹理。它的分辨率与相机视频相同,[<float>, <float>, <float>, <float>]
videoTransformMat2:表示缩放和旋转的2x2矩阵。我们应将此矩阵应用于视口坐标,以在视口中渲染videoTexture
,<HTMLVideoElement> videoElement
:用作WebGL纹理videoTexture
源的视频,<int> maxFacesDetected
:检测到的最大面部数量。
检测状态
在每次渲染迭代时,回调函数(代码片段中的 callbackTrack
)都会执行。它有一个参数(detectState
),这是一个具有以下属性的字典:
<float> detected
:面部检测概率,介于0
和1
之间,<float> x
,<float> y
:检测框中心在视口中的2D坐标(均介于-1和1之间,x
从左到右,y
从下到上),<float> s
:检测框沿水平轴的缩放比例,介于0和1之间(1为全宽)。检测框始终是正方形,<float> rx
,<float> ry
,<float> rz
:头部旋转的欧拉角,以弧度表示,<Float32Array> expressions
:列出面部表情系数的数组:expressions[0]
:嘴巴张开系数(0
→嘴巴闭合,1
→嘴巴完全张开)
在多面部检测模式下,detectState
是一个数组。其大小等于最大检测到的面部数量,数组中的每个元素格式如前所述。
其他方法
在初始化后(即 callbackReady
被调用后),将可用以下方法:
-
JEELIZFACEFILTER.resize()
:在调整<canvas>
元素大小后调用,以自适应调整视频的剪裁。如设备方向改变,也应调用该方法以考虑新的视频维度, -
JEELIZFACEFILTER.toggle_pause(<boolean> isPause, <boolean> isShutOffVideo)
:暂停/恢复。此方法将完全停止渲染/检测循环。如果isShutOffVideo
设置为true
,媒体流轨道将被停止,相机灯将关闭。它返回一个Promise
对象, -
JEELIZFACEFILTER.toggle_slow(<boolean> isSlow)
:切换慢速渲染模式:因为此库可能消耗大量GPU资源,它可能会使应用程序的其他元素变慢。如果用户打开例如CSS菜单,CSS过渡和DOM更新可能会变慢。通过此功能,可以通过减慢渲染速度来缓解GPU压力。遗憾的是,跟踪和3D渲染也会变慢,但当用户专注于画布的其他部分时,这不是问题。我们建议在用户关注画布的其他部分时启用慢速模式, -
JEELIZFACEFILTER.set_animateDelay(<integer> delay)
:更改animateDelay
(见init()
参数), -
JEELIZFACEFILTER.set_inputTexture(<WebGLTexture> tex, <integer> width, <integer> height)
:通过一个WebGL纹理实例更改视频输入。需提供纹理的像素维度, -
JEELIZFACEFILTER.reset_inputTexture()
:恢复使用用户的视频作为输入纹理, -
JEELIZFACEFILTER.get_videoDevices(<function> callback)
:应在init
方法之前调用。回调函数提供2个参数:<array> mediaDevices
:包含找到的所有设备的数组。每个设备是一个具有deviceId
字符串属性的JavaScript对象。此值可提供给init
方法使用特定相机。如果发生错误,此值设置为false
,<string> errorLabel
:如果发生错误,则错误的标签。可能为:NOTSUPPORTED
,NODEVICESFOUND
或PROMISEREJECTED
。
-
JEELIZFACEFILTER.set_scanSettings(<object> scanSettings)
:覆盖扫描设置。scanSettings
是具有以下属性的字典:<float> scale0Factor
:在最大缩放级别情况下搜索窗口的相对宽度(1
→全宽)。默认值为0.8
,<int> nScaleLevels
:缩放级别的数量。默认值为3
,[<float>, <float>, <float>] overlapFactors
:X轴,Y轴和缩放轴两个搜索窗口位置之间的相对重叠。更高的值使得扫描更快,但可能会遗漏某些位置。设置为[1, 1, 1]
表示没有重叠。默认值为[2, 2, 3]
,<int> nDetectsPerLoop
:指定每次绘图循环中的检测次数。-1
表示自适应值。默认值:-1
,<boolean> enableAsyncReadPixels
:启用异步GPU读取。默认值为false
。这将释放大量CPU资源,但可能在某些设备上增加延迟。
-
JEELIZFACEFILTER.set_stabilizationSettings(<object> stabilizationSettings)
:覆盖检测稳定设置。神经网络的输出总是伴有噪声,因此我们需要使用浮动平均值来稳定它以避免抖动伪影。内部算法首先计算介于0
和1
之间的稳定因子k
。如果k==0.0
,检测效果较差,我们更注重响应能力而不是稳定性。这种情况出现在用户快速移动、旋转头部或检测效果较差时。相反,如果k
靠近1
,检测效果良好,用户移动不多,我们可以进行大量稳定。stabilizationSettings
是一个具有以下属性的字典:[<float> minValue, <float> maxValue] translationFactorRange
:根据头部的平移速度(相对于视口)以因子kTranslation
乘以k
。如果translationSpeed<minValue
,则kTranslation=0
;如果translationSpeed>maxValue
,则kTranslation=1
。回归是线性的。默认值:[0.002, 0.005]
,[<float> minValue, <float> maxValue] rotationFactorRange
:类似于translationFactorRange
,但针对旋转速度。默认值:[0.015, 0.1]
,[<float> minValue, <float> maxValue] qualityFactorRange
:类似于translationFactorRange
,但针对头部检测系数。默认值:[0.9, 0.98]
,[<float> minValue, <float> maxValue] alphaRange
:它指定如何应用k
。在两次连续检测之间,我们使用混合因子alpha
混合先前的detectState
值和当前检测值。如果k<0.0
,则alpha=<minValue>
;如果k>1.0
,则alpha=<maxValue>
。在这两个值之间的变化是二次的。默认值:[0.05, 1.0]
。
-
JEELIZFACEFILTER.update_videoElement(<video> vid, <function|False> callback)
:通过另一个视频元素更改用于面部检测的视频元素(可以通过VIDEOSETTINGS.videoElement
提供)。完成后可以调用回调函数, -
JEELIZFACEFILTER.update_videoSettings(<object> videoSettings)
:动态更改视频设置(参见 Optional init arguments 了解videoSettings
的属性)。它用于将摄像头从自拍(用户)更改为后置(环境)摄像头。返回一个Promise
, -
JEELIZFACEFILTER.set_videoOrientation(<integer> angle, <boolean> flipX)
:动态更改videoSettings.rotate
和videoSettings.flipX
。此方法应在初始化后调用。默认值为0
和false
。角度应在以下值中选择:0, 90, 180, -90
。 -
JEELIZFACEFILTER.destroy()
:清理图形内存和JavaScript内存,卸载库。之后需要重新初始化库。返回一个Promise
, -
JEELIZFACEFILTER.reset_GLState()
:重置 WebGL 上下文, -
JEELIZFACEFILTER.render_video()
:在<canvas>
元素上渲染视频。
优化
1个还是2个画布?
您可以:
- 使用1个
<canvas>
和一个由facefilter和THREE.js(或其他3D引擎)共享的WebGL上下文, - 使用2个单独的
<canvas>
元素,通过CSS对齐,一个用于AR,另一个用于显示视频并运行此库。
第一种通常更高效,但THREE.js的最新版不适合共享WebGL上下文,可能会发生一些奇怪的错误。因此我们强烈建议使用2个单独的画布。
画布和视频分辨率
我们强烈推荐使用 JeelizResizer
帮助器来调整画布到显示尺寸,以避免计算不必要的像素。这款助手也为找到最优视频分辨率提供帮助,这个分辨率尽可能接近实际画布尺寸。如果相机分辨率过高而与画布分辨率不一致,您的应用将因为每个视频帧刷新WebGL纹理的成本过高而变慢。而如果视频分辨率过低相对于画布分辨率,图像将会模糊。可以查看THREE.js模板以了解如何使用它。要使用这个助手,您首先需要在HTML代码中包括它:
<script src="https://appstatic.jeeliz.com/faceFilter/JeelizResizer.js"></script>
然后在主脚本中,在初始化Jeeliz FaceFilter之前,您应该调用它以调整画布到最佳分辨率并找到最佳视频分辨率:
JeelizResizer.size_canvas({
canvasId: 'jeeFaceFilterCanvas',
callback: function(isError, bestVideoSettings){
JEELIZFACEFILTER.init({
videoSettings: bestVideoSettings,
// ...
// ...
});
}
});
详情可查看此助手的源代码(在 helpers/JeelizResize.js )以获取更多信息。
杂项
一些提示:
- 在优化方面,基于WebGL的演示比Canvas2D演示更为优化,而Canvas2D演示又比CSS3D演示更优化。
- 尽量使用较轻的资源。每个纹理图像应具有最低的分辨率,使用mipmap进行纹理最小化过滤。
- 使用的效果越多,速度就越慢。逐渐添加3D效果,以检查其是否对帧率影响过大。
- 使用低多边形网格。
多面部
可以同时检测和跟踪多个面部。启用该功能,只需指定可选的初始化参数 maxFacesDetected
。其最大值为 8
。事实上,如果您正在同时跟踪例如 8
个面部,由于对每一个跟踪面部的计算能力减少了 8
倍,检测会变得更慢。如果您设置这个值为 8
,但只检测到 1
个面部,相较于单个面部跟踪其减速不会太多。
如果启用了多面部跟踪,callbackTrack
函数将携带一个检测状态数组(而不是一个简单的检测状态)被调用。检测状态格式依旧相同。
您可以使用我们的 Three.js
多面部检测助手,helpers/JeelizThreeHelper.js
来入门并测试这个示例。主脚本 仅有60行代码!
多视频
要创建一个新的 JEELIZFACEFILTER
实例,您需要调用:
const JEELIZFACEFILTER2 = JEELIZFACEFILTER.create_new();
(注意):
- 每个实例使用一个新的WebGL上下文。根据配置,WebGL上下文的数量是有限的。我们建议不要同时使用超过16个上下文,
- 计算能力将在上下文之间共享。使用多个实例可能会增加延迟。 请查看这个演示,以了解它的工作原理:源码,在线演示
更换3D引擎
可以使用除了BABYLON.JS或THREE.JS的其他3D引擎。如果你完成了这项工作,我们希望将你的演示添加到此存储库中(或链接到你的代码)。只需打开一个拉取请求。
3D引擎可以与FaceFilter共享WebGL上下文和画布,或者使用覆盖在FaceFilter画布上的第二个画布(FaceFilter画布仅用于渲染视频)。在第一种情况下,WebGL上下文由Jeeliz Face Filter创建。即使第一种方法可能更优化,我们还是强烈推荐第二种方法。
更换神经网络
自2018年7月起可以更换神经网络。调用JEELIZFACEFILTER.init({...})
的时候,通过NNCPath: <NN_DEFAULT.json的路径>
设置NNCPath值为特定的神经网络文件:
JEELIZFACEFILTER.init({
NNCPath: '../../neuralNets/NN_LIGHT_1.json'
// ...
})
也可以直接使用NNC
属性而不是NNCPath
来提供神经网络模型的JSON文件内容。
我们提供几种神经网络模型:
neuralNets/NN_DEFAULT.json
:这是默认的神经网络,尺寸和性能之间有很好的折中,neuralNets/NN_WIDEANGLES_<X>.json
:这个神经网络更适合检测宽头角(但对于小角度不太准确),neuralNets/NN_LIGHT_<X>.json
:这是神经网络的轻量版本。文件大小减半,运行速度更快但对于大头部旋转角度准确性较低,neuralNets/NNC_VERYLIGHT_<X>.json
:比前一个版本更轻:250Kbytes,非常快。但对所有光照条件不太准确和稳健,neuralNets/NN_VIEWTOP_<X>.json
:这个神经网络非常适用于相机俯视的场景(例如用于自助终端的设置),neuralNets/NN_INTEL1536.json
:适用于Intel 1536 Iris GPU的神经网络(有一个图形驱动程序错误,见#85),neuralNets/NN_4EXPR_<X>.json
:这个神经网络还检测4种面部表情(嘴巴张开,微笑,皱眉,扬眉)。
使用模块
/dist/jeelizFaceFilter.module.js
与/dist/jeelizFaceFilter.js
完全相同,只是它作为JavaScript模块工作,因此可以直接使用以下方式导入:
import 'dist/jeelizFaceFilter.module.js'
或使用require
(参见问题#72):
const faceFilter = require('./lib/jeelizFaceFilter.module.js').JEELIZFACEFILTER;
faceFilter.init({
// 你也可以直接提供画布
// 使用canvas属性代替canvasId:
canvasId: 'jeeFaceFilterCanvas',
NNCPath: '../../../neuralNets/', // JSON神经网络模型的路径(默认是NN_DEFAULT.json)
callbackReady: function(errCode, spec){
if (errCode){
console.log('发生错误。错误代码=', errCode);
return;
}
// [使用spec初始化场景...]
console.log('信息:JEELIZFACEFILTER已准备好');
}, //结束callbackReady()
// 在每次渲染迭代(绘图循环)时调用
callbackTrack: function(detectState){
// 在此渲染你的场景
// [...处理detectState]
} //结束callbackTrack()
});
集成
使用打包工具
如果你使用打包工具(通常是Webpack或Parcel)来使用此库,首先应使用模块版本。
然后,使用标准库时,我们使用AJAX加载指定的神经网络模型(通过NNCPath
初始化参数提供),原因如下:
- 如果用户不接受共享其摄像头,或如果WebGL未启用,我们不需要加载神经网络模型,
- 我们假定库是通过静态HTTPS服务器部署的。
使用打包工具时,会有点复杂。使用经典的import
或require
调用来加载神经网络模型,并使用NNC
初始化参数来提供它会更容易:
const faceFilter = require('./lib/jeelizFaceFilter.module.js').JEELIZFACEFILTER
const neuralNetworkModel = require('./neuralNets/NN_DEFAULT.json')
faceFilter.init({
NNC: neuralNetworkModel, // 代替NNCPath
// ... 其他初始化参数
});
如果你有兴趣在NPM / ES6 / Webpack环境中使用这个库,可以查看@jackbilestech做的出色工作,jackbilestech/jeelizFaceFilter。
使用JavaScript前端框架
使用REACT和THREE Fiber
自2020年10月起,REACT/THREE Fiber/Webpack boilerplate在路径/reactThreeFiberDemo中可用。
另见
我们在此不正式涵盖与主流JavaScript前端框架(React,Vue,Angular)的集成。 欢迎提交Pull Request来添加针对特定框架的样板或演示。以下是一些关于React集成的提交问题:
你还可以查看这些Github代码仓库:
- ikebastuz/jeelizTest:基于Create React App的CSS3D FaceFilter的React演示
- CloffWrangler/facevoice:基于Create React App的另一个演示
- nickydev100/FFMpeg-Angular-Face-Filter:Angular样板
原生集成
可以通过Webview在一个原生应用中执行使用该库的JavaScript应用。
对于IOS,在IOS14.3之前的WKWebview
组件中禁用了相机访问。如果你想让你的应用程序在运行IOS <= 14.2的设备上运行,你必须实现一个黑客方法,通过websockets将相机视频流传输到webview中。
这个黑客方法没有在此存储库实现,但在另一个类似的Jeeliz库Jeeliz Weboji中实现了。这里是链接:
但这仍然是一个引入瓶颈的脏黑客。在高端设备上运行效果还是不错的(在Iphone XR上测试)。但最好坚持使用完全的web环境。
还有这个Github问题,详细介绍了如何嵌入库到Webview
组件,适用于React native。仅适用于Android:
Unity
自2023年9月起,Marks开发了一个Unity插件,用于使用Unity创建Face滤镜并将其导出到web上。你可以在Unity Asset Store上购买:增强现实WebGL - 面部跟踪虚拟试戴
托管
这个库需要通过MediaStream API
获取用户的摄像头视频。因此你的应用程序应该由HTTPS服务器托管(即使是自签名证书)。在某些Web浏览器中,它不会在不安全的HTTP下工作,即使是本地的。
开发服务器
出于开发目的,我们提供了一个简单的HTTPS服务器,用于检查演示或开发你自己的滤镜。要启动它,在bash控制台中执行:
使用Python2
python2 httpsServer.py
它需要Python 2.X。然后在你的Web浏览器中打开https://localhost:4443。
使用Node
npm install
npm run dev
转到https://127.0.0.1:8000/demos/threejs/cube/index.html
当你打开浏览器时会显示"不安全"。转到高级选项。点击继续。
托管优化
你可以使用我们托管并更新的库版本,网址是:
https://appstatic.jeeliz.com/faceFilter/jeelizFaceFilter.js
它使用与库路径相同路径下托管的神经网络NN_DEFAULT.json
。在这些演示中使用的助手(所有脚本在/helpers/中)也托管在https://appstatic.jeeliz.com/faceFilter/
。
它通过内容递送网络(CDN)使用gzip压缩提供服务。
如果你自己托管脚本,注意启用JSON和JS文件的gzip HTTP/HTTPS压缩。确实,神经网络JSON文件neuralNets/NN_DEFAULT.json
有点重,但用GZIP压缩效果很好。你可以在这里检查你的服务器的gzip压缩。
神经网络文件neuralNets/NN_DEFAULT.json
在调用JEEFACEFILTER.init()
后通过ajax的XMLHttpRequest
加载。在用户同意共享其摄像头之后加载这个文件。所以如果用户拒绝共享,或者没有可用的相机,我们不会加载这个文件。如果你通过服务工作者或简单的原始XMLHttpRequest
在HTML页面加载后系统预加载neuralNets/NN_DEFAULT.json
,加载速度会更快。然后当Jeeliz Facefilter请求它时,文件将已经在浏览器缓存中。
关于技术
引擎内部
此库依赖于Jeeliz WebGL深度学习技术,通过神经网络检测和跟踪用户的面部。精度是自适应的:硬件越好,处理的检测次数越多。所有操作都在客户端完成。
兼容性
- 如果
WebGL2
可用,则使用WebGL2
且不需要特定的扩展, - 如果
WebGL2
不可用但WebGL1
可用,我们需要OES_TEXTURE_FLOAT
扩展或OES_TEXTURE_HALF_FLOAT
扩展, - 如果
WebGL2
不可用,且WebGL1
不可用或OES_TEXTURE_FLOAT
或OES_HALF_TEXTURE_FLOAT
都未实现,则用户不兼容。
如果发生兼容性错误,请在此存储库上发布问题。如果是摄像头访问问题,请在关闭所有可能使用摄像头的应用程序(Skype,Messenger,其他浏览器标签和窗口,...)后重试。请包括:
- 浏览器、浏览器版本、操作系统、操作系统版本、设备型号以及如果是台式机的GPU,
- webglreport.com - WebGL1的屏幕截图(关于你的
WebGL1
实现), - webglreport.com - WebGL2的屏幕截图(关于你的
WebGL2
实现), - 从Web控制台的日志,
- 重现错误的步骤和截图。
文章和教程
你使用这个库写了一个教程吗?提交一个拉取请求或发送链接给我们,我们很高兴添加它。
英文
-
构建一个多面部滤镜:在WebGL Academy上托管的交互式分步教程,你将学习使用THREE.js和此库构建自由女神像
-
视频教程由 Chris Godber 制作: Three JS 头部跟踪控制
-
在Medium上的教程, 作者 Patricia Arnedo: 使用React构建AR绘图应用
-
2021年使用React和ThreeJS / React Three Fiber开发Web AR面部滤镜的教程 出色的教程由Level 30 Wizards 创意数字工作室制作,学习如何创建魔法师帽子面部滤镜。现场演示请点击这里
法语版
- 教程: 开发Matrix主题的网络摄像头面部滤镜在developpez.com上:Développer un filtre facial webcam thème Matrix
日语版
- 在Qiita.com上关于库的总体评审和解释: jeelizFaceFilterを試してみた
许可证
Apache 2.0。此应用程序可免费用于商业和非商业用途。