// 引入face.js
|
import * as faceapi from 'face-api.js';
|
import { reject } from 'lodash-es';
|
import { resolve } from 'path';
|
// 创建初始化标记,防止重复初始化
|
let isModelsLoaded = false;
|
// 类型定义
|
type DetectionResult = {
|
hasFace: boolean;
|
error?: string;
|
};
|
|
/**
|
* 人脸检测方法封装
|
* @param imageUrls 要检测的图片路径数组
|
* @param options 人脸检测配置项
|
* @returns Promise<boolean> 检测到任意人脸立即返回true,全部无脸返回false
|
*/
|
export const useFaceDetection = () => {
|
// 加载本地模型
|
const loadModels = async () => {
|
if (!isModelsLoaded) {
|
await faceapi.loadSsdMobilenetv1Model("/models/ssd_mobilenetv1")
|
await faceapi.loadFaceLandmarkModel('/models/face_landmark_68')
|
await faceapi.loadFaceLandmarkTinyModel('/models/face_landmark_68_tiny')
|
isModelsLoaded = true
|
}
|
}
|
|
// 整体检测方法
|
const detectFacesInImages = async (
|
imageUrls: string[]
|
): Promise<boolean> => {
|
try {
|
await loadModels();
|
for (const url of imageUrls) {
|
try {
|
const result = await processSingleImage(url)
|
if (result.hasFace) return true; //有人脸
|
} catch (error) {
|
console.log(`图片检测失败:${url}`, error)
|
continue;
|
}
|
}
|
return false;
|
} catch (error) {
|
console.log('人脸初始化失败', error)
|
return false;
|
}
|
}
|
|
|
// 单个图片处理
|
const processSingleImage = (url: string): Promise<DetectionResult> => {
|
return new Promise((resolve, reject) => {
|
const img = new Image();
|
img.src = url
|
img.crossOrigin = "anonymous"; // 修正拼写错误
|
img.onload = async () => {
|
console.log("load")
|
try {
|
const FaceImg = faceapi.detectAllFaces(img).withFaceLandmarks();
|
resolve({ hasFace: (await FaceImg).length > 0 });
|
} catch (error) {
|
reject(error);
|
}
|
};
|
img.onerror = (error) => {
|
console.log(`图片加载失败:${url}`);
|
console.log(error);
|
resolve({
|
hasFace: false,
|
error: `图片加载失败:${url}`,
|
});
|
};
|
});
|
};
|
|
return { detectFacesInImages }
|
|
}
|