vue2 tracking 人脸识别
名字被你们想完了 人气:0总是会有一些奇奇怪怪的需求无法避免。记录一下曾经项目遇到的一个需求。
需求
上传患者真实头像,可以有两种选择,一种是通过常规的文件选择方式上传,第二种方式就是医生可以调用电脑的摄像头拍一张然后上传。
分析
常规的就不用分析了,只分析第二种:
- 调用本地摄像头
- 然后可以进行拍照
- 因为是患者的真实头像,方便辨认,要求要拍到患者脸部
- 检测到患者脸部,自动截图,医生只需要点击上传即可
实现思路
首先看有不有能识别到患者脸部的前端第三方库,如果没有,这个需求就相对来说就麻烦一点,就是在拍照的时候需要医生辨别能否达到上传的要求,然后再拍照上传也行。
基于上面的思路,开始寻找,最后确定使用 tracking.js 它的 github 地址
使用 tracking.js
- 安装:
yarn add tracking
- 使用,用一个测试 demo 来展示:
src/components/TestFace.vue
<template> <div> <div> <p>请将摄像头对准患者脸部</p> <video id="video" style="transform:rotateY(180deg)" autoplay></video> </div> <div> <p>检测人脸结果</p> <canvas id="canvas" width="200" height="200" style="transform:rotateY(180deg)"></canvas> </div> </div> </template> <script> import { userMedia } from '../utils/utils' require('tracking/build/tracking-min.js') require('tracking/build/data/face-min.js') export default { data () { return { videoObj: null, trackerTask: null } }, mounted () { this.openCamera() }, methods: { openCamera () { // 有可能触发一些其他的按钮会重新获取 this.$nextTick(() => { const canvas = document.getElementById('canvas') const context = canvas.getContext('2d') this.videoObj = document.getElementById('video') // eslint-disable-next-line no-undef const tracker = new tracking.ObjectTracker('face') // 检测人脸 tracker.setInitialScale(4) tracker.setStepSize(2) tracker.setEdgesDensity(0.1) // eslint-disable-next-line no-undef this.trackerTask = tracking.track('#video', tracker, { camera: true }) const constraints = { video: { width: 200, height: 200 }, audio: false } userMedia(constraints, this.success, this.error) tracker.on('track', (event) => { event.data.forEach((rect) => { // 绘制到 canvas context.drawImage(this.videoObj, 0, 0, canvas.width, canvas.height) context.font = '16px Helvetica' context.strokeStyle = '#1890ff' context.strokeRect(rect.x, rect.y, rect.width, rect.height) }) if (event.data.length !== 0) { // 说明检测到人脸了,此时就可以截取图片传递给后端 // canvas 调用 toDataURL } }) }) }, handleCancel () { this.videoObj.srcObject.getTracks()[0].stop() this.trackerTask.stop() }, // 成功显示 success (stream) { this.videoObj.srcObject = stream this.videoObj.play() }, // 失败抛出错误,可能用户电脑没有摄像头,或者摄像头权限没有打开 error (error) { // 可以在这里面提示用户 console.log(`访问用户媒体设备失败${error.name}, ${error.message}`) } }, beforeDestroy () { this.handleCancel() } } </script>
src/utils/utils.js
export let userMedia = function (constraints, success, error) { if (navigator.mediaDevices.getUserMedia) { userMedia = function (constraints, success, error) { navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error) } } else if (navigator.webkitGetUserMedia) { userMedia = function (constraints, success, error) { navigator.webkitGetUserMedia(constraints, success, error) } } else if (navigator.mozGetUserMedia) { userMedia = function (constraints, success, error) { navigator.mozGetUserMedia(constraints, success, error) } } else if (navigator.getUserMedia) { userMedia = function (constraints, success, error) { navigator.getUserMedia(constraints, success, error) } } userMedia(constraints, success, error) }
最终的效果如下:
最后
首先确保有摄像头
有时候本地调试无法打开摄像头,可以在浏览器上输入:chrome://flags/#unsafely-treat-insecure-origin-as-secure
然后会出现如下页面,再操作即可:
加载全部内容