您目前的位置:主页 > www.800849.com >   正文

如何用 200 行 JavaScript 代码实现人脸检测?

来源:本站原创发表时间:2019-08-13

  在超市、地铁、车站等很多场景中,人脸识别已经被广泛应用,但是这个功能究竟是怎么实现的?

  在本文中,将以 pico.js 库为例,分享实现轻量级人脸识别功能的具体开发过程 。

  pico.js 是一个只有 200 行纯 Java 代码的人脸检测库,具备实时检测功能(在实际环境中可达到200+ FPS),压缩后仅 2kB 。

  本文将介绍pico.js,这一由Java编写的用于人脸检测的代码库,并展示其工作原理。尽管现已有类似的项目,但我们的目标是提供更小、计算效率更高的替代方案。

  在深入考究其细节前,建议各位用计算机的网络摄像头体验一下人脸检测的实时演示(也适用于移动设备)。注意,香港新版跑狗,所有进程都是在客户端完成的,即不向服务端发送图像。因此,各位无需担心在运行这段代码时的隐私问题。

  2013年,Markus团队在一个技术报告中介绍了这一由Java实现的pico.js代码库。它是参考C语言实现的,我们可在GitHub上获取其源码:。我们密切关注其实现方法,因为我们不打算复制学习过程,而仅关注它的运行。这背后的原因是,我们最好学习带有官方代码的检测器,将其加载到Java中并执行进程,如此就带有独特的优势(比如跨操作系统与设备的强大的可移植性)。

  Viola-Jones方法是基于区域分类的概念。这意味着在图像的每个合理位置和尺度上都使用分类器。这个区域枚举过程的可视化如下图所示:

  该分类器试图判断当前区域是否存在人脸。最后,获取到的人脸区域将根据重叠程度进行聚类。鉴于每张图像都有很多区域,在这实时进程中有两个小技巧:

  分类级联由一系列分类器组成。这些分类器中的每一个都能正确识别几乎所有的人脸,并丢弃一小部分非人脸区域。如果一个图像区域通过了级联的所有成员,那么它就被认定为人脸。通过(设计)序列中靠前的分类器比靠后的分类器更简单,这种效果得到了进一步放大。级联分类算法如下图所示:

  每个阶段包括一个分类器Cn,它既可以拒绝图像区域(R),也可以接受图像区域(A)。一旦被拒绝,该区域将不会进入下一级联成员。如果没有一个分类器拒绝该区域,我们认为它是一张人脸。

  在Viola-Jones框架中,每个分类器Cn都基于Haar-like特性。这使得每个区域可通过名为积分图像的预算结构来进行O(1)计算时间。

  然而,积分图像也有一些缺点。最明显的缺点是,这种数据结构需要额外的内存来储存:通常是unit8输入图像的4倍。另外一个问题是构建一个完整的图像所需的时间(也与输入的像素数有关)。在功能有限的小型硬件上处理大的图像也可能会有问题。这种方法的一个更微妙的问题是它的优雅性:随之而来的问题是我们是否能够创建一个不需要这种结构、并且具有所有重要属性的框架。

  Pico框架对每个分类器Cn用像素对比测试取代了Haar-like特性,形式如下:

  其中R是一个图像区域,(Xi,Yi)表示用于比较像素值的位置。注意,这种测试可以应用于各种尺寸的区域,而不需要任何专门的数据结构,这与Haar-like的特性不同。这是通过将位置(Xi,Yi)存储在标准化坐标中(例如,(Xi,Yi)在[−1,1]×[−1,1]中),并乘以当前区域的比例。这就是pico实现多尺度检测功能的思路。

  由于此类测试很简单,又因混叠和噪声而存在潜在问题,我们有必要将大量测试应用于该区域,以便对其内容进行推理。在pico框架中,这是通过

  其中Tt(R)表示决策树Tt在输入区域R上生成的标量输出。由于每个决策树都由若干个像素比较测试组成,这些测试可以根据需要调整大小,因此运行分类阶段Cn的计算复杂度与区域大小无关。

  每个Cn决策树都是AdaBoost的变体。接下来以这种方式将阈值设置为Cn的输出,以获取期望的线)。所有得分低于这个阈值的区域都不认为是人脸。添加级联的新成员,直到达到预期的假阳率。请参阅原出版物学习相关细节内容。

  正如简介中说的那样,我们不会复制pico的学习过程,而仅关注它的运行。如果您想学习自定义对象/人脸检测器,请使用官方的实现方法。Pico.js能够加载二进制级联文件并有效地处理图像。接下来的小节将解释如何使用pico.js来检测图像中的人脸。

  通过 src=pico.js/(或它的压缩版本) 引入并进行一些预处理后,就可以使用这些工具了。我们将讨论对图像进行人脸检测的JS代码(GitHub repo中的代码)。但愿这能详尽说明使用该库的方法。实时演示也有说明。

  区域分类器应识别图像区域是否为人脸。其思路是在整个图像中运行这个分类器,以获得其中的所有面孔(稍后详细介绍)。Pico.js的区域分类过程封装在一个函数中,其原型如下:

  前三个参数(r、c和s)指定区域的位置(其中心的行和列)及其大小。pixels阵列包含图像的灰度强度值。参数ldim规定从图像的一行移动到下一行的方式(在诸如OpenCV的库中称为stride)。也就是说,从代码中可以看出(r,c)位置的像素强度为[r*ldim + c]像素。该函数会返回一个浮点值,表示该区域的得分。香港马报资料一肖中特油机轰鸣由本周考核冠军。如果分数大于或等于0.0,则该区域认定为人脸。如果分数低于0.0,则该区域认定为非人脸,即属于背景类。

  Pico.js中pico.unpack_cascade过程将二进制的级联作为参数,将其解压并返回一个带有分类过程和分类器数据的闭包函数。我们用它初始化区域分类过程,以下是详细说明。

  官方pico的人脸检测级联称为facefinder。它由近450个决策树组成,每个决策树的深度为6,它们集成一个25级联。该级联将在我们是实验中用到,它能对正脸图像以适当的检测速率进行实时处理,正如实时演示看到的那样。

  facefinder级联可以直接从官方的github库上下载,代码写为:

  将facefinder_classify_region函数应用于图像中每个区域的合理位置和等级以便检测到所有的人脸。这个过程将在下一小节中解释。

  假定HTML body内有一个canvas元素,一个image标签和一个带有onclick回调的button标签。用户一旦点击了人脸检测按钮,检测过程就开始了。

  下面的JS代码用于绘制内容和图像,并获取原始像素值(红、绿、蓝+ alpha的格式):

  注意,人脸的最小尺寸默认设置为20。这太小了,对于大部分应用程序来说都是不必要的。但还需要注意的是,运行速度在很大程度上取决于此参数。对于实时应用程序,应该将此值设置为100。但是,设置的最小尺寸需匹配示例图像。

  检测过程完成后,数组dets包含表单(r,c,s,q),其中r,c,s指定人脸区域的位置(行,列)和大小,q表示检测分数。该地区得分越高,越有可能是人脸。

  我们需要根据经验设置变量qthresh(5.0刚好,适用于facefinder级联和静止图像中的人脸检测)。典型的检测结果是这样的:

  非极大值抑制聚类的目的是将重叠的人脸区域融合在一起。每个集群的代表是其中得分最高的一次检测(该方法因此而得名)。它的分数更新为集群中所有检测分数的总和。

  我们已经学习了使用pico.js检测静止图像中人脸的基本知识。值得注意的是,pico方法不如基于深度学习的现代人脸检测器强大。然而,pico非常快,这使得它成为许多应用程序的首选,比如那些需要实时处理的应用程序。

  由于pico.js产生的检测噪声比较大,我们开发了一种时间记忆模块,在处理实时视频时可减轻少此问题。该方法用于上述实时演示中,显著提高了主观检测质量。

  其思想是将几个连续帧的检测结合起来,以准确判断给定区域是否为人脸。这是通过实例化一个电路缓冲区来实现的,该缓冲区包含从最后一个f帧检测到的信号:

  update_memory闭包封装了电路缓冲区和刷新数据的代码。返回的数组包含来自最后f帧的检测。

  最终的分类阈值qthresh会显著提高,这会减少假阳性的数量,而不会显著影响到真阳率。


Copyright © 2002-2011 DEDECMS. 织梦科技 版权所有 Power by DedeCms

本港开奖直播| 2016年开奖结果| 老字号高手论坛高手榜l| 新版跑狗图彩图玄机图| 管家婆生活幽默解一肖| 惠泽天下万人娱乐区| 香港彩坛至尊数理开彩| 香港中马堂原创图库| 红姐图库红姐统一图库| 大红鹰高手坛|