查看原文
其他

使用 JavaScript,也能在 Web 应用中实现人脸检测功能?!

Jonathan Freeman CSDN 2019-07-25

想要实现一个面部识别的功能究竟该怎么做?在本文中,我们将以 JavaScript 库 pico.js 为依托,手把手教你如何为一款应用添加面部检测功能。

作者 | Jonathan Freeman

译者 | 弯月,责编 | 屠敏

出品 | CSDN(ID:CSDNnews)

以下为译文:

在本文中,我们将使用pico.js添加简单的面部检测。Pico.js是一个很小的JavaScript库,目前它还是一个近似于概念验证的库,还不能用于生产环境,但在我研究过的人脸检测库中,Pico.js的效果最佳。

本文的目标首先是在地图上通过一个红点显示用户的头部位置:

首先,我们创建一个包含pico.js功能的简单React类,然后用它来获取用户脸部的位置:

<ReactPico onFaceFound={(face) => {this.setState({face})}} />

接下来,如果检测到面部,我们就使用其位置信息来渲染组件:

{face && <FaceIndicator x={face.totalX} y={face.totalY} />}

我们在使用pico.js时所面临的第一个难题是,它是JavaScript的研究项目的实现,不一定是遵循现代JavaScript标准的面向生产环境的库。除此之外,你还不能直接使用yarn add picojs。虽然pico.js的入门教程是一个很好的入门级别的对象检测,但这个教程更像是一篇研究论文而不像API文档。但是,其中提供的示例足够代码使用。我花了几个小时将该教程提供的样本代码放入了一个相对简单的React类中。

pico.js需要做的第一件事就是加载级联模型,该模型会进行一个AJAX调用,而这个调用会引入预先训练好的模型的二进制文件。(你也可以使用pico.js来检测其他类型的对象,但你需要使用官方的pico实现来自己训练模型。)我们可以在componentDidMount方法中加载模型。为了清楚起见,我进一步将示例代码抽象为另一个名为loadFaceFinder的方法:

componentDidMount() {
    this.loadFaceFinder();
  }
  loadFaceFinder() {
    const cascadeurl = 'https://raw.githubusercontent.com/nenadmarkus/pico/c2e81f9d23cc11d1a612fd21e4f9de0921a5d0d9/rnt/cascades/facefinder';
    fetch(cascadeurl).then((response) => {
      response.arrayBuffer().then((buffer) => {
        var bytes = new Int8Array(buffer);
        this.setState({
          faceFinder: pico.unpack_cascade(bytes)
        });
        new camvas(this.canvasRef.current.getContext('2d'), this.processVideo);
      });
    });
  }

除了获取和解析人脸检测模型的二进制文件并设置到state中之外,我们还创建了一个新的camvas,它引用了<canvas>上下文和一个回调处理程序。camvas库从用户的网络摄像头将视频加载到canvas上,并针对渲染的每一帧调用处理程序。loadFaceFinder的代码几乎与pico.js提供的参考项目相同。我们只是更改了存储模型的位置,以便可以利用state访问,我们通过React的Ref(而不是使用浏览器提供的DOM API)来引用我们的canvas上下文。

我们的this.processVideo也几乎与参考项目中提供的代码相同。我们只需要稍微做一些改动。我们希望只在加载模型时执行代码,因此我们在代码的整个主体外又添加一个检查。我还用我们希望用户传入的回调处理程序创建了这个React类,因此只有在定义了该处理程序时,才会运行处理代码:

processVideo = (video, dt) => {
    if(this.state.faceFinder && this.props.onFaceFound) {
      /* all the code */
    }
}

我只改动了一个地方:在检测到面部时作何处理。pico.js示例在canvas绘制了一些圆圈,但我们希望将数据传递回我们的回调处理程序。让我们稍微修改一下代码, 以方便我们的回调处理程序更容易地处理这些值:

          this.props.onFaceFound({
            x: 640 - dets[i][1],
            y: dets[i][0],
            radius: dets[i][2],
            xRatio: (640 - dets[i][1]) / 640,
            yRatio: dets[i][0] / 480,
            totalX: (640 - dets[i][1]) / 640 * window.innerWidth,
            totalY: dets[i][0] / 480 * window.innerHeight,
          });

这种格式允许我们传回在捕获到的canvas元素中面部的绝对位置和半径,面部相对于canvas元素的相对位置,以及面部相对于canvas元素的位置映射到整个页面后的位置。到这里我们自定义的类就基本完成了。接下来,我还需要对pico.js和pico版本的camvas.js进行一些小改动才能使用现代语法,但这些只是关键字的变化,不涉及逻辑关系。

现在,我们可以将我们的自定义ReactPico类导入到我们的应用程序中,渲染,并在我们检测到面部时有条件地渲染FaceIndicator类。在尝试了其他一些人脸检测库之后,我很惊喜地发现pico.js的准确性和可用性非常高,尽管它还不是一个完全成熟的库。

原文:https://www.infoworld.com/article/3403019/javascript-tutorial-add-face-detection-to-your-web-app.html

本文为 CSDN 翻译,转载请注明来源出处。

【End】


 热 文 推 荐 

一场全能的开发者大会,来自助力开发者成功进阶的华为云

☞微信们正在成为“被模仿者”!中国互联网现状及趋势报告

☞深入浅出 Vue 响应式原理!

☞程序员爬取 3 万条评论,《长安十二时辰》槽点大揭秘!

☞暗网竟成比特币最大用户? 上半年5.15亿美元被用于非法活动

☞抖音微博等短视频千万级高可用、高并发架构如何设计?

☞10个简单小窍门带你提高Python数据分析速度(附代码)

☞Fast.ai:从零开始学深度学习 | 资源帖

☞实测!华为鸿蒙比 Android系统快60%!

点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

你点的每个“在看”,我都认真当成了喜欢

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存