微信小程序使用tensorflow.js完成前端人脸业务(1)

微信小程序使用tensorflow.js完成前端人脸业务(1)

  • 研究动机
  • 环境搭建
  • 牛刀小试
    • 使用blazeface api 载入模型
    • 建立一个UI界面,检测模型是否正确预测
  • 下章内容

研究动机

人脸业务主要包括如下:

  1. 人脸检测(face detection)检测图片中是否包含人脸信息,用矩形标识出人脸的位置。
  2. 人脸验证(face verification)判断人脸图像是否为某个人。
  3. 人脸鉴别(face identification)判断人脸图像是谁。
  4. 人脸关键点 (face landmark) 标识诸如眼睛、鼻子、嘴巴等关键点。

对于这些业务,百度讯飞等各大厂有提供外部接口,但本文章旨在介绍如何不使用这些API,实现人脸业务,不要总是做调包侠,深入学习人脸业务对将来想要做机器视觉方面工作的小伙伴很有帮助。

为什么要做前端人脸业务呢?
因为这样可以减少服务器的负担,你想啊,如果用后端做人脸检测,那就要把每帧图片发送到服务器,由服务器来做各种人脸检测操作,然后把结果返回回来,这是非常耗时耗资源的,不仅需要考虑高并发资源消耗问题,而且由于很难达到实时性,用户体验较差。而前端人脸业务则解决了这个痛点,服务器只需要发送一次用于实现人脸业务的模型,由前端实现模型正向推理(预测),这样就把原来后端服务器的工作转移到前端设备上,不仅减少了服务器负担而且可以轻松实现实时检测。

对于Android端,我已经找到了很好的前端人脸业务实现。
微信小程序使用tensorflow.js完成前端人脸业务(1)_第1张图片

简单介绍一下实现过程:首先使用Google ML Ki提供的人脸检测业务,然后用mobilefacenet完成人脸embedding,得到512维的向量,然后和已注册人脸数据比对,得到最终结果。

而对于微信小程序,我没有找到前端人脸业务的完整实现,接下来我将会介绍在微信小程序端如何实现前端人脸业务。

环境搭建

首先是根据tfjs-wechat的GitHub仓库教程来加入tensorflow.js。具体步骤如下:

  1. 首先你需要注册微信小程序,然后打开微信小程序后台,在“设置-第三方服务-插件管理”中添加插件,可以通过 appid [wx6afed118d9e81df9] 查找插件并添加。
  2. app.json中引入插件代码包(建议使用0.1.0最新版本)
{
  ...
  "plugins": {
    "tfjsPlugin": {
      "version": "0.1.0",
      "provider": "wx6afed118d9e81df9"
    }
  }
  ...
}
  1. 用npm安装tensorflow.js包,这个项目需要使用tf.loadGraphModel API来载入模型,所以需要填充fetch函数,npm的package.json文件如下:
{
  "name": "face_detect",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "@tensorflow/tfjs-backend-cpu": "2.0.1",
    "@tensorflow/tfjs-backend-webgl": "2.0.1",
    "@tensorflow/tfjs-converter": "2.0.1",
    "@tensorflow/tfjs-core": "2.0.1",
    "fetch-wechat": "0.0.3"
  },
  "author": "",
  "license": "ISC"
}
  1. 使用npm安装,对于有困难的朋友,可以考虑使用镜像nrm,安装速度可以快很多。然后运行一下代码,进行批量安装。
npm install
  1. 微信小程序右上角‘详情-本地设置’完成如下配置:
    微信小程序使用tensorflow.js完成前端人脸业务(1)_第2张图片

  2. 微信小程序菜单栏上’工具-构建npm’,构建后会出现如下警告,但不影响运行。
    微信小程序使用tensorflow.js完成前端人脸业务(1)_第3张图片

  3. 在app.js的onLaunch里调用插件configPlugin函数

var fetchWechat = require('fetch-wechat');
var tf = require('@tensorflow/tfjs-core');
var webgl = require('@tensorflow/tfjs-backend-webgl');
var plugin = requirePlugin('tfjsPlugin');
//app.js
App({
  onLaunch: function () {
    plugin.configPlugin({
      // polyfill fetch function
      fetchFunc: fetchWechat.fetchFunc(),
      // inject tfjs runtime
      tf,
      // inject webgl backend
      webgl,
      // provide webgl canvas
      canvas: wx.createOffscreenCanvas()
    });
  }
});

