热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用TensorFlow.js在网页浏览器中实现高效的人脸识别JavaScript接口

作者|VincentMühle编译|姗姗出品|人工智能头条(公众号ID:AI_Thinker)【导读】随着深度学习方法的应用,浏览器调用人脸识别技术已经得到了更广泛的应用与提升。在

作者 | Vincent Mühle

编译 | 姗姗

出品 | 人工智能头条(公众号ID:AI_Thinker)


【导读】随着深度学习方法的应用,浏览器调用人脸识别技术已经得到了更广泛的应用与提升。在实际过程中也具有其特有的优势,通过集成与人脸检测与识别相关的API,通过更为简单的coding就可以实现。今天将为大家介绍一个用于人脸检测、人脸识别和人脸特征检测的 Javascript API,通过在浏览器中利用 tensorflow.js 进行人脸检测和人脸识别。大家不仅可以更快速学习这个,对有人脸识别技术需求的 JS 开发者来说更是一件值得开心的事。


前言


对于 JS 开发者来说这将是一件很开心的事,那就是终于可以在浏览器中进行人脸识别了!通过接下来的这篇文章,将为大家介绍  face-api.js,一个构建在 tensorflow.js core 上的 Javascript 模块,实现了人脸检测、人脸识别和人脸特征检测三种 CNNs (卷积神经网络)。


我们将通过研究一个简单的代码示例,只用几行代码就可以试着使用这个包。


第一个人脸识别包 face-recognition.js,现在又来了一个包?


如果读过我的另一篇关于人脸识别的文章 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 几乎相同的结果,但,是在浏览器中实现的!而最棒的一点是,它不需要设置任何外部依赖关系,就可以直接使用。还有一个意外的奖励 —— 在 WebGL 上运行操作 ,GPU 的加速。


这足以让我相信,Javascript 社区需要这样一个包!这也将留给你们足够的想象空间,你们可以用它来构建各种各样的应用。


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


如果你是希望尽快开始,你可以跳过这一部分,直接跳到编码中。但是为了更好地理解 face-api.js 使用的方法。要实现人脸识别,强烈建议参与一起学习,因为我经常会被问到这个问题。


简单来说,我们实际上想要实现的是,识别给出的一个人的面部图像,用作输入图像(input image)。


我们的方法是,给出想识别的那个人的一张或多张图片,并给此人的名字打上标签,用作参考数据(reference data)。现在将输入图片与引用数据进行对比并找出最相似的参考图片。如果两个图像足够相似,我们将会输出此人的名字,否则我们输出结果为 “unknow”。


听起来不错吧!然而这其中还存在两个问题。首先,如果一张照片中有多人并且我们想把所有人都识别出来该怎么办?其次,我们需要能够计算出两张人脸图像的相似度度量,以便比较它们。


人脸检测


对于第一个问题的答案是通过人脸检测来解决。简单地说,我们首先定位输入图像中的所有面孔。人脸检测,face-api.js 实现了一个 SSD 算法,它基本上是基于 MobileNetV1 的 CNN,在网络的顶部有一些额外的盒预测层。


网络返回每张面孔的边界框与相应的分数,即显示面孔的每个边界框的概率。这些分数用于筛选边界区域,因为图像中可能根本不包含任何面孔。注意,即使只有一个人要检索边界框,人脸检测也应该执行。

 

在浏览器中使用tensorflow.js进行人脸识别的Javascript API


人脸特征检测和人脸对齐


第一个问题解决了!但是,我们想要对齐边界框,这样我们就可以在传递给人脸识别网络之前,在每个区域的人脸中心提取出图像,这将使人脸识别更加准确!


为此 face-api.js 实现了一个简单的 CNN 网络,此网络返回给定人脸图像的 68 个点的面部特征。


在浏览器中使用tensorflow.js进行人脸识别的Javascript API


根据特征点的位置,边界区域可以集中在面部中心。在下图中你可以看到人脸检测的结果(左)与对齐的人脸图像(右)


在浏览器中使用tensorflow.js进行人脸识别的Javascript API


人脸识别


现在我们可以将提取和对齐的人脸图像输入到人脸识别网络中,该网络是基于类似 ResNet-34 的架构,基本上对应于 dlib 中实现的架构。该网络已经被训练学习将人脸的特征映射到人脸描述符(一个有128个值的矢量)中,通常也被称为人脸嵌入。


