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 相关文章推荐
同域jQuery(跨)iframe操作DOM(示例代码)
Dec 13 Javascript
JS实现OCX控件的事件响应示例
Sep 17 Javascript
HTML,CSS,JavaScript速查表推荐
Dec 02 Javascript
JavaScript中的Web worker多线程API研究
Dec 06 Javascript
jquery使用remove()方法删除指定class子元素
Mar 26 Javascript
原生js实现addclass,removeclass,toggleclasss实例
Nov 24 Javascript
Javascript自定义事件详解
Jan 13 Javascript
微信小程序按钮去除边框线分享页面功能
Aug 27 Javascript
JavaScript实现图片放大镜效果
Jun 27 Javascript
小谈angular ng deploy的实现
Apr 07 Javascript
jQuery实现评论模块
Aug 19 jQuery
解决VantUI popup 弹窗不弹出或无蒙层的问题
Nov 03 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下打开phpMyAdmin出现403错误的问题解决方法
2013/05/23 PHP
JS提交并解析后台返回的XML的代码
2008/11/03 Javascript
extjs grid设置某列背景颜色和字体颜色的方法
2010/09/03 Javascript
Extjs gridpanel 出现横向滚动条问题的解决方法
2011/07/04 Javascript
jQuery ajax dataType值为text json探索分享
2013/09/23 Javascript
window.open 以post方式传递参数示例代码
2014/02/27 Javascript
js中取得变量绝对值的方法
2015/01/03 Javascript
推荐一款jQuery插件模板
2015/01/09 Javascript
javascript折半查找详解
2015/01/26 Javascript
Nodejs抓取html页面内容(推荐)
2016/08/11 NodeJs
解析javascript图片懒加载与预加载的分析总结
2016/10/27 Javascript
EditPlus中的正则表达式 实战(2)
2016/12/15 Javascript
JS实现图片点击后出现模态框效果
2017/05/03 Javascript
js 简易版滚动条实例(适用于移动端H5开发)
2017/06/26 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
2017/08/20 Javascript
什么是Vue.js框架 为什么选择它?
2017/10/17 Javascript
基于mpvue的小程序项目搭建的步骤
2018/05/22 Javascript
小试SVG之新手小白入门教程
2019/01/08 Javascript
JavaScript事件委托实现原理及优点进行
2020/08/29 Javascript
三剑客:offset、client和scroll还傻傻分不清?
2020/12/04 Javascript
vue集成一个支持图片缩放拖拽的富文本编辑器
2021/01/29 Vue.js
python实现归并排序算法
2018/11/22 Python
对python遍历文件夹中的所有jpg文件的实例详解
2018/12/08 Python
python 字典的打印实现
2019/09/26 Python
python之pymysql模块简单应用示例代码
2019/12/16 Python
使用Python操作ArangoDB的方法步骤
2020/02/02 Python
django 连接数据库出现1045错误的解决方式
2020/05/14 Python
CSS3中Animation动画属性用法详解
2016/07/04 HTML / CSS
婚礼证婚人证婚词
2014/01/08 职场文书
年会搞笑主持词
2014/03/27 职场文书
司机工作自我鉴定
2014/09/19 职场文书
学校纪律作风整改措施思想汇报
2014/10/11 职场文书
2014年应急管理工作总结
2014/11/26 职场文书
士兵突击观后感
2015/06/16 职场文书
使用SQL实现车流量的计算的示例代码
2022/02/28 SQL Server
Win11应用商店打开闪退怎么解决? win11应用商店打不开的多种解决办法
2022/04/05 数码科技