8.编译,将会有如下警告,但不影响运行。
微信小程序使用tensorflow.js完成前端人脸业务(1)_第4张图片
OK!~自此tensorflow环境就配置好了。

牛刀小试

使用blazeface api 载入模型

对于人脸检测,tensorflow.js已经给出了开箱即用的工具,不仅提供了blazeface人脸检测预训练模型,而且还提供了api,只需要调用简单的几个函数,即可完成人脸检测。当然,除了人脸检测,tensorflow.js还提供了很多其他的预训练模型以及api,网站在此。废话不多说,我们来使用blazeface api载入模型吧。

首先运行npm安装blazeface工具包。

npm install @tensorflow-models/blazeface

然后在页面js文件的onReady函数中载入模型,具体载入代码如下:

const blazeface = require('@tensorflow-models/blazeface');
const model = await blazeface.load({modelUrl:“这里填模型的地址”});

如果不指定一个本地模型的地址,那么模型将从tensorflow Hub网站上下载,速度很慢,所以建议先把模型下载下来,用http-server打开一个静态服务器,然后便可以快速加载模型了。
具体操作如下:

  1. 打开这个tensorflow Hub官网网址,点击下载即可,如果不能,这里提供百度网盘链接,提取码是:fazc
  2. 使用npm全局安装http-server
npm install http-server -g
  1. 使用http-server打开静态服务器,path-to-model是填你模型下载所在的文件夹路径,–cors是解决跨域问题的,一定要加上,不然会报错,无法获取模型
hs path-to-model --cors
  1. 模型地址就是http://127.0.0.1:8080/model.json,这里注意model.json其实是定义了模型的结构,api读取该.json之后,会自动加载同一文件夹下的.bin文件,即权重文件。

OK! 模型载入完成

建立一个UI界面,检测模型是否正确预测

index.wxml

<view class="container">
  <camera device-position="front" flash="off" frame-size="small">camera>
  <text class="result">{{result}}text>
view>

index.wxss

camera{
  width: 576rpx; 
  height: 704rpx;
  z-index: 5;
}
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
} 

index.js

import * as tf from '@tensorflow/tfjs-core'
const blazeface = require('@tensorflow-models/blazeface');
Page({
  data: {
    result: "载入中...",
    _modelUrl: 'http://127.0.0.1:8080//model.json',
  },
  _model: null,
  async onReady(options){
    const model = await blazeface.load({modelUrl:this.data._modelUrl});
    this._model = model;
    const context = wx.createCameraContext();
    let count = 0;
    const listener = context.onCameraFrame((frame) => {
      count++;
      if (count === 3) {
        this.detectFace(frame);
        count = 0;
      }
    });
    listener.start();
  },
  async detectFace(frame) {
    if (this._model) { 

      const image = {
        data: new Uint8Array(frame.data),
        width: frame.width,
        height: frame.height
      }
      const res = await this._model.estimateFaces(image);
      if(res.length>=1){
        this.setData({
          result:"检测到人脸"
        })
      }
      else{
        this.setData({
          result: "没有检测到人脸"
        })
      }
    }
  }
})

源码在这里,需要注意:微信小程序开发者暂不支持相机组件在电脑预览,因此在模拟器中无法看到真实效果,所以就要用手机预览了,这个时候需要改变index.js中的‘page-data-_modelUrl’变量,因为‘127.0.0.1’其实是本地地址,需要更换成sh运行打印的另外一个地址,地址根据实际电脑的ip地址不同而不同。图片如下:
微信小程序使用tensorflow.js完成前端人脸业务(1)_第5张图片

OK! 完美,到这里blazeface检测模型已经测试完成,不难发现这个模型预测速度是非常快的,完全达到了实时检测的要求。

下章内容

接下来的文章将会在此基础上做以下几点优化:

  1. 解决电脑模拟器无法预览的问题
  2. 分析blaze face api源码
  3. 修改blaze face api,使其更好地在微信小程序中调用
  4. 加入对人脸预测框和关键点的标识

下一个教程:微信小程序使用tensorflow.js完成前端人脸业务(2)

你可能感兴趣的:(tensorflow,机器学习,小程序)