face-api.js: Face detection don't work on AWS Lambda due to node-canvas not working on node 8.10

Hi there!

I am trying to get this up and running on AWS Lambda but are having trouble as it seem the ‘canvas’ package is broken on node 8.10. I am trying to get some face detection going.

https://github.com/Automattic/node-canvas/issues/1252#issuecomment-437598572

It looks like its kind of a pain to try and run any other version of node on AWS Lambda, so I started trying to use it without the canvas package. As you mention in the README and I also noticed that the faceapi.locateFaces() function also takes a Tensor4D class as input. I have never used Tensorflow and I am a little confused as how to turn a ArrayBuffer from axios into a correctly shaped Tensor4D object.

I am fetching a jpeg image using axios.

I found the tf.tensor4d function but not sure what shape and dtype it should be.

Do you have any idea?

My code so far:

const { data: imageBuffer } = await axios.get(url, {
	responseType: 'arraybuffer'
})
const imageTensor = tf.tensor4d(imageBuffer, [?, ?, ? ,?])
const faces = await detector.locateFaces(imageTensor)

Error messages look similar to this one:

Error: Based on the provided shape, [1,2,3,4], and dtype float32, the tensor should have 24 values but has 68695

Any help is greatly appreciated!

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 24 (2 by maintainers)

Most upvoted comments

Thanks!

Tried the get-pixels npm package and it works!

get-pixels return a 4 channel array all the time, even for jpegs 🤷 , so had to remove the alpha channel.

const pixels = await new Promise<Pixels>(resolve => {
	getPixels(url, (err, pixels: Pixels) => {
		if (err) {
			throw err
		}
		console.log('pixels:', pixels)
		resolve(pixels)
	})
})

// remove alpha channel
const RGBValues = []
pixels.data.forEach((px, i) => {
	if ((i + 1) % 4 != 0) {
		RGBValues.push(px)
	}
})
const imageTensor = tf.tensor3d(RGBValues, [pixels.shape[1], pixels.shape[0], 3]) as any
const faces = await detector.locateFaces(imageTensor)

Now to the task of getting it up on Lambda without breaking their code size limit, wish me luck!