justadudewhohacks / face-api.js

JavaScript API for face detection and face recognition in the browser and nodejs with tensorflow.js
MIT License
16.69k stars 3.71k forks source link

External image sources #45

Closed ingalou closed 6 years ago

ingalou commented 6 years ago

Hi, First of all thank you for your work, it's excellent and very simple to use.

I have a small problem, when I use the face recognition, the api doesn't seem to work with external image sources. I would like to work with a data base and I'm receiving this error message :

"Failed to execute 'texImage2D' on 'WebGL2RenderingContext': Tainted canvases may not be loaded."

Do you know how can I overcome this problem ?

justadudewhohacks commented 6 years ago

Hmm, can you show some example code of what you are doing? The error message indicates that whatever you are trying to pass into the net is either not a tensor or a valid media element or the media content is not loaded yet.

ingalou commented 6 years ago

html :

<div class="footballer_images_container">
     <img class="it_will_work_for_this_image" src="public/amy1.png" alt="">
     <img class="it_will_not_work_for_this_image" src="https://upload.wikimedia.org/wikipedia/commons/e/e4/Karim_Benzema_2018.jpg" alt="">   
</div>

js

const $imgToCompare = footballerImageContainer.querySelectorAll("img")

//compare image
const compareImage = async ()=>{

    //load models
    await faceapi.loadModels(MODEL_URL)

    //vector the custom image 
    const descriptor1 = await faceapi.computeFaceDescriptor($customImage)

   //compare all the images to the custom image
    $imgToCompare.forEach(img => {
        //compare both image
        faceSimilarities(img, descriptor1)  
    });
}

//compare faces
const faceSimilarities = async (image, descriptor1)=>{

    //vector the images to compare
    const descriptor2 = await faceapi.computeFaceDescriptor(image)

    //compare the ressemblance of the faces
    const distance = faceapi.euclideanDistance(descriptor1, descriptor2)

    //transform the distance in %
    const similarityPercentage = Math.round(((1 - distance) * 100) * 100) / 100 
    // console.log(similarityPercentage + "%") 

    //put the value in the array
    imgScore.push(similarityPercentage)

    //if it's the last image
    if($imgToCompare[$imgToCompare.length - 1] === image){
        compareScore()

    }
}

So this will calculate the euclidian distance between a custom image, and all the image in the "footballer_images_container" div. When it's finished, it will pick the image with the most similarities with the function compareScore().

The problem is it will work for "public/amy1.png" because the source is in local but not for "https://upload.wikimedia.org/wikipedia/commons/e/e4/Karim_Benzema_2018.jpg" because the source is external.

I hope i'm clear.

seranus commented 6 years ago

You may get blocked by the browser because of the CORS on the external site

justadudewhohacks commented 6 years ago

Yeah @seranus is right, that simply wont work. Look at the example how I implemented external images fetching, I proxy the request via an express server

ingalou commented 6 years ago

Ok thank you !

sathyarr commented 5 years ago

Facing similar problem for External Video sources. any idea?

bettysteger commented 3 years ago

@sathyamoorthyrr have you found a solution for videos?

Igorgomes98 commented 3 years ago

@lpsBetty have you found solution, any idea? I'm have same problem

sathyarr commented 3 years ago

@sathyamoorthyrr have you found a solution for videos?

@lpsBetty

I think I got settled with an internal video, as per this, https://github.com/sathyarr/video-face-emotion-detection-analysis/blob/master/README.md#how-to-run

I have lost the context altogether. been so long worked on this.

bettysteger commented 3 years ago

@IgorGomesFATEC yes it worked with the "newer" npm package: https://www.npmjs.com/package/@vladmandic/face-api

Hirsau commented 2 years ago

I am facing a similar issue. My images are local to the computer. If I load them like this: img src='/images/test.jpg' everything works correctly. However, if I retrieved them from a server I have running locally: img src='http://localhost:9000/test.jpg'

I get the exact same error message: DOMException: Failed to execute 'texImage2D' on 'WebGL2RenderingContext': Tainted canvases may not be loaded.

I don't understand this, since both approaches are successful in loading the image, and in both cases, I am not accessing the image until after the 'load' event is thrown. Don't both result in exactly the same image data being loaded into the element?