我正在尝试创建一个应用程序,可以为您拍摄一张好照片,值得分析您的皮肤。 我有3个主要条件:
该功能仅可通过浏览器在移动设备上使用(不适用于移动应用程序)。
当我运行 detectorFace 函数时,我遇到了这个奇怪的错误:
Box.constructor - expected box to be IBoundingBox | IRect, instead have {"x": null, "y": null, "width": null, "height": null}
奇怪的是,只有当我使用 TinyFaceDetector 时才会发生这种情况,这就是我使用它的方式:
useEffect(() => {
const loadModel = async () => {
try {
await Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri("/models"),
faceapi.nets.faceLandmark68TinyNet.loadFromUri("/models"),
]);
initializeCamera();
setIsModelLoaded(true);
} catch (error) {
console.error("Error loading models:", error);
}
};
const detectFace = async () => {
if (isModelLoaded && webcamRef.current) {
const video = webcamRef.current.video as HTMLVideoElement;
const detections = await faceapi
.detectAllFaces(
video,
new faceapi.TinyFaceDetectorOptions({
scoreThreshold: 0.1,
inputSize: 128,
})
)
.withFaceLandmarks(true);
if (detections.length > 0) {
const minX = 0;
const maxX = 75;
const minY = 165;
const maxY = 230;
if (
detections[0].detection.box.x !== null &&
detections[0].detection.box.x >= minX &&
detections[0].detection.box.x <= maxX &&
detections[0].detection.box.y >= minY &&
detections[0].detection.box.y <= maxY
) {
setIsFaceInShape(true);
} else {
setIsFaceInShape(false);
}
const brightness = await calculateAverageBrightness(video);
if (brightness < 150) {
setIsLightGood(true);
} else {
setIsLightGood(false);
}
}
}
};
loadModel();
const intervalId = setInterval(detectFace, 200);
return () => {
clearInterval(intervalId);
};
}, [isModelLoaded]);
useEffect(() => {
if (isFaceInShape && isLightGood) {
capture();
}
}, [isFaceInShape, isLightGood]);
奇怪的是,当功能捕获完成时,我在屏幕上看到错误,但在后台我可以看到完美拍摄的图像,并且捕获中的其余逻辑运行良好,这意味着错误不会发生不做任何事情,它不会阻止应用程序工作,它来自哪里?
我尝试过的: 我注意到,当我降低超时间隔时,错误发生的频率会降低,但我需要它快速扫描,以便应用程序按预期工作。
什么有效: 当我使用 ssdMobilenetv1 时,它可以正常工作,没有任何错误,但它是一个非常重的模型,特别是对于移动设备而言,并且相机开始滞后很多,因为它每 0.2 秒进行一次大型扫描。该错误主要发生在我尝试使用的 TinyFaceDetector 上,因为对于移动设备来说,它工作得很好,但我需要 withFaceLandmarks 属性。
如果您需要我的应用程序中的更多代码,请告诉我。
在尝试使用模型进行人脸检测之前,请确保模型已完全加载并初始化。我认为你的 loadModel 函数应该是这样的:
const loadModel = async () => {
try {
await Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri("/models"),
faceapi.nets.faceLandmark68TinyNet.loadFromUri("/models"),
]).then(function(){
initializeCamera();
setIsModelLoaded(true);
});
} catch (error) {
console.error("Error loading models:", error);
}
};