justadudewhohacks / face-api.js

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

"Blob is not defined" fetching local images #194

Open enecumene opened 5 years ago

enecumene commented 5 years ago

Hi, i testing face-api.js and trying loading a local image for make face similarity and is throw me "Blob is not defined" in my nodeJS application, here the function where i try computing descriptors:

face.env.monkeyPatch({ fetch, Blob });

const threshold = 0.6;
var descriptors = { desc1: null, desc2: null };

function computarDescriptor(aDesc, aUri) {
  // ~statics/pics/001_tmp.jpg
  face.fetchImage(aUri).then(function(result) {
    console.log('fecthImage: ' + result);
    descriptors['desc' + aDesc] = face.computeFaceDescriptor(result);
  }).catch(err => {
    console.log(err);
  })
}

node-fetch and blob is installed and monkeyPatched and referenceErros is still there.

Thanks

enecumene commented 5 years ago

Just added const Blob = require('node-fetch'); before bufferToImage function located at build/commonjs/dom/bufferToImage.js and worked fine..

justadudewhohacks commented 5 years ago

Ahh, currently face.env.monkeyPatch doesn't patch Blob, thanks for pointing this out. Maybe as for now you could simply try to expose Blob to the global scope? global.Blob = require('blob');

hanjeahwan commented 5 years ago

Ahh, currently face.env.monkeyPatch doesn't patch Blob, thanks for pointing this out. Maybe as for now you could simply try to expose Blob to the global scope? global.Blob = require('blob');

After i define as global i get

TypeError: Right-hand side of 'instanceof' is not an object

tfjs-image-recognition-base\src\dom\bufferToImage.ts:5:14

EziamakaNV commented 5 years ago

Ahh, currently face.env.monkeyPatch doesn't patch Blob, thanks for pointing this out. Maybe as for now you could simply try to expose Blob to the global scope? global.Blob = require('blob');

After i define as global i get

TypeError: Right-hand side of 'instanceof' is not an object

tfjs-image-recognition-base\src\dom\bufferToImage.ts:5:14

@justadudewhohacks Hi, I'm getting the same error as well. the fetchImage function isnt working after monkey patching fetch

EziamakaNV commented 5 years ago

Hi @enecumene, @justadudewhohacks

I had a similar issue a few minutes ago. The only difference is that I was trying to fetch the image from the cloud (cloudinary).

I solved it by using the 'loadImage' function from the node 'canvas' package i.e

import { loadImage } from 'canvas';

const referenceImage = await loadImage(refImageUrl);

It might work for local images. Hope this helps

sebacampos commented 5 years ago

Hi! I'm working on API REST (Node v12.9.1 and Express 4.17.1) and have the same problem "Blob is not defined" when trying to fetch images from URL.

I have tried all suggestions in this issue comments:

1. global.Blob = require('blob'); and got same as @hanjeahwan

TypeError: Right-hand side of 'instanceof' is not an object

2. const referenceImage = await loadImage(refImageUrl); as @EziamakaNV suggested, but this doesn't work when I try to use faceapi.detectSingleFace() because is not HTMLImageElement, even though I already monkeypatched Image with Canvas... detection = await faceapi.detectSingleFace(referenceImage).withFaceLandmarks().withFaceDescriptor();

Argument of type 'Image' is not assignable to parameter of type 'TNetInput'. Type 'Image' is not assignable to type 'HTMLImageElement'.

If i add //@ts-ignore , then i get:

Error: toNetInput - expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id

I also tried creating new Image() like this:

const canvas = require('canvas');

const img = new Image()
const canvasCreated = canvas.createCanvas(200, 200)
const ctx = canvasCreated.getContext('2d')
img.onload = () => ctx.drawImage(img, 0, 0)
img.onerror = err => { throw err }
img.src = URL_TO_IMAGE

Result:

UnhandledPromiseRejectionWarning: TypeError: media.addEventListener is not a function

If you have any other suggestion I would be happy to try! Thanks in advance for your amazing work @justadudewhohacks

theshook commented 4 years ago

Same scenario with @sebacampos currently I am building rest api with node. then I encountered this.

JitendraGosavi01 commented 4 years ago

Ahh, currently face.env.monkeyPatch doesn't patch Blob, thanks for pointing this out. Maybe as for now you could simply try to expose Blob to the global scope? global.Blob = require('blob');

I am using this library in react and getting same problem with fetchImage function, could you please help me on this?

sebacampos commented 4 years ago

I did this long time ago so I don't remember very well, but this was my working implementation: monkeypatching fetch AND canvas classes:

import { loadImage, Canvas, Image, ImageData } from 'canvas';

// @ts-ignore
faceapi.env.monkeyPatch({ Canvas, Image, ImageData, fetch });

export const detect = async (imageUrl: string): Promise<WithFaceDescriptor<any>> => {
  let canvasImage;

  try {
    canvasImage = await loadImage(imageUrl);

    if (!canvasImage) {
      throw new Error("Canvas not loaded.");
    }
  } catch (error) {
     throw new Error("Could not load image.");
  }

  const faces = await detectFaces(canvasImage); 

  return faces[0];
} 

const detectFaces = (image: any): any => faceapi.detectAllFaces(image).withFaceLandmarks().withFaceDescriptors();

Hope it helps

JitendraGosavi01 commented 4 years ago

Actually the issue is i am fetching my labeled faces , from node api and I want to fetch that images with fetchImage , and it's not working,

Thanks

On Mon, 24 Aug 2020, 7:29 p.m. Sebastian Campos, notifications@github.com wrote:

I did this long time ago so I don't remember very well, but this was my working implementation: monkeypatching fetch AND canvas classes:

import { loadImage, Canvas, Image, ImageData } from 'canvas'; // @ts-ignorefaceapi.env.monkeyPatch({ Canvas, Image, ImageData, fetch });

export const detect = async (imageUrl: string): Promise<WithFaceDescriptor> => { let canvasImage;

try { canvasImage = await loadImage(imageUrl);

if (!canvasImage) {
  throw new Error("Canvas not loaded.");
}

} catch (error) { throw new Error("Could not load image."); }

const faces = await detectFaces(canvasImage);

return faces[0];} const detectFaces = (image: any): any => faceapi.detectAllFaces(image).withFaceLandmarks().withFaceDescriptors();

Hope it helps

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/justadudewhohacks/face-api.js/issues/194#issuecomment-679142698, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHIVDUMFBRQ7HH6TUMZNWVTSCJW2LANCNFSM4GQETFOQ .