因为业务需求需要识别用户上传的图片是否是显示的完整人脸(五官都是在图片上的),但是又不想使用其他平台的一些开放接口的,可以参考使用face.js实现。
第一步下载faceapi.js
npm install face-api.js
第二步下载model文件
model文件需要在github上的faceapi仓库中下载, 找到weights文件夹进行下载
https://github.com/justadudewhohacks/face-api.js/tree/master
将下载好的model文件可以放置在你项目的目录下,我是放在public文件下
第三步 在你需要的目录下下导入faceapi.js文件
import * as faceapi from "face-api.js";
然后在页面初始化模型
async init() {
const modelsPath = "/weights";
// 加载模型
await faceapi.nets.ssdMobilenetv1.loadFromUri(modelsPath);
await faceapi.nets.faceLandmark68Net.loadFromUri(modelsPath);
await faceapi.nets.faceRecognitionNet.loadFromUri(modelsPath);
}
最后在你需要进行人脸识别的逻辑处理位置,加上以下代码 (我这里的图片是base64格式, 如果是别的格式的话可以参考 faceapi的接口进行替换)
let var = "base64格式";
const byteCharacters = atob(val.replace(/^data:image\/\w+;base64,/, ""));
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: "image/jpeg" });
const img = await faceapi.bufferToImage(blob);
// 进行人脸检测
const detection = await faceapi.detectSingleFace(img).withFaceLandmarks();
if (detection) {
// 存在检测到的人脸
const detections = await faceapi.detectAllFaces(img).withFaceLandmarks();
detections.forEach((element) => {
const { landmarks } = element;
const leftEye = landmarks.getLeftEye()[0];
const rightEye = landmarks.getRightEye()[3];
const mouth = landmarks.getMouth();
const imageWidth = img.width;
const imageHeight = img.height;
if (
(leftEye.x < imageWidth / 3 && rightEye.x < imageWidth / 3) || // 左右眼位于图像左侧
(leftEye.x > (2 * imageWidth) / 3 && rightEye.x > (2 * imageWidth) / 3) || // 左右眼位于图像右侧
(mouth[0].y < imageHeight / 3 && mouth[6].y < imageHeight / 3) || // 嘴巴位于图像上方
(mouth[0].y > (2 * imageHeight) / 3 && mouth[6].y > (2 * imageHeight) / 3) // 嘴巴位于图像下方
) {
console.log("半张人脸");
return;
} else {
console.log("完整人脸");
}
});
} else {
// 未检测到人脸
console.log("图片不包含人脸");
return;
}