Не удается загрузить модели для face-api.js несмотря на вывод моделей

#javascript #node.js #express #face-api

#javascript #node.js #выразить #face-api

Вопрос:

Я пытаюсь создать приложение для распознавания лиц. Но, несмотря на загрузку моделей. Я получаю сообщение об ошибке «SsdMobilenetv1 — загрузить модель перед выводом» Я отправляю HTML-файл интерфейса с сервера. и во внешнем интерфейсе клиента я пытаюсь выполнить распознавание лиц. Я был бы очень, очень благодарен за ваш любезный ответ. С уважением!!!

Это мой экспресс-сервер

Index.js

 const express = require("express")
const path = require('path')
const app = express()
const hbs = require("hbs")


const publicFolder = path.join(__dirname, '../public')
const viewsPath = path.join(__dirname, "../views")

app.use(express.static(publicFolder));


app.set("view engine", "hbs");
app.set("views", viewsPath);

app.get('/', (req, res) => {
    res.render('index.hbs')
})

app.listen(7000, () => {
    console.log("Listening On port")
})
  

Это файл скрипта во внешнем интерфейсе face.js

 const MODEL_URL = "/weights";
Promise.all([
    faceapi.nets.ssdMobilenetv1.loadFromUri(MODEL_URL),
    faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
    faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
]).then((val) => {
    // console here gives an array of undefined
    console.log(val)
}).catch((err) => {
    console.log(err)
})

const img = document.getElementById('img')
const inputField = document.getElementById('imgUpload')
const canvas = document.getElementById('canvas')

const inputChangeListner = function (e) {
    var selectedFile = e.target.files[0];
    var reader = new FileReader();

    img.title = selectedFile.name;

    reader.onload = function (event) {
        console.log(event)
        img.src = event.target.result;
    };

    reader.readAsDataURL(selectedFile);
}
inputField.onchange = inputChangeListner


faceapi.detectSingleFace(img).then((value) => {
 console.log(value)
}).catch((err) => { console.log(err) })
  

Из-за низкой репутации я не могу опубликовать изображение напрямую, но вот ссылка на мою структуру папок

https://i.imgur.com/pJqU848.png

Ответ №1:

Я считаю, что только две части в вашем клиентском скрипте имеют отношение к этой проблеме, поэтому давайте сосредоточимся на них:

 const MODEL_URL = "/weights";
Promise.all([
    faceapi.nets.ssdMobilenetv1.loadFromUri(MODEL_URL),
    faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
    faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
]).then((val) => {
    // console here gives an array of undefined
    console.log(val)
}).catch((err) => {
    console.log(err)
})

// ...

faceapi.detectSingleFace(img).then((value) => {
 console.log(value)
}).catch((err) => { console.log(err) })
  

итак, у нас есть Promise.all вверху, который планирует выполнение 3 функций, ssdMobilenetv1 среди них, которая является обязательной для вызова перед вызовом faceapi.detectSingleFace . Но проблема в том, что эти 3 функции изнутри Promise.all будут выполняться асинхронно, в то время как основной поток будет продвигаться вперед и пытаться вызвать faceapi.detectSingleFace , хотя ssdMobilenetv1 это все еще продолжается.

Самым простым решением было бы поставить detectSingleFace на успешный обратный вызов Promise.all :

 const MODEL_URL = "/weights";
Promise.all([
    faceapi.nets.ssdMobilenetv1.loadFromUri(MODEL_URL),
    faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
    faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
]).then((val) => {
    // console here gives an array of undefined
    console.log(val);
    faceapi.detectSingleFace(img).then((value) => {
     console.log(value)
    }).catch((err) => { console.log(err) });
}).catch((err) => {
    console.log(err)
});
  

Потому что внутри обратного вызова вы можете быть уверены, что faceapi.nets.ssdMobilenetv1 это сделано.

Комментарии:

1. Это сработало!!! Я благодарен. Это должно было быть очевидно из-за асинхронной природы. detectSingleFace был запущен перед загрузкой SsdMobilenetv1. Действительно ценю вашу помощь