vladmandic / face-api

FaceAPI: AI-powered Face Detection & Rotation Tracking, Face Description & Recognition, Age & Gender & Emotion Prediction for Browser and NodeJS using TensorFlow/JS
https://vladmandic.github.io/face-api/demo/webcam.html
MIT License
853 stars 155 forks source link

LabeledFaceDescriptors - constructor expected descriptors to be an array of Float32Array #116

Closed maheraldous closed 2 years ago

maheraldous commented 2 years ago

Hello I had my issue in the orginal project but it seems no one is ansewring so I hope you do https://github.com/justadudewhohacks/face-api.js/issues/872#issue-1338322523

vladmandic commented 2 years ago

please fill actual issue using provided template if you want me to take a look at it
& note which face-api you're using & post full code and notes what is it what

posting link to incomplete information is really not helpful

but just taking a quick look

i have no idea how you entered it in database to start with, but thats where NaN values are, so everything fails when you try to convert it to Float32Array.

maheraldous commented 2 years ago

Yes convert to Float32Array is the problem.

What I am trying to do is that I have 2 images both are in the server but number 1 I already detected all the faces in it and saved them with all the information like expression and gender and label in the database so the imsge number 2 is in that code where I am trying to detect the faces and create information then call the image number information from the database by using var faces = await db.models.faceidModel.findAll(); actually I am calling all not just the image number 1 but this is not the problem since I will loop in every image.

The image number 2 when I call it to put it in the detection later I use var canvasImage = await loadImage(fileObject.path); to load it by it's path then detect the faces in it then call the image number 1 information then compare it to the image number 2.

vladmandic commented 2 years ago

you still have not provided any environment and/or version info - please fill the template or i'll have to close the issue.

second, simplify the issue as much as possible. database is not relevant here, face matcher is not relevant.

only thing relevant is how did you get invalid face descriptor in the first place - can you reproduce that?
if you cant, empty database and validate each record before you store in database - identify which records are invalid BEFORE you store them. and why is your type object to start with? face-api returns Float32Array as result directly.

vladmandic commented 2 years ago

any updates?

maheraldous commented 2 years ago

I got the match to work and here is my test code and it worked and Thank you for telling me the the face-api returns Float32Array by default and that was my problem that I didn't know that.

        try {
            const user = await db.models.userModel.findOne({ where: { id: context.userAuth.id } });
            const userId = await user.id;
            if (isEmpty(user)) {
               return Error(`Sorry, we can't find you.`);
            }

            var imgPath1 = `${dirname('')}/media/usersfiles/${userId}/faceid/dwayne-the-rock-.jpg`
            var imgPath2 = `${dirname('')}/media/usersfiles/${userId}/faceid/the-rock-youtube.jpg`
            var imgPath3 = `${dirname('')}/media/usersfiles/${userId}/faceid/download.jpg`

            // FaceID
            // const canvasImage = await loadImage("https://nmaahc.si.edu/sites/default/files/styles/max_1300x1300/public/images/header/audience-citizen_0.jpg?itok=unjNTfkP");
            var canvasImage1 = await loadImage(imgPath1);
            var canvasImage2 = await loadImage(imgPath2);
            var canvasImage3 = await loadImage(imgPath3);

            // Read each face and save the face descriptions in the descriptions array
            // There is one face in every image
            const detectFaces1 = await faceapi.detectAllFaces(canvasImage1).withFaceLandmarks().withFaceExpressions().withAgeAndGender().withFaceDescriptors();
            const detectFaces2 = await faceapi.detectAllFaces(canvasImage2).withFaceLandmarks().withFaceExpressions().withAgeAndGender().withFaceDescriptors();
            const detectFaces3 = await faceapi.detectAllFaces(canvasImage3).withFaceLandmarks().withFaceExpressions().withAgeAndGender().withFaceDescriptors();

            var person1 = {
                id: '1',
                label: 'Dwayne',
                descriptor: [detectFaces1[0].descriptor]
            }

            var person2 = {
                id: '1',
                label: 'Dwayne',
                descriptor: [detectFaces2[0].descriptor]
            }

            var person3 = {
                id: '2',
                label: 'Person',
                descriptor: [detectFaces3[0].descriptor]
            }

            var persons = [
                person1,
                person2,
                person3
            ]

            var theCurrentUser = {
                id: userId,
                label: 'Dwayne',
                descriptions: []
            }

            var getAllCurrentUserDescriptors = persons.filter(item => {
                if (item.id === '1') {
                    theCurrentUser.descriptions.push(item.descriptor[0]);
                }
            });
            console.log('getAllCurrentUserDescriptors: ', getAllCurrentUserDescriptors);
            console.log('theCurrentUser: ', theCurrentUser.descriptions);

            // For FaceMatcher
            const labeledDescriptors = [];

            labeledDescriptors.push(new faceapi.LabeledFaceDescriptors(theCurrentUser.label, theCurrentUser.descriptions));
            labeledDescriptors.push(new faceapi.LabeledFaceDescriptors(person3.label, person3.descriptor));

            // Load face matcher to find the matching face
            console.log('labeledDescriptors: ', labeledDescriptors);
            const faceMatcher = new faceapi.FaceMatcher(labeledDescriptors, 0.6);
            console.log('faceMatcher: ', faceMatcher);

            // Find matching faces
            var displaySize = { width: canvasImage1.width, height: canvasImage1.height };
            var personToCompare = detectFaces1;
            const resizedDetections = faceapi.resizeResults(personToCompare, displaySize);
            console.log('resizedDetections: ', resizedDetections);

            const results = resizedDetections.map((d) => faceMatcher.findBestMatch(d.descriptor));
            console.log('results: ', results);

            return {
                response: 'Thank you',
                status: true
            };
        } catch (error) {
            throw Error(`${info.path.key}: ${error.message}`);
        }