55

JavaScript教程:为Web应用程序添加人脸检测功能

 5 years ago
source link: https://www.tuicool.com/articles/byeY32e
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【51CTO.com快译】上周我们使用annyang为地图界面增添了语音命令(https://www.infoworld.com/article/3400658/javascript-tutorial-add-speech-recognition-to-your-web-app.html)。本周我们将使用pico.js添加简单的头部跟踪功能,进一步增强我们的多模式界面。pico.js是一个精简的JavaScript库,与其说是生产级库不如说是概念证明,但它在我研究过的人脸检测库中似乎效果最好。

YzMJFre.jpg!web

本文旨在用简单的红点开始显示覆盖在地图上的用户头部位置:

VnEBfqR.png!web

图1

我们先创建一个包装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入门(https://tehnokv.com/posts/picojs-intro/)深入浅出地介绍了对象检测,但它更像是一篇研究论文,而不像API文档。不过,所附的例子足以实际使用代码。我花了几小时将所附的样本放入到一个比较简单的React类中,我们可以用这个类充分利用代码。

pico.js要做的第一件事是加载级联模型,这需要进行AJAX调用,获取对人脸预训练的模型的二进制表示。(你可以使用同一个库来跟踪其他类型的对象,但需要使用官方的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); 
      }); 
    }); 
  } 

除了获取和解析人脸检测模型的二进制表示并设置状态外,我们还创建了一个新的camvas,它引用<canvas>上下文和回调处理程序。camvas库将视频从用户的网络摄像头加载到canvas上,并为渲染的每个帧调用处理程序。loadFaceFinder的内容几乎就是pico.js提供的参考项目的相同副本。我们更改了存储模型的位置,以便可以在状态下访问。我们通过react Ref来引用canvas上下文,而不是使用浏览器提供的DOM API。

我们的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类导入到我们的App中,渲染它,如果检测到人脸就有条件地渲染FaceIndicator类。我使用另外一些人脸检测库后惊讶地发现,pico.js的准确性和易用性很强,尽管它不是功能完备的库。

原文标题:JavaScript tutorial: Add face detection to your web app,作者:Jonathan Freeman

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK