I'm trying to make the app for face detection. But despite loading models. I'm getting the error "SsdMobilenetv1 - load model before inference" I'm sending the Front End HTML File from the server. and on the client front end I'm trying to do the face detection. I would be very very grateful for your kind response. Regards!!!
This is my express server
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")
})
This is the script file on front end 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) })
Because of low reputation, i can't post the image directly but here is the link to my folder structure
I believe that only two parts in your client-side script are relevant for this issue, so let's focus on those:
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) })
so, we've got a Promise.all
at the top which schedules execution of 3 functions, ssdMobilenetv1
among them, which is obligatory to call prior to calling faceapi.detectSingleFace
. But, the problem is, these 3 functions from within Promise.all
will be executed asynchronously, while main thread will go forward and try to invoke faceapi.detectSingleFace
, even though ssdMobilenetv1
is still going on.
Simplest solution would be to put detectSingleFace
to the success callback of 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)
});
Because inside the callback, you can be sure that faceapi.nets.ssdMobilenetv1
is done.