face-guard
Version:
前端轻量级人脸识别与图像采集工具,基于 face-api.js 封装,支持自动检测、用户引导和 Base64 图像输出。
88 lines (87 loc) • 2.94 kB
JavaScript
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