浏览器里标记生活大爆炸所有演员 — — face-api.js

超神经 HyperAI 导读

忘掉那些不开心的,还是有人在好好做浏览器的啦。

最近,一群工程师基于 tensorflow.js core 框架,开发出一款可以在浏览器上运行的人脸识别 API——face-api.js,不仅能同时还可以识别多张人脸,让更多非专业 AI 工程师,能够低成本使用人脸识别技术。

人脸识别原理

face-api.js 是一个基于 Tensorflow.js core 的 js 框架,通过三种 CNN 来进行人脸识别和人脸特征检测,从而识别图像中的人物。

跟大多数图像识别技术一样,这项技术的实现原理也是通过匹配数据库,找到相似度最高的图像,并输出结果。不过,face-api.js 可以同时识别一张图像中的多张人脸。

一般人脸识别技术的工作原理为:工程师们先把大量标记有人名等信息的图像输入到系统,构建数据训练集,然后将识别对象作为测试集,与训练集中的图像进行比对。

如果两个图像相似度达到阈值,则输出结果,否则输出「unknown」。

face-api.js 的实现原理

首先需要进行人脸检测,即圈出图像中所有的人脸。

face-api.js 通过 SSD 算法(Single Shot Multibox Detector)来进行人脸检测。SSD 算法是一种可以直接检测目标类别,并确定 bounding box(俗称 b box)的多目标检测法,在提高识别精度的同时还能提高识别速度。

可以将 SSD 理解为一个基于 MobileNetV1 的 CNN,并额外添加了边框预测层。系统首先通过 bounding box 圈定面部轮廓,并进行打分,跟人脸越接近的图像分数越高,以此来过滤掉非面部的图像内容。

浏览器里标记生活大爆炸所有演员 — — face-api.js

为保证准确性,输入测试集的图像应以人脸为中心,所以需要对面部进行边框对齐。为此 face-api.js 通过一个简单的 CNN 来找出确定人脸图像的 68 个标志点,为下一步人脸识别做准备。

浏览器里标记生活大爆炸所有演员 — — face-api.js

示例图

通过标志点,系统可以进一步确定人脸图像,下图是人脸对齐前(左)和对齐后(右)的效果图。

浏览器里标记生活大爆炸所有演员 — — face-api.js

人脸对齐效果图

很明显,对齐后,跟人脸无关的东西更少了,这是有利于提高系统识别精度的。

人脸识别的实现

圈定人脸后就要开始进行面部识别了。

该程序会将对齐后的人脸输入到人脸识别深度学习网络中,该网络基于 ResNet-34 体系架构,通过 Dlib 库进行人脸检测。该技术可以将人脸特征映射到一个人脸描述符(具有 128 个值的特征向量)上,这个过程通常被称为人脸嵌入。

之后,程序再将每个图像的人脸描述符,与训练集中的人脸描述符进行相似度比较,并基于阈值判断两个面是否相似(对于 150×150 像素的人脸图像,阈值采用 0.6 较为合适)。

可采用欧式距离(即欧几里得度量)进行相似度度量,效果非常好,实际效果可观察下面这张 gif 图。

浏览器里标记生活大爆炸所有演员 — — face-api.js

Talk is cheap , show me the code !

介绍完理论知识后,就该给大家演练一下实操过程了,以下图作为输入图像。

浏览器里标记生活大爆炸所有演员 — — face-api.js

第一步:获取脚本

可以从 dist /face-api.js 上获取最新脚本:

浏览器里标记生活大爆炸所有演员 — — face-api.js

也可以通过 NPM 获取:

浏览器里标记生活大爆炸所有演员 — — face-api.js

第二步:加载数据模型

模型文件可以作为 Web 应用程序的静态资源,也可以挂载到其他位置,可以通过指定文件路径或 URL 来加载模型。

假设模型在 public/models 目录下:

浏览器里标记生活大爆炸所有演员 — — face-api.js

如果是加载特定模型,则为:

浏览器里标记生活大爆炸所有演员 — — face-api.js

第三步:获得完整描述

HTML 图像、画布或视频都可以作为网络的输入。下面是获取输入图像,即所有人脸的完整描述:

浏览器里标记生活大爆炸所有演员 — — face-api.js

也可以自主选择人脸位置和特征:

浏览器里标记生活大爆炸所有演员 — — face-api.js

还可以通过 HTML 画布显示边框,使结果可视化:

浏览器里标记生活大爆炸所有演员 — — face-api.js

浏览器里标记生活大爆炸所有演员 — — face-api.js

人脸特征显示如下:

浏览器里标记生活大爆炸所有演员 — — face-api.js

现在我们已经可以计算出输入图像中每张人脸的位置和描述符,这些描述符将作为参考数据。

下一步是获取图像的 URL,并使用 faceapi.bufferToImage 创建 HTML 图像元素:

浏览器里标记生活大爆炸所有演员 — — face-api.js

对每个图像确定人脸位置并计算描述符:

浏览器里标记生活大爆炸所有演员 — — face-api.js

然后遍历输入图像的人脸描述符,找到参考数据中最相似的描述符:

浏览器里标记生活大爆炸所有演员 — — face-api.js

通过欧几里得度量,获得输入图像中每个人脸的最佳匹配结果,并在 HTML 画布中显示边框及其标签:

浏览器里标记生活大爆炸所有演员 — — face-api.js

浏览器里标记生活大爆炸所有演员 — — face-api.js

这就是 face-api.js 的人脸识别全过程,是不是非常简单呢?感兴趣的朋友可以去试试,欢迎把你的实验结果和心得体会发给我们。