现在回到比较两个人脸时的原始问题:我们将使用提取的每张人脸图像的描述符,并将它们与参考数据的人脸描述符进行比较。更准确地说,我们可以计算两张人脸描述符之间的欧式距离,根据阈值判断两个人脸是否相似(对于 150×150 幅人脸图像,0.6 是一个很好的阈值)。使用欧几里得距离方法非常有效,当然你也可以选择任意类型的分类器。下面的 gif 图像例子就是通过欧几里得距离来比较的两张人脸图像:


在浏览器中使用tensorflow.js进行人脸识别的Javascript API


在学过了人脸识别的理论之后,我们开始 coding  ~~


编码


在这个简短的示例中,我们将逐步看到如何在下面这张多人的输入图像上进行人脸识别:


在浏览器中使用tensorflow.js进行人脸识别的Javascript API


脚本


首先,从 dist / face - api .js上或者 dist/face-ap.min.js 的minifed版本中获取  latest build  ,包括脚本:



<script src="face-api.js">script>

如果用 npm :


npm i face-api.js


加载模型数据


根据你的应用需求,可以专门加载需要的模型,但是要运行一个完整的端到端示例,我们需要加载人脸检测、人脸特征检测和人脸识别这三个模型。模型文件在 repo 上可用,可在此找到。


链接:

https://github.com/justadudewhohacks/faceapi.js/tree/master/weights


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


模型文件可以作为静态资源来提供在给 web 应用程序,也可以在其他地方托管它们,通过指定文件的路径或 url 来加载它们。假设在 public/models 下一个模型目录中提供它们。




const MODEL_URL = '/models'await faceapi.loadModels(MODEL_URL)

如果你只想加载特殊模块:


const MODEL_URL = '/models'

await faceapi.loadFaceDetectionModel(MODEL_URL)
await faceapi.loadFaceLandmarkModel(MODEL_URL)
await faceapi.loadFaceRecognitionModel(MODEL_URL)


从输入图像接收所有面孔的完整描述


神经网络接受 HTML 图像、画布或视频元素作为输入。简单地说,要检测输入的人脸的边界,只需使 Score > minScore




const minConfidence = 0.8const fullFaceDescriptions = await faceapi.allFaces(input, minConfidence)

完整的脸部描述包含检测结果(边界框+分数)、脸部特征和计算描述符。faceapi.js 做了之前讨论所有的问题。也可以手动获取人脸位置和特征。github repo上有这样的示例。

注意,边界和特征与原始图像/媒体大小相关。如果显示的图像大小与原始图像大小不一致,可以调整它们的大小:


const resized = fullFaceDescriptions.map(fd => fd.forSize(width, height))


可以通过画出边界区域来可视化检测结果



fullFaceDescription.forEach((fd, i) => {  faceapi.drawDetection(canvas, fd.detection, { withScore: true })})

在浏览器中使用tensorflow.js进行人脸识别的Javascript API

人间特征按照下面的方法显示出来


fullFaceDescription.forEach((fd, i) => {
  faceapi.drawLandmarks(canvas, fd.landmarks, { drawLines: true })
})


在浏览器中使用tensorflow.js进行人脸识别的Javascript API


人脸识别


知道了如何在输入图像中检索所有人脸的位置和描述符,我们将得到一些分别显示一个人的图像,并计算人脸描述符。这些描述符就是我们的参考数据。


假设我们有一些示例图像,我们首先用 url 获取图像。


然后使用 faceapi.bufferToImage 从数据缓存区中创建 HTML 图像元素:




// fetch images from url as blobsconst blobs = await Promise.all(  ['sheldon.png' 'raj.png''leonard.png''howard.png'].map(    uri => (await fetch(uri)).blob()  ))// convert blobs (buffers) to HTMLImage elementsconst images = await Promise.all(blobs.map(  blob => await faceapi.bufferToImage(blob)))

接下来,对于每个图像,定位被试的脸并计算面部描述符,就像之前对输入图像所做的处理那样:


const refDescriptions = await Promsie.all(images.map(
  img => (await faceapi.allFaces(img))[0]
))

const refDescriptors = refDescriptions.map(fd => fd.descriptor)


现在,剩下要做的就是循环遍历输入图像的人脸描述,找到与参考数据欧式距离最小的描述符:



const sortAsc = (a, b) => a - bconst labels = ['sheldon''raj''leonard''howard']const results = fullFaceDescription.map((fd, i) => {  const bestMatch = refDescriptors.map(    refDesc => ({      label: labels[i],      distance: faceapi.euclideanDistance(fd.descriptor, refDesc)    })  ).sort(sortAsc)[0]  return {    detection: fd.detection,    label: bestMatch.label,    distance: bestMatch.distance  }})

