腾讯人脸识别登录Express+Vue2
腾讯云操作
1、注册腾讯账号并实名认证(微信注册也可)
2、开通服务
在 人脸识别控制台 中,按照页面提示,同意《人脸识别服务规则》后,即可开通服务。
3、人员库管理/人员管理 新建人员库
点击人员库名称进去创建人员
4、有一定node基础的可以手动配置生成后端代码
后端express中
1、npm 下载依赖包
# 生成token包 npm i jsonwebtoken # 腾讯人脸识别包 npm i tencentcloud-sdk-nodejs-iai # 配置跨域包 npm i cors
别忘了在app中配置跨域
2、路由视图中代码
//生成token包(npm i jsonwebtoken) let jwt = require("jsonwebtoken") //腾讯人脸识别包(npm i tencentcloud-sdk-nodejs-iai) const tencentcloud = require("tencentcloud-sdk-nodejs-iai"); //人脸识别登录 router.post('/faceLogin',async (req, res) => { //获取前端传来的base64 let b64 = req.body.b64 const IaiClient = tencentcloud.iai.v20200303.Client; const clientConfig = { credential: { //自己的腾讯secretId secretId: "自己的腾讯secretId", //自己的腾讯密匙 secretKey: "自己的腾讯密匙", }, region: "ap-beijing", //地域参数(华北地区北京) profile: { httpProfile: { endpoint: "iai.tencentcloudapi.com", }, }, }; const client = new IaiClient(clientConfig); const params = { "GroupIds": [ //你创建的人员库ID "你创建的人员库ID" ], "Image": b64, //图片的base64格式编码 "NeedPersonInfo": 1, //是否返回人员具体信息。0 为关闭,1 为开启。默认为 0。 "QualityControl": 0, //图片质量控制。 0: 不进行控制; 1:较低的质量要求 "FaceMatchThreshold": 85, //人脸对比度设置为大于85才可 }; let doc = await client.SearchFaces(params) //doc为人脸识别后的返回信息 console.log(doc,'doc'); if(doc.FaceNum===1){ //表示当前人脸库有该人员 let personId = doc.Results[0].Candidates[0].PersonId //拿到该人员的ID let personName = doc.Results[0].Candidates[0].PersonName //拿到该人员的名称 console.log(personName,'personNume'); //根据该人员的名称去MongoDB中查询该用户对象(可以跳过这一步) let userObj = await userModel.findOne({username:personName}) console.log(userObj,'userObj'); if (userObj) { //如果查询到该用户 //生成token let token = jwt.sign({ "name": userObj.username }, "secretKey", { expiresIn: '1d' }) res.send({ code: 200, msg: "登录成功!", userObj, token }) return false } else { res.send({ code: 250, msg: "用户名或密码错误!", doc }) return false } }else{ res.send({ code:251, msg:'人脸库无此人!' }) return false } })
后端工程配置完毕,如有疑问可自行百度,也可私信up
前端Vue2中
1、准备工具文件
百度网盘下载js工具包
链接: https://pan.baidu.com/s/1snApbFqPPwOkhxwDWZ7_LA
提取码: dxc6
解压后会得到一个js文件夹,把它放到src/assets文件夹下
前端中用到了element-ui组件库,需提前配置好
2、Login.vue中
<template> <div class="login-wrapper"> <div class="big-box" v-show="isShowV"> <div class="video-box"> <video id="video" width="320" height="240" preload autoplay loop muted></video> <canvas id="canvas" width="320" height="240"></canvas> </div> <div class="success-face"> <canvas id="screenshotCanvas" width="320" height="240"></canvas> <div class="switch-button"> <el-row> <el-button type="primary" @click="destroyed">关闭摄像头</el-button> <el-button type="primary" @click="init">开始识别</el-button> </el-row> </div> </div> </div> <div class="login-form"> <div class="title-container"> <div class="t_wel">欢迎登录</div> <div class="t_site">小川数据可视化平台</div> </div> <div class="form-box"> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" class="demo-ruleForm"> <el-form-item prop="username"> <el-input v-model="ruleForm.username" prefix-icon="el-icon-user-solid" placeholder="请输入用户名"></el-input> </el-form-item> <el-form-item prop="password"> <el-input show-password v-model="ruleForm.password" prefix-icon="el-icon-lock" placeholder="请输入密码"></el-input> </el-form-item> <el-form-item> <el-button @keyup.enter="keyDown" type="primary" @click="submitForm('ruleForm')" style="width: 100%;padding: 15px 0">立即登录</el-button> </el-form-item> <el-form-item> <el-button type="text" @click="faceLoginBtn">人脸识别登录</el-button> </el-form-item> </el-form> </div> </div> </div> </template> <script> import tracking from '@/assets/js/tracking-min' import '@/assets/js/face-min.js' export default { name: "Login2", data() { return { ruleForm: { username: 'admin', password: '123', }, rules: { username: [ { required: true, message: '请输入用户名', trigger: 'blur' }, ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, ], }, //人脸识别用到的变量 trackerTask: null, mediaStreamTrack: null, video: null, screenshotCanvas: null, uploadLock: true, // 上传锁 isShowV:false }; }, methods: { //人脸识别登录 faceLoginBtn(){ this.isShowV = this this.init(); }, // 初始化设置 init() { this.video = this.mediaStreamTrack = document.getElementById('video'); this.screenshotCanvas = document.getElementById('screenshotCanvas'); let canvas = document.getElementById('canvas'); let context = canvas.getContext('2d'); // 固定写法 let tracker = new window.tracking.ObjectTracker('face'); tracker.setInitialScale(4); tracker.setStepSize(2); tracker.setEdgesDensity(0.1); //摄像头初始化 this.trackerTask = window.tracking.track('#video', tracker, { camera: true }); let _this = this; //监听图像变化 tracker.on('track', function(event) { // 检测出人脸 绘画人脸位置 context.clearRect(0, 0, canvas.width, canvas.height); event.data.forEach(function(rect) { context.strokeStyle = '#76e535'; context.strokeRect(rect.x, rect.y, rect.width, rect.height); }); // event.data.length长度为多少代表检测几张人脸 if(_this.uploadLock && event.data.length){ //上传图片 _this.screenshotAndUpload(); } }); }, // 上传图片 screenshotAndUpload() { // 上锁避免重复发送请求 this.uploadLock = false; // 绘制当前帧图片转换为base64格式 let canvas = this.screenshotCanvas; let video = this.video; let ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(video, 0, 0, canvas.width, canvas.height); //base64Img为最终人像数据 let base64Img = canvas.toDataURL('image/jpeg'); //发送给后端 this.$http.post("http://localhost:3000/users/faceLogin",{b64:base64Img.split(',')[1]}).then(res=>{ if(res.data.code===200){ //登录成功把token存在浏览器会话存储中 sessionStorage.setItem("token",res.data.token) this.$message.success(res.data.msg) this.destroyed(); }else if(res.data.code===250){ console.log(res.data,'res.data') this.$message.error(res.data.msg) this.destroyed(); }else if(res.data.code===251){ console.log(res.data,'res.data') this.$message.error(res.data.msg) this.destroyed(); } }) // 请求接口成功以后打开锁 // this.uploadLock = true; }, //关闭摄像头 destroyed(){ if(!this.mediaStreamTrack){ return } this.mediaStreamTrack.srcObject.getTracks()[0].stop(); this.trackerTask.stop() this.isShowV = false }, //键盘事件 keyDown(e){ //如果是回车则执行登录方法 if(e.keyCode === 13){ //需要执行的登录方法 this.submitForm('ruleForm'); } }, //表单登录按钮 submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { this.$message.success('本登录只能使用人脸登录!') } else { console.log('error submit!!'); this.$message.error('请填写登录信息!!!') return false; } }); }, }, mounted() { //绑定事件 window.addEventListener('keydown',this.keyDown); }, //销毁事件 destroyed(){ window.removeEventListener('keydown',this.keyDown,false); } } </script> <style lang="scss" scoped> html,body{ width: 100%; height: 100%; } *{ box-sizing: border-box; } .login-wrapper{ //background-image: url("@/assets/image/暗系-风景.png") ; width: 100%; height: 100%; background-repeat: no-repeat; background-size: 100% 100%; background-position: center center; overflow: hidden; .login-form{ position: absolute; left: 80%; top: 50%; -webkit-transform: translate(-50%,-50%); transform: translate(-50%,-50%); width: 480px; height: 465px; max-width: 100%; margin-right: 120px; padding: 40px 70px 0; overflow: hidden; background-color: rgba(255,255,255,.1); border-radius: 15px; .title-container{ position: relative; text-align: center; .t_wel{ font-size: 26px; line-height: 1; color: #eee; margin-bottom: 10px; } .t_site{ font-size: 14px; line-height: 1; color: #bebebe; margin-bottom: 26px; } } .form-box{ .el-form{ .el-form-item{ .el-input{ margin-top: 10px; } .el-button{ margin-top: 10px; } } } } } .big-box{ position: absolute; top: 5%; left: 50%; width: 320px; //border: 1px solid #ddd; //height: 700px; transform: translate(-50%); .video-box{ width: 320px; height: 240px; #canvas{ position: absolute; top: 0; left: 0; } } .success-face{ width: 320px; height: 240px; //border: #ddd solid 1px; } } } </style>
说明:不管前端怎么写,只要能生成图片的base64编码就行,只要往后端提交图片的base64格式编码即可
注意:前端项目启动只能在本地localhost访问,不能使用ip地址访问项目,不然浏览器调摄像头时会报错,原因是安全隐私问题。切记
前端登录效果图:
前端工程已完毕,如有疑问可自行百度,或者私信up


