前端捕获人脸识别实践
source link: https://iiong.com/front-end-capture-face-recognition-practice/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
前端捕获人脸识别实践
公司有个项目涉及人脸识别,需要前端能力支持,需要用户进入摄像头后识别人脸进行截图,然后上传后端进行数据交换。不过目前主流摄像头支持调用,开源社区有个 trackingjs
类库问题解决计算机视觉解决方案。
trackingjs
很多工作量帮你做好,只需要引入他的库就可以用了:
<div class="app-container">
<video ref="videoRef" class="video-wrapper" preload autoplay loop muted />
<canvas ref="captureFaceRef" width="600" height="560" class="capture-face-wrapper" />
</div>
<div class="result-wrapper">
<h3>捕获到人脸数据:</h3>
<canvas ref="shortCutRef" class="short-cut-wrapper" />
</div>
想实现功能至少需要 videoRef
和 shortCutRef
节点,videoRef
主要是调用摄像头获取流媒体进行播放,而 shortCutRef
节点就是人脸截图,你可以拿到里面的图片进行提交,至于图片转 base64
数据流根据需求定吧。上面多一个 captureFaceRef
主要是捕获人脸的状态圈,告知用户捕获状态,而这个状态 trackingjs
事件回调里包含其中。
本项目是 vue3
项目,所以先初始化相关的业务:
const videoRef = ref(null)
const captureFaceRef = ref(null)
const shortCutRef = ref(null)
// 捕捉人脸坐标对象
const saveArray = {}
let captureFaceCanvas = null
let captureFaceContext = null
let shortCutRefCanvas = null
let shortCutRefContext = null
// tracking 实例化对象
let tracker = null
然后在 mounted
生命周期拿到 dom
节点信息和初始化 trackingjs
:
onMounted(() => {
captureFaceCanvas = captureFaceRef.value
shortCutRefCanvas = shortCutRef.value
captureFaceContext = captureFaceCanvas.getContext('2d')
shortCutRefContext = shortCutRefCanvas.getContext('2d')
initTracker()
captureFacePhoto(shortCutRefCanvas)
})
initTracker
方法要注意下声明 face
的模块,因为 trackingjs
机器学习模型很多,我这边只用到人脸,所以声明该模型:
const initTracker = () => {
// 实例化 face 模块
tracker = new window.tracking.ObjectTracker('face')
// 初始化抓取人脸边框配置
tracker.setInitialScale(4)
tracker.setStepSize(2)
tracker.setEdgesDensity(0.1)
// 摄像头开启
window.tracking.track(videoRef.value, tracker, {
camera: true
})
// 追踪事件回调
tracker.on('track', event => {
captureFaceContext.clearRect(0, 0, captureFaceCanvas.width, captureFaceCanvas.height)
event.data.forEach(function (rect) {
captureFaceContext.strokeStyle = 'red'
captureFaceContext.strokeRect(rect.x, rect.y, rect.width, rect.height)
captureFaceContext.fillStyle = 'red'
saveArray.x = rect.x
saveArray.y = rect.y
saveArray.width = rect.width
saveArray.height = rect.height
})
})
}
上面就是根据配置进行个性化配置,具体可以查阅官方文档。
然后制作截图功能:
const captureFacePhoto = canvas => {
// 将video对象内指定的区域捕捉绘制到画布上指定的区域,实现拍照
shortCutRefContext.drawImage(videoRef.value, 140, 70, 340, 340, 0, 0, 140, 140)
const getImage = canvas.toDataURL('image/png')
console.log(getImage)
}
至此为止基本功能已经实现了,不过在人脸识别过程中,却发现人脸识别经常失误,比如识别到侧边脸以及截图文件不完整。
const bestCaptureTimer = () => {
if (saveArray.x > 130 &&
saveArray.x + saveArray.width < 460 &&
saveArray.y > 58 &&
saveArray.y + saveArray.height < 388 &&
saveArray.width < 330 &&
saveArray.height < 330) {
captureFacePhoto(shortCutRefCanvas)
for (const key in saveArray) {
delete saveArray[key]
}
}
}
这个定时器让用户在画布中央进行截图,提高人脸识别率。
对于需要检验摄像头设备完全可以用浏览器的 api 实现:
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {}
}
// 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
// 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = constraints => {
// 首先,如果有getUserMedia的话,就获得它
const getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia
// 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
}
// 否则,为老的navigator.getUserMedia方法包裹一个Promise
return new Promise((resolve, reject) => {
getUserMedia.call(navigator, constraints, resolve, reject)
})
}
}
navigator.mediaDevices.getUserMedia({ video: true }).then(() => {
// 人脸识别业务初始化
const tracker = new window.tracking.ObjectTracker('face')
// 一些业务...
}).catch(err => {
console.warn(err.name + ": " + err.message)
ElMessage.error({
message: '没有检验到摄像头,请插入摄像头设备!',
showClose: true,
duration: 0
})
})
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK