基于node.js 实现百度ai人脸检测功能(api)
很有幸和老师同学们一起尝试学习百度ai的相关技术文档,自己做了一个很ez的人脸检测的小网页,和大家分享一下。
1.首先根据技术文档中的要求我们要获取access_token
这个我们只需要去注册自己的百度智能云的id账号,然后进入人脸识别页面页面,创建自己的应用,就可以获取到自己的API Key 以及Secret Key,拿到这个就可以去根据实例代码获取我们要的access_token了。
示例图如下:
根据百度ai技术文档提供的获取access_token的方法,可以获取到如下相关信息。
注意这是一个node的项目,相关模块需要用npm/cnpm安装,我想有node基础的同学就不用我阐述了。
官方获取access_token代码如下:
var https = require('https');
var qs = require('querystring');
const param = qs.stringify({
'grant_type': 'client_credentials',
'client_id': 'xCRoucNpcqBSL3Ssvyz9003z',
'client_secret': 'wTxCPkMOnNZmat4PxWMgu8wU2QA8ZvGK'
});
https.get({
hostname: 'aip.baidubce.com',
path: '/oauth/2.0/token?' + param,
agent: false
},
function (res) {
// 在标准输出中查看运行结果
res.pipe(process.stdout);
}
);
注意:client_id 和 client_secert 分别填入你获取到的API Key 以及Secret Key。这样运行这个js文件, 用node命令运行,dos返回结果
/*{
"refresh_token": "25.229e474f1ddaa3dd8bf615a0640c1db5.315360000.1886430622.282335-17511300",
"expires_in": 2592000,
"session_key": "9mzdWrktAR59shMTTbnfWJ2QNQo6NqrQQiSZlE94z70aI5ttomvuXYJVIPzSXw2n3cMf7hgoug5m4hhhYoeIUTlDmx+byA==",
"access_token": "24.ae8755d49cf860037da7cb9f4868af07.2592000.1573662622.282335-17511300",
"scope": "vis-ocr_ocr brain_ocr_idcard public brain_all_scope vis-faceverify_faceverify_h5-face-liveness vis-faceverify_FACE_V3 vis-faceverify_idl_face_merge brain_cvpaas-app-scope wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test\u6743\u9650 vis-classify_flower lpq_\u5f00\u653e cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_\u5f00\u653eScope",
"session_secret": "c66f9aa948dc1c44b542d8798626ad6d"
}
*/
这里获取到的"access_token"就是我们要的数据
2.然后请求官方api,人脸识别的接口,这个会在你创建的应用下面有,分为v2和v3版本。
示例图如下:
如图可以看到人脸识别接口的api,以及接口是v3
然后完善我们后台的请求接口 /face
let express = require('express');
let https = require('https');
let request = require('request');
var router = express.Router();
//人脸识别接口
var token = "24.ae8755d49cf860037da7cb9f4868af07.2592000.1573662622.282335-17511300";
//url 林更新
var str = 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1219144778,2690834063&fm=26&gp=0.jpg';
router.post('/', (req, res) => {
let options = {
host: 'aip.baidubce.com',
path: '/rest/2.0/face/v3/detect?access_token="' + token + '"',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
let contents = JSON.stringify({
// url 图片类型
image: str,
image_type: "URL",
"face_field": 'age,beauty,expression,face_shape,gender,glasses,race',
//这里根据文档填入你想要获取到的参数
});
let req_baiduai = https.request(options, function (res_baiduai) {
res_baiduai.setEncoding('utf8');
res_baiduai.on('data', function (chunk) {
res.send(chunk)
var testResult = JSON.parse(chunk);
console.log(chunk)
res.end();
})
});
req_baiduai.write(contents);
req_baiduai.end();
});
module.exports = router;
注意: 如果要使用BASE64 图片类型
需要修改上述代码:
var fs = require(‘fs’);
var image = fs.readFileSync(’./ab.png’).toString(‘base64’);
添加fs模块获取你要测试的本地图片并且转换为base64格式修改body请求体
//base 64 图片类型
image: image,
image_type: “BASE64”,
3.通过前端获取到我们的后台接口/face返回的请求百度的数据
其中数据是通过ajax获取到的,并且通过js全局变量返回到全局环境以便于之后的渲染操作。
$.ajax({
//几个参数需要注意一下
type: "post", //方法类型
// dataType: "json", //预期服务器返回的数据类型
url: "http://localhost:2019/face", // url
// data: $('#form1').serialize(),
success: function (res) {
{
console.log(res); //打印服务端返回的数据(调试用);
a += res;
alert("提交成功!!!");
return a;
}
},
async: false,
error: function () {
alert("提交异常!");
},
});
4.布局前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="icon" href="../images/bg.jpg" type="images/x-ico" />
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script src="./js/vue.js"></script>
</head>
<style>
* {
margin: 0;
padding: 0
}
html,
body {
width: 100%;
height: 100%;
background-image: url(../images/007.jpg);
background-size: cover;
overflow-y: hidden;
}
video {
position: absolute;
left: 100px;
border: 10px solid white;
}
canvas {
position: absolute;
left: 150px;
bottom: -20px;
}
button {
position: absolute;
width: 100px;
height: 30px;
top: 330px;
left: 260px;
}
.result {
position: absolute;
width: 370px;
height: 500px;
right: 200px;
top: 30px;
/* border: 5px solid white; */
text-align: center;
padding: 20px;
color: white;
/* background: black; */
}
p {
text-align: left;
font-size: 20px;
font-weight: 600;
color: white;
line-height: 30px;
}
</style>
<body>
<video id="video" width="400" height="300" autoplay></video>
<button id="snap">Snap Photo</button>
<canvas id="canvas" width="400" height="300"></canvas>
<div class="result">
<h1>人脸属性</h1>
<p>"face_num":{{ msg0 }}</p>
<p>"face_token":{{ msg1 }}</p>
<p>"face_probability":{{ msg2 }}</p>
<p>"age":{{ msg3 }}</p>
<p>"beauty":{{ msg4 }}</p>
<p>"expressiton":{{ msg5 }}</p>
<p>"face_shape":{{ msg6 }}</p>
<p>"gender":{{ msg7 }}</p>
<p>"glasses":{{ msg8 }}</p>
<p>"race":{{ msg9 }}</p>
</div>
</body>
<script type="text/javascript">
var aVideo = document.getElementById('video');
var aCanvas = document.getElementById('canvas');
var ctx = aCanvas.getContext('2d');
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia; //获取媒体对象(这里指摄像头)
navigator.getUserMedia({
video: true
}, gotStream, noStream); //参数1获取用户打开权限;参数二是一个回调函数,自动传入视屏流,成功后调用,并传一个视频流对象,参数三打开失败后调用,传错误信息
function gotStream(stream) {
// video.src = URL.createObjectURL(stream); // 老写法
aVideo.srcObject = stream;
aVideo.onerror = function () {
stream.stop();
};
stream.onended = noStream;
aVideo.onloadedmetadata = function () {
// alert('摄像头成功打开!');
};
}
function noStream(err) {
alert(err);
}
document.getElementById("snap").addEventListener("click", function () {
ctx.drawImage(aVideo, 0, 0, 320, 240); //将获取视频绘制在画布上
});
//cancas 保存图片
var a = "";
$.ajax({
//几个参数需要注意一下
type: "post", //方法类型
// dataType: "json", //预期服务器返回的数据类型
url: "http://localhost:2019/face", // url
// data: $('#form1').serialize(),
success: function (res) {
{
console.log(res); //打印服务端返回的数据(调试用);
a += res;
alert("提交成功!!!");
return a;
}
},
async: false,
error: function () {
alert("提交异常!");
},
});
var testResult = JSON.parse(a);
// var datalist = JSON.parse()
var vm = new Vue({
el: '.result', // 表示 我们 new的这个实例要去控制页面上的哪个区域
data: { //data中存放的是el中要用到的数据
msg0: testResult.result.face_num,
msg1: testResult.result.face_list[0].face_token,
msg2: testResult.result.face_list[0].face_probability,
msg3: testResult.result.face_list[0].age,
msg4: testResult.result.face_list[0].beauty,
msg5: testResult.result.face_list[0].expression,
msg6: testResult.result.face_list[0].face_shape,
msg7: testResult.result.face_list[0].gender,
msg8: testResult.result.face_list[0].glasses,
msg9: testResult.result.face_list[0].race,
//通过vue提供的指令就可以简单的把数据渲染到页面上,不提倡操作dom
}
});
</script>
<script>
</script>
</html>
其中数据是通过vue渲染上去的,可能拿数据比较粗鲁,但是因为时间原因,嘻嘻嘻,希望大家理解。
最后的效果如下:
测试
如果你使用的图片是url形式,只需要在网上找一些明星照片然后填入url地址就可以,如果你使用base64格式图片,可以在摄像头开启之后拍摄一张图片,(我是用canvas画布将拍照效果保存页面上,你可以直接右键保存到你的项目的文件夹下)然后再次刷新页面就会出现效果。