UNPKG

face-guard

Version:

前端轻量级人脸识别与图像采集工具,基于 face-api.js 封装,支持自动检测、用户引导和 Base64 图像输出。

88 lines (87 loc) 2.94 kB
import * as e from "face-api.js"; class a { constructor(t) { this.modelPath = t.modelPath || "/models", this.videoElement = null, this.recognitionInterval = null, this.onError = t.onError || console.error, this.onFaceDetected = t.onFaceDetected || (() => { }), this.stream = null, this.onFeedback = t.onFeedback || (() => { }); } /** * 模型处理 */ async loadModels() { try { await e.nets.tinyFaceDetector.loadFromUri(this.modelPath), await e.nets.faceLandmark68Net.loadFromUri(this.modelPath), await e.nets.faceRecognitionNet.loadFromUri(this.modelPath), console.log("模型加载完成"); } catch (t) { throw this.onError("模型加载失败: " + t.message), t; } } /** * 检测视频元素 开启视频采集 * @param {视频元素} videoElement */ async start(t) { if (!t) throw new Error("必须传入 video 元素"); this.videoElement = t; try { await this.loadModels(), await this.startVideo(); } catch (i) { this.onError(i); } } /** * 视频采集 */ async startVideo() { try { const t = await navigator.mediaDevices.getUserMedia({ video: {} }); this.videoElement.srcObject = t, this.stream = t, this.videoElement.play(), setTimeout(() => { this.startRecognition(); }, 1e3); } catch (t) { this.onError("无法访问摄像头: " + t.message); } } /** * 人脸识别(循环识别) */ startRecognition() { this.recognitionInterval = setInterval(async () => { const t = await e.detectAllFaces(this.videoElement, new e.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceDescriptors(); if (t.length > 0) { const i = t[0].alignedRect.score; if (i > 0.9) { const o = this.getBase64Image(); this.onFaceDetected(o), this.stop(); } else { const o = this.getUserFeedback(i); this.onFeedback?.(o); } } else this.onFeedback?.("未检测到人脸,请调整位置"); }, 100); } /** * 获取采集信息 * @returns 返回base64编码的图片 */ getBase64Image() { const t = document.createElement("canvas"); return t.width = this.videoElement.videoWidth, t.height = this.videoElement.videoHeight, t.getContext("2d").drawImage(this.videoElement, 0, 0, t.width, t.height), t.toDataURL("image/png"); } /** * 提示信息 * @param {*} score * @returns */ getUserFeedback(t) { return t < 0.5 ? "请向前移动" : t < 0.7 ? "请向左或右移动" : "请稍微调整位置"; } stop() { this.recognitionInterval && (clearInterval(this.recognitionInterval), this.recognitionInterval = null), this.stream && (this.stream.getTracks().forEach((t) => t.stop()), this.stream = null), this.videoElement && (this.videoElement.srcObject = null); } } export { a as default }; //# sourceMappingURL=face-guard.es.js.map