手把手教你在浏览器中使用脸部识别软件包 face-api.js

AI 研习社按:本文为雷锋字幕组编译的技术博客,原标题 face-api.js — JavaScript API for Face Recognition in the Browser with tensorflow.js,作者为 Vincent Mühler 。 翻译 | 王飞 赵朋飞 整理 | MY

我可以很激动地说,我们终于有可能在浏览器中运行人脸识别程序了!在这篇文章中,我会给大家介绍一个基于 TensorFlow.js 核心的 JavaScript 模块,这个模块叫做 face-api.js。为了实现人脸检测、人脸识别以及人脸特征点检测的目的,该模块分别实现了三种类型的卷积神经网络。

和往常一样,我们先看一个简单一点的代码实例,用几行的代码以便能够让大家可以直接开始使用这个包。我们开始吧!

第一个 face-recognition.js,那么现在还有其他包吗?

如果你有阅读过我的另外一篇关于 nodejs 进行人脸识别方面的文章:Node.js+face-recognition.js: Simple and Robust Face Recognition using Deep Learning , 你可能会意识到,一段时间以前,我构建过一个相似的包。比方说三个 face-recognition.js,将人脸识别功能引入 nodejs 当中。

起初,我没有想到在 javascript 社区中对脸部识别软件包的需求如此之高。对于很多人来说,face-recognition.js 似乎是一个很不错的免费软件包了,另外也有像微软和亚马逊提供的付费软件包。但是,一直有人问我能否在浏览器中完整地运行整个人脸识别的流程

最后的答案是肯定的,多亏了 tensorflow.js,利用好 tfjs-core, 我成功实现了部分相似的工具,这些小工具能够让你得到和使用 face-recognition.js 几乎相似的运行结果,并且是在浏览器中。而且最棒的一点是你不需要再安装任何依赖项,它可以直接运行。额外的好处是它还支持 GPU 加速,在 WebGL 上运行操作。

这足让我相信 JavaScript 社区需要这样的浏览器软件包!接下来就是发挥你自己的想象力,你可以用这个来构建各种各样的应用程序。:)

如何用深度学习来解决人脸识别的问题

如果你是那种想要尽快开始的人(或妹子),你可以跳过这一部分并直接跳到代码部分。但为了更好地理解 face-api.js 中用于实现人脸识别的方法,我强烈建议你按照步骤来,因为我经常被问到这一部分的问题。

为了简单起见,我们实际想要实现的是给定一个人的脸部图像然后对他/她进行识别,给定的图像即输入图像。我们解决这个问题的方法是为每个我们想要识别的人提供一个(或多个)图像,并用人名称标记,即参考数据。现在我们将输入图像与参考数据进行比较,并找到最相似的参考图像。如果两个图像足够相似,那我们就输出人名,否则我们输出'未知'。

听起来像是个不错的计划!但是这里仍存在两个问题。首先,如果我们有一张显示多个人的图像,并且我们想要识别所有这些图像,那该怎么办呢?其次,我们还需要能够获得度量两张人脸图像的相似性的量,以便进行比较。

人脸检测

第一个问题的答案是人脸检测。简单地说,我们首先找到输入图像中的所有的人脸。对于人脸检测,face-api.js 实现了 SSD(Single Shot Multibox Detector),它基本上是一个基于 MobileNetV1 的 CNN,在网络顶部叠加了一些额外的预测层。

这个网络返回包围每张脸的 bounding box,以及其对应的分数,即每个 boundingbox 中包含人脸的概率。这里的分数用于过滤边界框,因为图像中可能根本不包含人脸。另外要注意的是,即使图像中只有一个人,为了得到 boundingbox,也应该首先进行人脸检测这一步骤。

人脸特征点检测与人脸对齐

第一个问题解决了 但是,我想指出我们接下来要对齐边界框,在将它们传递到面部识别网络之前,为每个框提取以面部为中心的图像,因为这样可以使面部识别更准确!

针对这个目标。face-api.js 已经实现了一个简单的 CNN,这个网络能够返回给定人脸图片的 68 个脸部特征点。

根据特征点的位置,boundingbox 可以被确定在脸部的中心。下面显示的是人脸检测的结果(左)以及人脸对齐后的结果(右)。

人脸识别

现在我们可以将提取和对齐的人脸图像提供给人脸识别网络,该网络基于类似 ResNet-34 的体系结构,基本上与 dlib 中实现的体系结构相对应。该网络已经被训练,能够学习将人脸的特征映射到一个人脸描述器上(具有 128 个值的特征向量),这一过程通常也被称为面部嵌入。

现在回到我们最开始比较两张脸的这个问题上:我们将使用每个提取的面部图像的面部描述符,并将它们与参考数据的面部描述符进行比较。更确切地说,我们可以计算两个面部描述符之间的欧氏距离,并基于阈值判断两个面是否相似(对于 150×150 大小的面部图像来说,0.6 是比较好的阈值)。使用欧几里德距离的效果非常好,但当然你也可以使用你选择的任何类型的分类器。以下 gif 可视化了两张图片通过欧几里德距离进行比较的过程。

现在,让我们消化一下人脸识别的理论,接下来用代码来编写一个例子吧。

编码时间!

在这个简短的例子中,我们将逐步了解如何在以下输入图像中识别多个人脸:

包含脚本

首先,从 dist/face-api.js 获取最新的编译,或者 从 dist/face-api.min.js 获取修订版,并将脚本包含进来:

如果使用 npm:

加载模型数据

根据您的应用程序的需求,您可以专门加载您需要的模型,但是要运行一个完整的端到端示例,我们需要加载人脸检测、 脸部特征点和人脸识别模型。模型文件可以在 repo 或点击这里获取。

