Vue+tracking.js 实现前端人脸检测功能


Posted in Javascript onApril 16, 2020

项目中需要实现人脸登陆功能,实现思路为在前端检测人脸,把人脸照片发送到后端识别,返回用户token登陆成功

前端调用摄像头使用tracking.js检测视频流中的人脸,检测到人脸后拍照上传后端。

后端使用face_recognition人脸识别库,使用Flask提供restfulAP供前端调用

实现效果如下图:

登陆界面:

Vue+tracking.js 实现前端人脸检测功能

摄像头检测人脸界面:

Vue+tracking.js 实现前端人脸检测功能

前端代码如下:

<template>
 <div id="facelogin">
 <h1 class="title is-1">{{FaceisDetected}}</h1>
 <!-- <p>{{FaceisDetected}}</p> -->
 <div class="content-cam">
 <div class="camera-wrp sec">
 <video width="320" height="320" ref="videoDom" id="video_cam" preload autoplay loop muted></video>
 <canvas width="320" height="320" ref="canvasDOM" id="face_detect"></canvas>
 <div class="control-btn"></div>
 </div>
 <div class="images-wrp sec">
 <!-- <p class="title is-5">Image taken</p> -->
 <div
  :class="`img-item img-item-${index}`"
  v-for="(image, index) in images"
  :key="`img-wrp-${index}`"
  :style="`background-image: url('${image}')`"
 ></div>
 </div>
 </div>
 </div>
</template>

