使用face-api.js轻松将面部识别添加到你的应用程序

英文 | https://medium.com/better-programming/add-facial-recognition-to-your-app-easily-with-face-api-js-58df65921e7

翻译 | web前端开发(web_qdkf)

随着越来越多的复杂工具日渐成熟,图像识别的受欢迎程度继续增长。随着AI和计算机视觉技术的发展(事实上,由于互联网,我们现在可以获得大量数据),现在也可以在浏览器中进行人脸表情识别。

今天,我想向你介绍face-api.js,这是在TensorFlow.js(为JavaScript创建的流行的机器学习库)之上实现的JavaScript人脸识别库。

Face-api非常容易使用。它具有强大的API,该API仅公开必要的配置,隐藏了所有底层,例如实际编写神经网络。除了不同的识别模型外,它还带有预建的绘图功能,因此我们不必弄乱画布。

在本教程中,我将介绍如何使用它来检测图像上的情绪。实际上,只是为了向你展示使用face-api.js来实现它很容易,整个脚本文件大约有20行。因此,让我们开始吧。

设置Face-API

让我们从索引文件开始。我们需要的只是一个我们想要处理的图像。我收集了一些马克的面部表情不同的图片。这将是本教程的测试主题:

除了图像之外,我们还需要包括face-api库。你可以直接从GitHub存储库中获取它,也可以npm i face-api.js在控制台中运行。我还创建了一个app.js文件,在该文件中我们将与库的API进行交互。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Emotion Decetion With face-api.js</title>
        <style>
            body {
                margin: 0;
            }
            canvas {
                position: absolute;
                top: 0;
                left: 0;
            }
</style>
    </head>
    <body>
        <img src="emotions.jpg" alt="" />
        <script src="face-api.min.js"></script>
        <script src="app.js"></script>
    </body>
</html>

我在根目录中有图像,并且还添加了一些次要样式。我们将把检测框绘制到canvas元素上。但是,我们不需要创建canvas标签,因为我们将从脚本中创建标签。通过给它一个绝对位置,它将被放置在图像的顶部。

face-api代替图像支持其他用于人脸识别的媒体元素,例如video或canvas. 有了该设置并准备好之后,我们就可以开始进行脚本的编写了!

加载模型

我们要做的第一件事就是包含将用于识别的模型。创建一个models文件夹,然后从GitHub存储库中的weights文件夹下载模型。

我们不会使用所有这些。你只需要在ssdMobilenetv1,faceLandmark68Net和faceExpressionNet模式及其相应的碎片文件一起。从文件中可以看到,该库还可以猜测年龄和性别。

要从JavaScript加载模型,请在app.js文件中添加以下内容:

(async () => {
    await faceapi.nets.ssdMobilenetv1.loadFromUri('/models');
})();

调用是异步的;因此,我们需要将整个代码包装到异步IIFE中。另外,我们也可以使用诺言,因为我们从中获得了待处理的诺言loadFromUri。如果在节点环境中使用它,则还可以使用loadFromDisk方法直接从磁盘加载它。

侦测人脸

接下来,我们将需要获取图像并将其用于检测和从中创建画布:

(async () => {
    await faceapi.nets.ssdMobilenetv1.loadFromUri('/models');


    const image = document.querySelector('img');
    const canvas = faceapi.createCanvasFromMedia(image);
    const detection = await faceapi.detectAllFaces(image);
})();

Face-api定义了一些用于在canvas元素上进行交互和绘制的函数。createCanvasFromMedia将为canvas我们返回一个元素,可以稍后将其插入dom。

检测人脸也是异步的,因此我们必须再次使用await。如果图像中只有一张脸,则可以调用detectAllFaces或detectSingleFace。 默认情况下,这些方法使用SSD Mobilenet V1面部检测器。 如果要使用其他模型,可以将其作为第二个参数传递给方法,如下所示:

const detection = await faceapi.detectAllFaces(image, new faceapi.TinyFaceDetectorOptions());

绘制检测

为了在画布上绘制检测结果,我们需要定义另外两个变量。由于图像的显示尺寸和原始尺寸可能会有所不同,因此我们需要匹配尺寸。否则,盒子的位置将关闭。

(async () => {
    ...
    const detection = await faceapi.detectAllFaces(image);


    const dimensions = {
        width: image.width,
        height: image.height
    };


    const resizedDimensions = faceapi.resizeResults(detection, dimensions);


    document.body.append(canvas);


    faceapi.draw.drawDetections(canvas, resizedDimensions);
})();

在这里,我们得到了图像的宽度和高度,并把它传递到resizeResults旁边的detection。然后,我们将画布添加到主体并绘制检测框。

如果你100%确定图片的显示尺寸和自然尺寸匹配,则可以省略计算并detection直接传递给drawDetections方法,而不用传递resizedDimensions。

到目前为止,这只是人脸识别,但是我们没有与这些障碍相关的任何情绪。

添加表情和地标检测

要添加更多检测,我们需要再加载两个模型:faceLandmark68Net和faceExpressionNet。

(async () => {
    await faceapi.nets.ssdMobilenetv1.loadFromUri('/models');
    await faceapi.nets.faceLandmark68Net.loadFromUri('/models');
    await faceapi.nets.faceExpressionNet.loadFromUri('/models');


    ...
})();

我们还需要修改我们的价值detection。我们需要告诉face-api,当检测到人脸时,还包括地标和表情:

(async () => {
    ...
    const detection = await faceapi.detectAllFaces(image)
                                    .withFaceLandmarks()
                                    .withFaceExpressions();


    ...
})();

最后,我们可以将它们绘制到画布上。一切就绪后,这就是整个脚本文件:

(async () => {
    await faceapi.nets.ssdMobilenetv1.loadFromUri('/models');
    await faceapi.nets.faceLandmark68Net.loadFromUri('/models');
    await faceapi.nets.faceExpressionNet.loadFromUri('/models');


    const image = document.querySelector('img');
    const canvas = faceapi.createCanvasFromMedia(image);
    const detection = await faceapi.detectAllFaces(image)
                                    .withFaceLandmarks()
                                    .withFaceExpressions();


    const dimensions = {
        width: image.width,
        height: image.height
    };


    const resizedDimensions = faceapi.resizeResults(detection, dimensions);


    document.body.append(canvas);


    faceapi.draw.drawDetections(canvas, resizedDimensions);
    faceapi.draw.drawFaceLandmarks(canvas, resizedDimensions);
    faceapi.draw.drawFaceExpressions(canvas, resizedDimensions);
})();

现在我们知道了Mark内心的真实感受。如果你想按原样获得项目,请访问我为本教程创建的faceapi存储库。现在,你可以开始为自己的机器人添加感官了。祝编码快乐!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章