百度AI 人脸识别 v3 node版

2018-04-27 人脸接口V3版本发布 新增人脸库管理等功能


本篇文章介绍了如何使用 nodejs 调用V3版本的人脸识别api


2018-05-05

nodejs 后台

var https = require('https')
var qs = require('querystring')
//用express搭建的服务器
var express = require('express')
var app = express()
var fs = require('fs')
var bodyParser = require('body-parser')

/*
 每次启动时都会 请求 /access 接口,从而获取新的access_token,或者可以 持久化数据,保存在json文件里,
 每隔一个月更新一次,因为每隔一个月给的access_token都会不一样
*/
var access_token = ''

const param = qs.stringify({
    'grant_type': 'client_credentials',
    'client_id': '你的 API key', 
    'client_secret': '你的 Secret Key' 
})

//这是我要对比的图片,写的时候有一个问题就是png的图片和jpg的图片不能对比,所以我都替换成png图片了
var bitmap = fs.readFileSync('./images/my03.png')
//图片转为 base64格式
var base64str1 = new Buffer(bitmap).toString('base64')

//bodyParser.urlencoded 限制了提交的大小不超过 50mb
app.use(bodyParser.urlencoded({limit: '50mb', extended: true }))

//我的html,js放在faceid文件夹下
app.use(express.static('../faceid'))

app.post('/access', function (req, res) {
    https.get(
        {
            hostname: 'aip.baidubce.com',
            path: '/oauth/2.0/token?' + param,
            agent: false
        },
        function (res) {
            res.setEncoding('utf8')
            res.on('data',function (data) {
            //取得access_token
                access_token = JSON.parse(data).access_token
            })
        }
    )
})

//这是 html界面 post请求 的judge 
app.post('/judge', function (req, res) {
    let  options = {
        host: 'aip.baidubce.com',
        path: '/rest/2.0/face/v3/match?access_token="'+access_token+'"',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        }
    }
    //这里还有很多参数,我都没写,具体的看官网
    /*
        从html界面传回来的数据req.body.img,然后用正则来格式化,
        replace(/\s/g, "+")这个是把任何的Unicode空白符转化为 +
        replace(/^data:image\/\w+\Wbase64,/, "") 再把字符串开头的data:image/png;base64 删除
        ^ 匹配字符串的开头,
        \/匹配/
        \w+ 匹配任何ASCII字符组成的单词 
        \W  匹配任何非ASCII字符

    */
    let contents = JSON.stringify([
        {
            image: base64str1,
            image_type: "BASE64",
        }, {
            image: req.body.img.replace(/\s/g, "+").replace(/^data:image\/\w+\Wbase64,/, ""),
            image_type: "BASE64",
        }
    ])

    let req_baidu = https.request(options, function (res_baidu) {
        res_baidu.setEncoding('utf8')
        res_baidu.on('data', function (chunk) {
            //百度返回来的数据,有得分,直接发给html,在html中处理
            res.send(chunk)
        })

    })
    req_baidu.write(contents)
    req_baidu.end()

})
//服务在3302端口
var server = app.listen(3302, function () {
    console.log('listening at http://%s','localhost:3302');
})

接下来是 html 代码


