Nodejs调用百度AI接口实现人脸识别

3,771 阅读5分钟

百度AI提供了非常强大的AI接口,可以非常容易实现诸如图片识别,语音识别,文字识别,人脸识别等功能。 下面以人脸识别为例,说明下如何通过Nodejs调取百度AI接口,实现识别人脸的位置、年龄、性别、颜值、情绪等信息。

1. 项目创建

首先使用Express的脚手架创建一个项目。 对于Express不熟悉的同学可以先看看这篇文档:www.expressjs.com.cn/

安装 express脚手架

 npm install express-generator -g

创建项目:

express  myapp

项目创建好之后,安装 axios,用来做网络请求。

npm i axios -S

2. 登录百度AI,创建项目

在正式调用接口前,需要先注册好百度的账号,然后登录百度AI开放平台:ai.baidu.com/ 登录成功后点右上角进入到控制台。

点击左侧的人脸识别,进去之后,创建一个项目。在创建页面,根据自己的需求填写就可以。 点击管理项目可以看到项目列表。在这里可以获取到项目的API Key和Secret Key,以后会用到。

3. 获取Access Token

调用人脸识别的接口的时候,需要传入一个Access Token参数,所以我们需要先获取下这个token。

获取Access Token

请求URL数据格式

向授权服务地址aip.baidubce.com/oauth/2.0/t…

  • grant_type: 必须参数,固定为client_credentials;
  • client_id: 必须参数,应用的API Key;
  • client_secret: 必须参数,应用的Secret Key;

服务器返回的JSON文本参数如下:

  • access_token: 要获取的Access Token;
  • expires_in: Access Token的有效期(秒为单位,一般为1个月);
  • 其他参数忽略,暂时不用;

例如:

{
  "refresh_token": "25.b55fe1d287227ca97aab219bb249b8ab.315360000.1798284651.282335-8574074",
  "expires_in": 2592000,
  "scope": "public wise_adapt",
  "session_key": "9mzdDZXu3dENdFZQurfg0Vz8slgSgvvOAUebNFzyzcpQ5EnbxbF+hfG9DQkpUVQdh4p6HbQcAiz5RmuBAja1JJGgIdJI",
  "access_token": "24.6c5e1ff107f0e8bcef8c46d3424a0e78.2592000.1485516651.282335-8574074",
  "session_secret": "dfac94a3489fe9fca7c3221cbf7525ff"
}

token的有效时间为:2592000ms。最好把token缓存起来。这里我使用redis来缓存。

安装redis

我以Mac说明 到redis官网下载redis:redis.io/ 下载完成后:

  1. 解压:tar zxvf redis-4.0.10.tar.gz
  2. 移动到: mv redis-4.0.10 /usr/local/
  3. 切换到:cd /usr/local/redis-4.0.10/
  4. 编译测试: sudo make test
  5. 编译安装: sudo make install
  6. 启动: redis-server
  7. 新建一个终端窗口,输入命令行redis-cli
  8. 保存数据 set name 'davie'
  9. 获取数据 get name

安装 redis 库

在Nodejs使用redis,需要先安装redis库. 参考文档:www.npmjs.com/package/red… 安装:

npm install redis

获取Access Token

var qs = require('querystring');
let axios = require('axios');

var redis = require("redis"),
    client = redis.createClient();
 
client.on("error", function (err) {
    console.log("Error " + err);
});

/**
 * 把token使用redis缓存起来
 */
async function getToken(){

    return new Promise(function(resolve,reject){
        client.get('token',async (err,reply) =>{
            if(err){
                reject(err)
            }else{
                if(reply){
                    resolve(reply)
                }else{
                    let result = await getNewToken();
                    // 缓存token,设置时间
                    // 参考 https://www.npmjs.com/package/redis
                    client.set('token', result.data.access_token, 'EX', result.data.expires_in);
                    resolve(result.data.access_token)
                }
            }
        })
    })
}

async function getNewToken(){
    const param = qs.stringify({
        'grant_type': 'client_credentials',
        'client_id': '这里换成你的API Key',
        'client_secret': '这里换成你的Secret Key'
    });
    return  axios.get('https://aip.baidubce.com/oauth/2.0/token?'+ param)
}

module.exports = getToken;

4. 图片上传

实现图片上传功能,来获取图片。

添加图片上传页面

在views目录下新建home.jade,代码如下:

extends layout

block content
  h1= title
  div 图片上传
  form(action="/upload", method="post" enctype="multipart/form-data")
    input(type="file" name="avatar")
    input(type="submit" value="提交")

这个页面是使用jade写的,你也可以使用ejs或其他模板。

路由到home页面,修改routes/index.js

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('home', { title: 'Express' }); //渲染home页面
});

测试一下,启动服务器

npm start

在浏览器地址栏输入:http://localhost:300 可以看到一个图片上传页面。

安装multer中间件

为了实现图片上传,我们还需要multer,它是一个Nodejs的图片上传中间件。 文档:www.npmjs.com/package/mul… 安装multer:

npm install --save multer

设置图片上传目录:

var multer  = require('multer')
var upload = multer({ dest: 'public/uploads/' })

实现图片上传接口:

routes/index.js中添加:

router.post('/upload',upload.single('avatar'),(req,res)=>{
  let imgUlr = 'http://localhost:3000/uploads/' + req.file.filename
})

在前端图片上传页面选择图片提交后,就会把数据提交到这个接口,图片会被保存到public/uploads/目录下。

上传后的图片名称为: req.file.filename,所以一个可访问的图片地址就是:'http://localhost:3000/uploads/' + req.file.filename

5. 调用人脸识别接口

接口地址:https://aip.baidubce.com/rest/2.0/face/v1/merge?access_token=你的touken 使用post方法请求,token拼接在url上。

请求参数说明:

  • image:图片信息(总数据大小应小于10M),图片上传方式根据image_type来判断
  • image_type:
    • BASE64:图片的base64值,base64编码后的图片数据,编码后的图片大小不超过2M;
    • URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长);
    • FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个

必填的参数只有这两个,其他还有:face_field、max_face_num、face_type、liveness_control 详情参看文档:ai.baidu.com/ai-doc/FACE…

其中image_type的值可以是BASE64,URLFACE_TOKEN,这里我使用了第一种BASE64。 那就需要把上传的图片转成base64.

图片转base64

安装 image-to-base64

https://www.npmjs.com/package/image-to-base64

使用方法:

const image2base64 = require('image-to-base64');
image2base64("path/to/file.jpg") // you can also to use url
    .then(
        (response) => {
            console.log(response); //cGF0aC90by9maWxlLmpwZw==
        }
    )
    .catch(
        (error) => {
            console.log(error); //Exepection error....
        }
    )

请求接口

async function getFaceResult(imgUrl,response){
  try {
    let token = await getToken();
    let imgBase64 =  await image2base64(imgUrl) // you can also to use url
    
    let faceResult = await axios.post('https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token='+ token,
    {
      image:imgBase64,
      image_type:"BASE64",
      face_field:'age,beauty,expression,face_shape,gender,glasses,landmark,landmark150,race,quality,eye_status,emotion,face_type'
    })
    response.render('index',faceResult.data.result.face_list[0])
  } catch (error) {
    response.send(error)
  }
}

图片上传后调用:

router.post('/upload',upload.single('avatar'),(req,res)=>{
  let imgUlr = 'http://localhost:3000/uploads/' + req.file.filename
  getFaceResult(imgUlr,res);
})

完成。

欢迎关注:【微信公号:H5开讲啦】

qrcode_for_gh_af6d0ab2a309_258.jpg