安装依赖
开发face-api.js
最好使用ts来开发,可以省去很多查文档的时间,并且face-api是支持ts的
下载模型文件
在face-api.js
的github上下载代码包并将其中的w文件夹中的内容拷贝到自己的项目models
文件夹中
引入依赖
1
| import { detectSingleFace, FaceDetection, FaceLandmarks68, nets, TinyFaceDetectorOptions, WithFaceLandmarks } from 'face-api.js'
|
获取摄像头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| export class VideoController { private width: number private height: number private container: HTMLElement public videoElement: HTMLVideoElement constructor(width: number, height: number, container: HTMLElement = document.body) { this.videoElement = document.createElement('video') this.width = width this.height = height this.container = container } createVideo() { this.videoElement.width = this.width this.videoElement.height = this.height this.videoElement.autoplay = true this.videoElement.muted = true this.videoElement.controls = false this.videoElement.style.display = 'none' this.videoElement.style.position = 'absolute' this.videoElement.style.top = '0px' this.videoElement.style.left = '0px' this.videoElement.setAttribute('playsinline', 'playsinline') this.container.append(this.videoElement) } setSrc(url:string){ this.videoElement.src = url } async getCamera() { const mediaDevices = navigator.mediaDevices
console.log('开始获取摄像头数据') const stream = await mediaDevices.getUserMedia( { 'audio': false, 'video': { width: { ideal: this.height }, height: { ideal: this.width },
facingMode: { exact: 'user' } } } ).catch(err => { console.log('摄像头数据获取失败',err) })
if (stream) { console.log('获取到摄像头数据',stream.getTracks()) this.videoElement.srcObject = stream this.videoElement.play() this.videoElement.style.transform = 'rotateY(180deg)' this.videoElement.onloadedmetadata = () => { } } }
}
|
加载模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| Promise.all([ nets.tinyFaceDetector.loadFromUri('./static/model'), nets.faceLandmark68Net.loadFromUri('./static/model'), nets.faceRecognitionNet.loadFromUri('./static/model'), nets.faceExpressionNet.loadFromUri('./static/model'), ]).then(async () => { this.video = new VideoController(window.innerWidth, window.innerHeight, this.$window) this.video.createVideo() this.video.getCamera() this.video.videoElement.addEventListener('play', () => { setTimeout(() => { }, 1000) }) }).catch(err => { console.log('人脸识别数据加载失败', err) })
|
人脸识别
当获取到摄像头画面后,就可以进行人脸识别了
使用face-api下的detectSingleFace
函数可以得到人脸的基本数据(大小和位置),如果需要进一步判断年龄,表情等,需要使用对应的方法解析获得的detections
1 2 3 4 5 6 7 8
| const detections = await detectSingleFace( this.video.videoElement, new TinyFaceDetectorOptions() ) .withFaceLandmarks() .withFaceExpressions() .withFaceDescriptors() .withAgeAndGender()
|
最终会获得一个人脸数据的数组,数组内是多人的人脸数据,使用face-api
自带的drew方法可以绘制到canvas中。