正如前面讲到的,在这里用效果很好的欧氏距离作为相似度度量。最终得到了在输入图像中每个人的最佳匹配。

最后可以将边界框和它们的标签一起画出来并显示结果:


// 0.6 is a good distance threshold value to judge
// whether the descriptors match or not
const maxDistance = 0.6

results.forEach(result => {
  faceapi.drawDetection(canvas, result.detection, { withScorefalse })

  const text = `${result.distance < maxDistance ? result.className : 'unkown'} (${result.distance})`
  const { x, y, height: boxHeight } = detection.getBox()
  faceapi.drawText(
    canvas.getContext('2d'),
    x,
    y + boxHeight,
    text
  )
})


在浏览器中使用tensorflow.js进行人脸识别的Javascript API


这就是这次的学习之旅!至此希望大家已经学会如何使用这个 api,并且建议大家看一下 repo 中的其他示例。


原文链接


GitHub链接


推荐阅读
  • 中科院学位论文排版指南
    随着毕业季的到来,许多即将毕业的学生开始撰写学位论文。本文介绍了使用LaTeX排版学位论文的方法,特别是针对中国科学院大学研究生学位论文撰写规范指导意见的最新要求。LaTeX以其精确的控制和美观的排版效果成为许多学者的首选。 ... [详细]
  • 云函数与数据库API实现增删查改的对比
    本文将深入探讨使用云函数和数据库API实现数据操作(增删查改)的不同方法,通过详细的代码示例帮助读者更好地理解和掌握这些技术。文章不仅提供代码实现,还解释了每种方法的特点和适用场景。 ... [详细]
  • 本文探讨了图像标签的多种分类场景及其在以图搜图技术中的应用,涵盖了从基础理论到实际项目实施的全面解析。 ... [详细]
  • 在网站制作中随时可用的10个 HTML5 代码片段
    HTML很容易写,但创建网页时,您经常需要重复做同样的任务,如创建表单。在这篇文章中,我收集了10个超有用的HTML代码片段,有HTML5启动模板、空白图片、打电话和发短信、自动完 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 反向投影技术主要用于在大型输入图像中定位特定的小型模板图像。通过直方图对比,它能够识别出最匹配的区域或点,从而确定模板图像在输入图像中的位置。 ... [详细]
  • 本文探讨了Jsonapi-rb与ActiveModelSerializers (AMS)在性能上的差异,并分享了详细的基准测试结果。 ... [详细]
  • 本文介绍了如何使用JavaScript的Fetch API与Express服务器进行交互,涵盖了GET、POST、PUT和DELETE请求的实现,并展示了如何处理JSON响应。 ... [详细]
  • 本文将详细介绍多个流行的 Android 视频处理开源框架,包括 ijkplayer、FFmpeg、Vitamio、ExoPlayer 等。每个框架都有其独特的优势和应用场景,帮助开发者更高效地进行视频处理和播放。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 在Ubuntu 16.04中使用Anaconda安装TensorFlow
    本文详细介绍了如何在Ubuntu 16.04系统上通过Anaconda环境管理工具安装TensorFlow。首先,需要下载并安装Anaconda,然后配置环境变量以确保系统能够识别Anaconda命令。接着,创建一个特定的Python环境用于安装TensorFlow,并通过指定的镜像源加速安装过程。最后,通过一个简单的线性回归示例验证TensorFlow的安装是否成功。 ... [详细]
  • 本文详细介绍了 TensorFlow 的入门实践,特别是使用 MNIST 数据集进行数字识别的项目。文章首先解析了项目文件结构,并解释了各部分的作用,随后逐步讲解了如何通过 TensorFlow 实现基本的神经网络模型。 ... [详细]
  • 本文详细介绍了 org.apache.commons.io.IOCase 类中的 checkCompareTo() 方法,通过多个代码示例展示其在不同场景下的使用方法。 ... [详细]
  • 主板IO用W83627THG,用VC如何取得CPU温度,系统温度,CPU风扇转速,VBat的电压. ... [详细]
  • 解决TensorFlow CPU版本安装中的依赖问题
    本文记录了在安装CPU版本的TensorFlow过程中遇到的依赖问题及解决方案,特别是numpy版本不匹配和动态链接库(DLL)错误。通过详细的步骤说明和专业建议,帮助读者顺利安装并使用TensorFlow。 ... [详细]
author-avatar
捕鱼达人2502868831
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有