export default {
name: 'facelogin',
data() {
return {
count: 0,
isdetected: '请您保持脸部在画面中央',
videoEl: {},
canvasEL: {},
images: [],
trackCcv: false,
trackTracking: false,
autoCaptureTrackTraking: false,
userMediaConstraints: {
audio: false,
video: {
// ideal(应用最理想的)
width: {
min: 320,
ideal: 1280,
max: 1920
},
height: {
min: 240,
ideal: 720,
max: 1080
},
// frameRate受限带宽传输时,低帧率可能更适宜
frameRate: {
min: 15,
ideal: 30,
max: 60
},
// 摄像头翻转
facingMode: 'user'
}
}
}
},
computed: {
FaceisDetected() {
return this.isdetected
}
},
created() {
this.changeView()
},

 mounted() {
 // The getUserMedia interface is used for handling camera input.
 // Some browsers need a prefix so here we're covering all the options
 navigator.getMedia =
 navigator.getUserMedia ||
 navigator.webkitGetUserMedia ||
 navigator.mozGetUserMedia ||
 navigator.msGetUserMedia
 this.init()
 },
 methods: {
 async init() {
 this.videoEl = this.$refs.videoDom
 this.canvasEL = this.$refs.canvasDOM
 await navigator.mediaDevices
 .getUserMedia(this.userMediaConstraints)
 .then(this.getMediaStreamSuccess)
 .catch(this.getMediaStreamError)
 await this.onPlay()
 },
 async onPlay() {
 debugHelper.log('onPlay')


 this.onTrackTracking()
 },
 changeView() {
 this.setTitle('刷脸登陆')
 this.setBackDisabled(false)
 this.setBackIcon('arrow_back')
 msgbus.vm.setBottomNavVisible(false)
 msgbus.vm.setBottomBtnVisible(false)
 msgbus.vm.setMsgInputVisible({ value: false })
 },


 onTrackTracking() {
 const context = this
 const video = this.videoEl
 const canvas = this.canvasEL
 const canvasContext = canvas.getContext('2d')
 let tracker = new tracking.ObjectTracker('face')


 video.pause()
 video.src = ''
 tracker.setInitialScale(4)
 tracker.setStepSize(2)
 tracker.setEdgesDensity(0.1)
 tracking.track('#video_cam', tracker, { camera: true })
 tracker.on('track', function(event) {
 const { autoCaptureTrackTraking } = context
 canvasContext.clearRect(0, 0, canvas.width, canvas.height)
 event.data.forEach(function({ x, y, width, height }) {
  canvasContext.strokeStyle = '#a64ceb'
  canvasContext.strokeRect(x, y, width, height)
  canvasContext.font = '11px Helvetica'
  canvasContext.fillStyle = '#fff'
 })


 if (!isEmpty(event.data) && context.count <= 10) {
  if (context.count < 0) context.count = 0
  context.count += 1
  //debugHelper.log(context.count)
  if (context.count > 10) {
  context.isdetected = '已检测到人脸,正在登录'
  //context.$router.push({ name: 'pwdlogin' })
  }
 } else {
  context.count -= 1
  if (context.count < 0) context.isdetected = '请您保持脸部在画面中央'
  //this.isdetected = '已检测到人脸,正在登录'
 }
 
 })
 },
 onDownloadFile(item) {
 const link = document.createElement('a')
 link.href = item
 link.download = `cahyo-${new Date().toISOString()}.png`
 link.click()


 link.remove()
 },
 onTakeCam() {
 const canvas = document.createElement('canvas')
 const video = this.$el.querySelector('#video_cam')
 const canvasContext = canvas.getContext('2d')


 if (video.videoWidth && video.videoHeight) {
 const isBiggerW = video.videoWidth > video.videoHeight
 const fixVidSize = isBiggerW ? video.videoHeight : video.videoWidth
 let offsetLeft = 0
 let offsetTop = 0


 if (isBiggerW) offsetLeft = (video.videoWidth - fixVidSize) / 2
 else offsetTop = (video.videoHeight - fixVidSize) / 2


 // make canvas size 300px
 canvas.width = canvas.height = 300
 const { width, height } = canvas


 canvasContext.drawImage(
  video,
  offsetLeft,
  offsetTop,
  fixVidSize,
  fixVidSize,
  0,
  0,
  width,
  height
 )
 const image = canvas.toDataURL('image/png')
 this.images.push(image)
 }
 },
 onDetectFace(param, index) {
 const imgItem = document.querySelector(`.img-item-${index}`)
 const image = new Image()
 image.src = param


 const tracker = new tracking.ObjectTracker('face')
 tracker.setStepSize(1.7)
 tracking.track(image, tracker)


 tracker.on('track', function(event) {
 event.data.forEach(function(rect) {
  window.plot(rect.x, rect.y, rect.width, rect.height)
 })
 })


 window.plot = function(x, y, w, h) {
 const rect = document.createElement('div')
 document.querySelector(`.img-item-${index}`).appendChild(rect)
 rect.classList.add('rect')
 rect.style.width = w + 'px'
 rect.style.height = h + 'px'
 rect.style.left = x + 'px'
 rect.style.top = y + 'px'
 rect.style.border = '2px solid yellow'
 rect.style.position = 'absolute'
 }
 },
 getMediaStreamSuccess(stream) {
 window.stream = stream // make stream available to browser console
 this.videoEl.srcObject = stream
 debugHelper.log('getMediaStreamSuccess1')
 //this.$store.commit('setVideoCanvasObject', this.videoEl)
 debugHelper.log('getMediaStreamSuccess2')
 },
 // 视频媒体流失败
 getMediaStreamError(error) {
 alert('视频媒体流获取错误' + error)
 },
 // 结束媒体流
 stopMediaStreamTrack() {
 clearInterval(this.timeInterval)
 if (typeof window.stream === 'object') {
 this.videoEl.srcObject = null
 //this.$store.commit('setVideoCanvasObject', '')
 window.stream.getTracks().forEach(track => track.stop())
 }
 },

总结

到此这篇关于Vue+tracking.js 实现前端人脸检测功能的文章就介绍到这了,更多相关vue tracking.js 人脸检测内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
不同浏览器的怪癖小结
Jul 11 Javascript
js函数setTimeout延迟执行的简单介绍
Jul 17 Javascript
jquery解析xml字符串示例分享
Mar 25 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
Mar 31 Javascript
javascript中scrollTop详解
Apr 13 Javascript
JS截取与分割字符串常用技巧总结
Nov 10 Javascript
关于Jquery中的事件绑定总结
Oct 26 Javascript
Javascript数组循环遍历之forEach详解
Nov 07 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
Jun 29 Javascript
requireJS模块化实现返回顶部功能的方法详解
Oct 16 Javascript
vue-property-decorator用法详解
Dec 12 Javascript
js 闭包深入理解与实例分析
Mar 19 Javascript
tracking.js实现前端人脸识别功能
Apr 16 #Javascript
electron 如何将任意资源打包的方法步骤
Apr 16 #Javascript
vue中keep-alive内置组件缓存的实例代码
Apr 16 #Javascript
详解Nuxt内导航栏的两种实现方式
Apr 16 #Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
Apr 16 #Javascript
vue下canvas裁剪图片实例讲解
Apr 16 #Javascript
javascript设计模式 ? 代理模式原理与用法实例分析
Apr 16 #Javascript
You might like
用php写的serv-u的web申请账号的程序
2006/10/09 PHP
一个改进的UBB类
2006/10/09 PHP
解析在PHP中使用mysqli扩展库对mysql的操作
2013/07/03 PHP
合格的PHP程序员必备技能
2015/11/13 PHP
配置Nginx+PHP的正确思路与过程
2016/05/10 PHP
javascript获取当前日期时间及其它操作函数
2011/01/11 Javascript
myFocus slide3D v1.1.0 使用方法与下载
2011/01/12 Javascript
初学Jquery插件制作 在SageCRM的查询屏幕隐藏部分行的功能
2011/12/26 Javascript
js写出遮罩层登陆框和对联广告并自动跟随滚动条滚动
2014/04/29 Javascript
js实现同一页面可多次调用的图片幻灯切换效果
2015/02/28 Javascript
jquery+css3实现网页背景花瓣随机飘落特效
2015/08/17 Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
2015/12/13 Javascript
JavaScript开发Chrome浏览器扩展程序UI的教程
2016/05/16 Javascript
JQuery异步提交表单与文件上传功能示例
2017/01/12 Javascript
基于js文件加载优化(详解)
2018/01/03 Javascript
vue项目中跳转到外部链接的实例讲解
2018/09/20 Javascript
解决vue-cli脚手架打包后vendor文件过大的问题
2018/09/27 Javascript
vue 路由懒加载中给 Webpack Chunks 命名的方法
2020/04/24 Javascript
低版本中Python除法运算小技巧
2015/04/05 Python
Python 基础教程之包和类的用法
2017/02/23 Python
python2.7安装图文教程
2018/03/13 Python
python 字典中文key处理,读取,比较方法
2018/07/06 Python
在Python中实现shuffle给列表洗牌
2018/11/08 Python
Pycharm 2020年最新激活码(亲测有效)
2020/09/18 Python
python自动脚本的pyautogui入门学习
2020/04/01 Python
Python基于pyjnius库实现访问java类
2020/07/31 Python
HTML5 Canvas实现玫瑰曲线和心形图案的代码实例
2014/04/10 HTML / CSS
Simons官方网站:加拿大时尚零售商
2020/02/20 全球购物
我的中国梦演讲稿600字
2014/08/19 职场文书
项目安全员岗位职责
2015/02/15 职场文书
学校捐款活动总结
2015/05/09 职场文书
2015年药品销售工作总结范文
2015/05/25 职场文书
银行文明优质服务培训心得体会
2016/01/09 职场文书
你离财务总监还有多远?速览CFO的岗位职责
2019/11/18 职场文书
Innodb存储引擎中的后台线程详解
2022/04/03 MySQL
在虚拟机中安装windows server 2008的图文教程
2022/06/28 Servers