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 相关文章推荐
Javascript 读后台cookie代码
Sep 15 Javascript
什么是DOM(Document Object Model)文档对象模型
Mar 05 Javascript
uploadify 3.0 详细使用说明
Jun 18 Javascript
javascript中的循环语句for语句深入理解
Apr 04 Javascript
JS实现鼠标经过好友列表中的好友头像时显示资料卡的效果
Jul 02 Javascript
浅析jQuery EasyUI中的tree使用指南
Dec 18 Javascript
JQuery右键菜单插件ContextMenu使用指南
Dec 19 Javascript
javascript 数组操作详解
Jan 29 Javascript
EasyUI加载完Html内容样式渲染完成后显示
Jul 25 Javascript
解决Vue 通过下表修改数组,页面不渲染的问题
Mar 08 Javascript
vue在手机中通过本机IP地址访问webApp的方法
Aug 15 Javascript
vue 父组件通过v-model接收子组件的值的代码
Oct 27 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
星际争霸 Starcraft 游戏介绍
2020/03/14 星际争霸
PHP应用JSON技巧讲解
2013/02/03 PHP
PHP中的正则表达式实例详解
2017/04/25 PHP
ThinkPHP5框架缓存查询操作分析
2018/05/30 PHP
PDO::beginTransaction讲解
2019/01/27 PHP
实现checkbox全选、反选、取消JavaScript小脚本异常
2014/04/10 Javascript
Jquery焦点与失去焦点示例应用
2014/06/10 Javascript
火狐下input焦点无法重复获取问题的解决方法
2014/06/16 Javascript
前端轻量级MVC框架CanJS详解
2014/09/26 Javascript
探讨js字符串数组拼接的性能问题
2014/10/11 Javascript
node.js中的path.sep方法使用说明
2014/12/08 Javascript
jQuery中的pushStack实现原理和应用实例
2015/02/03 Javascript
JS实现定时自动关闭DIV层提示框的方法
2015/05/11 Javascript
javascript绘制漂亮的心型线效果完整实例
2016/02/02 Javascript
JavaScript:Date类型全面解析
2016/05/19 Javascript
详解webpack提取第三方库的正确姿势
2017/12/22 Javascript
自定义vue组件发布到npm的方法
2018/05/09 Javascript
echarts实现地图定时切换散点与多图表级联联动详解
2018/08/07 Javascript
Jquery实现无缝向上循环滚动列表的特效
2019/02/13 jQuery
layui表格 返回的数据状态异常的解决方法
2019/09/10 Javascript
原生JS封装拖动验证滑块的实现代码示例
2020/06/01 Javascript
Python分支结构(switch)操作简介
2018/01/17 Python
python使用epoll实现服务端的方法
2018/10/16 Python
Python3 使用cookiejar管理cookie的方法
2018/12/28 Python
详解Python 函数如何重载?
2019/04/23 Python
python3使用腾讯企业邮箱发送邮件的实例
2019/06/28 Python
Django自关联实现多级联动查询实例
2020/05/19 Python
python如何建立全零数组
2020/07/19 Python
澳洲女装时尚在线:Blue Bungalow
2018/05/05 全球购物
Ashford台湾:以折扣价提供奢华的男女用表款
2019/12/04 全球购物
2014年会演讲稿范文
2014/01/06 职场文书
个人授权委托书
2014/04/03 职场文书
2014幼儿园大班工作总结
2014/11/10 职场文书
学前教育见习总结
2015/06/23 职场文书
优秀教师工作总结2015
2015/07/22 职场文书
Python实战实现爬取天气数据并完成可视化分析详解
2022/06/16 Python