<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="best" content="Best">
    <title>人脸识别title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        html, body {
            height: 100%;
            background: #f9f9f9;
        }

        body {
            display: flex;
            /*弹性布局,用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为Flex布局。
                       子元素的float、clear和vertical-align属性将失效。http://blog.csdn.net/u011300580/article/details/56011564*/
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .veriface {
            width: 800px;
            height: 500px;
            background-color: #FFFFFF;
            display: flex;
            flex-direction: column;
            justify-content: space-around;
            align-items: center;
        }

        .veriface .capture {
            display: block;
            width: 760px;
            height: 360px;
            background-color: #222222;
        }

        .veriface .control {
            display: flex;
            flex-direction: row;
            justify-content: space-around;
            align-items: center;
            width: 100%;
            height: 70px;
        }

        .veriface .control span {
            width: 100px;
            height: 45px;
            background: #F9F9F9;
            text-align: center;
            line-height: 45px;
            color: #222222;
            font-size: 12px;
            border-radius: 8px;
            box-shadow: 0 0 4px #cccccc;
            user-select: none;
            cursor: pointer;
            transition: 1s;
        }

        .veriface .control span:hover {
            background-color: #e6e6e6;
        }

        .veriface h3.notice {
            color: #336688;
        }
        .draw_img{
            position: fixed;
            bottom: 0px;
            left: 0px;
        }
    style>
head>
<body>
<canvas class="draw_img" width="300" height="200">canvas>
<div class="veriface" style="margin-top: 3px">
    <video class="capture" width="760" height="360" src="">video>
    <h3 class="notice">把脸放过来h3>
    <div class="control">
        <span class="open">开启摄像头span>
        <span class="recognition">人脸识别span>
        <span class="close">关闭摄像头span>
    div>
div>
<script>
    /*
          从前台到后台的人脸识别
            1.开启摄像头
                1)window.navigator
            2.同步到video的src
                对象=> window.URL =>blob
                1)解析视频流为blob 添加到 src
            3.canvas创建视频片段照片
            4.
    */

    var open = document.querySelector('.open');//获取open按钮
    var capture = document.querySelector('.capture'); // 获取video标签
    var recognition = document.querySelector('.recognition'); //获取人脸识别的按钮

    var close = document.querySelector('.close');
    var notice = document.querySelector('.notice');
    var canvas = document.querySelector('.draw_img');
    var context = canvas.getContext('2d');
    var buffer;

    open.onclick = invokingCamera;  //回调函数 函数名称加括号是主动执行
    recognition.onclick = screenShot;  //点击人脸识别
    close.onclick = function () {
        //console.log(buffer);
        buffer && buffer.getTracks()[0].stop(); //停止视频流
        //console.log(buffer);
    }
    //获取摄像头,获取流媒体数据
    function invokingCamera() {
        if (navigator.mediaDevices.getUserMedia) {
            //优先使用前置摄像头
            navigator.mediaDevices.getUserMedia({audio: false, video: {facingMode: "user"}}).then(
                //获取视频流数据 成功后
                function (MediaStream) {
                    //console.log(stream);
                    buffer = MediaStream; //会指向一个内存地址
                    //console.log(buffer);
                    capture.srcObject = MediaStream;
                    capture.onloadedmetadata = function(e) {
                        capture.play();
                    };
                }
            ).catch(
                //失败后
                function (err) {
                    console.log(err.name + ": " + err.message);
                }
            );
        } else {
            alert('您的浏览器不支持摄像头');
        }
    }

    function screenShot() {
        msg('正在检测,请稍后~~~', '#c665ff');
        context.drawImage(capture,0,0,200,150);
        new Post({
            url: '/judge',
            data:canvas.toDataURL('image/png'),
            success: function (res) {
                 console.log(res); //服务器发送的消息
                res = JSON.parse(res).result.score;
                console.log(typeof res);
                if (res > 85) {
                    msg('欢迎主人~', '#7ef6c7');
                } else {
                    msg('丑拒~~', '#f10d0f');
                }
            }
        })
    }

    function msg(con, color) { //输出信息
        notice.innerHTML = con + '';
        notice.style.color = color;
    }

    //post 方式传输数据 get的话 base64 5mb url
    function Post(opt) {
        //构造函数
        this.init(opt);
    }

    Post.prototype = {
        init: function (opt) {  //初始化 参数 URL地址 Data参数 method方式
            this.url = opt.url || '';
            this.data = opt.data || {};
            this.method = 'POST';
            this.async = true;//异步
            this.success = opt.success || function () {  //回调函数
            }
            this.xhr();
        },
        xhr: function () {
            var that = this;
            var xhr = new XMLHttpRequest();//ajax对象实例化
            console.log(this.data)
            //请求的类型  请求地址 异步或者同步
            xhr.open(this.method, this.url, this.async);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); //表头
            xhr.send('img='+this.data);
            xhr.onreadystatechange = function (ev) {
                if (xhr.status === 200 && xhr.readyState === 4) {
                    this.success(xhr.response);//回调数据
                }
            }.bind(this);
        }
    }
    new Post({
        url: '/access',
        data:'',
    })
script>
body>
html>

你可能感兴趣的:(javascript)