模型的权重已经被量化,与原始模型相比,将模型文件的大小减少了 75%,以允许您的客户只加载所需的最少数据。此外,模型权重被分割成最大 4 MB 的块,允许浏览器缓冲这些文件,以便这些文件只被加载一次。

模型文件可以简单的被当做浏览器的静态资源,或者你可以在其他地方托管它们,并可以通过特定的路由或 URL 加载这些文件。假设你将它们和你的其他资源一起放到模型目录下(public/models):

或者,如果你仅仅想加载特定的模型:

从输入图像中获得对所有面孔的完整描述

神经网络接受 HTML 图像、画布、视频或者张量等形式的输入。使用 score > minScore 检测面部边界框,我们简单的说:

完整的面部描述包括检测结果(边界框+分值),脸部特征,以及计算描述符。正如你所看到的,在前面的讨论中 faceapi.allFaces 在后台做了所有的工作。然而,你也可以手动获取脸部位置和特征点。如果你以此为目标的话,可以在 github repo 找到很多例子。

注意,边界框和特征点位置依赖于原始图像/媒体的大小。如果显示的图像大小与原始图像大小不一致,您可以简单地调整大小:

我们可以通过将边界框绘制到画布上来可视化检测结果 :

脸部特征点可以如下方式显示:

通常,我所做的是将一个绝对定位的画布叠加在 img 元素的顶部,它们的宽度和高度是相同的(可以查看 github 上的示例了解更多信息)

面部识别

现在我们知道了如何检索输入图像中所有人脸的位置和描述了,我们将从一些图像中指出每个人脸并计算出人脸的描述符。这些描述符将会是我们的参考数据。

假设我们有一些可用的示例图像,我们首先从一个 url 获取图像,并使用 faceapi.bufferToImage 从数据缓冲区中创建 HTML 图像元素:

接下来,对于每一个图像,我们定位主题并计算面部描述符,就像我们之前对输入图像所做的操作:

现在,我们要做的所有事情都是循环遍历我们输入图像的面部描述,并找到与参考数据距离最小的描述符:

正如前面提到的,我们使用欧氏距离度量相似度,结果证明它是有效的。我们最终得到了在输入图像中检测到的每个面孔的最佳匹配。

最后,我们可以将边界框和它们的标签一起绘制到画布上,以显示结果:

好了!到目前为止,我希望您已经了解了如何使用这个 api。另外,我还建议您看一下 repo 的其他例子。现在尽情享受这个软件包吧!

如果你喜欢这篇文章,欢迎点赞并在 medium 或 twitter 上关注我。也欢迎在 github repository 上评价。请继续关注更多教程!

原文链接:

https://itnext.io/face-api-js-javascript-api-for-face-recognition-in-the-browser-with-tensorflow-js-bcc2a6c4cf07

原文发布于微信公众号 - AI研习社(okweiwu)

原文发表时间:2018-07-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PPV课数据科学社区

R语言中不能进行深度学习?

摘要: R语言现在能也进行深度学习了,而且和python一样好,快来试一试吧。 众所周知,R语言是统计分析最好用的语言。但在Keras和TensorFlow的帮...

45790
来自专栏tiankonguse的专栏

图片上的算法之JPEG压缩

听了JPEG图片的压缩算法,发现蛮有意思的,这里通过JPEG的整体思想、色彩空间转换,缩减取样、DCT变换、量化以及熵编码技术分享一下心得。

60000
来自专栏量子位

如何用sklearn创建机器学习分类器?这里有一份上手指南

原作:Kasper Fredenslund 林鳞 编译自 Data Science Central 量子位 出品 | 公众号 QbitAI 分类器是数据挖掘中对...

360160
来自专栏机器人网

人脸识别,一行代码就能搞定?

什么,只要一行代码就能搞定人脸识别?当然是假的啦。 虽然不能一行就搞定,依靠python强大的人脸识别包,只要十多行代码完全可以实现人脸识别的功能。这就叫站在巨...

38050
来自专栏北京马哥教育

深度学习 + OpenCV,Python实现实时目标检测

使用 OpenCV 和 Python 上对实时视频流进行深度学习目标检测是非常简单的,我们只需要组合一些合适的代码,接入实时视频,随后加入原有的目标检测功能。 ...

1.1K70
来自专栏CreateAMind

运动信息向量的神经网络学习 code、ppt、视频ok

官方代码还未开放, http://visualdynamics.csail.mit.edu/

7920
来自专栏机器之心

资源 | 微软开源MMdnn:实现多个框架之间的模型转换

选自GitHub 作者:Kit CHEN等 机器之心编译 参与:路雪、思源 近日,微软开源 MMdnn,可用于转换、可视化和诊断深度神经网络模型的全面、跨框架解...

38060
来自专栏应兆康的专栏

16. 清理贴错标签的开发集和测试集样本

在错误分析期间,你可能会注意到开发集中的一些样本被错误标记(mislabeled)。当我说”dislabeled”时,我的意思是在模型训练之前,这个样本被错误的...

367100
来自专栏数据派THU

教你用Keras和CNN建立模型识别神奇宝贝!(附代码)

在今天博客的最后,你将会了解如何在你自己的数据库中建立、训练并评估一个卷积神经网络。

69110
来自专栏深度学习那些事儿

浅谈深度学习中超参数调整策略

深度学习中,设计模型以及保证模型的正确性是首要需要考虑的。当模型设置完成时,理论上模型不存在问题,实现效果也通过计算可以复现出来。一切准备就绪后,那么接下来需要...

360110

扫码关注云+社区

领取腾讯云代金券