huan / node-facenet

Solve face verification, recognition and clustering problems: A TensorFlow backed FaceNet implementation for Node.js.
https://zixia.github.io/node-facenet/
Apache License 2.0
406 stars 77 forks source link

TypeError while using align method with ImageData #114

Closed nickbw2003 closed 6 years ago

nickbw2003 commented 6 years ago

Hi there,

we are trying to use your project within a nodejs (v8) server project, but are currently struggling while aligning images by your facenet api which receives ImageData. Our process is as follows:

  1. Image is posted by a frontend project against our express driven server
  2. Image is received by server (Buffer)
  3. Transform Buffer to ImageData object and use it with the facenet.align api
  4. Get embeddings and distance to other images by corresponding facenet apis

The point of error in our process is at step 3. We are using the align method like this: private async getFaces(imageBuffer: Buffer): Promise<Face[]> { return await this.facenet.align({ data: new Uint8ClampedArray(imageBuffer), width: this.width, height: this.height }); }

And this is the error we are getting: [Nest] 40266 - 2018-3-7 14:07:46 [ExceptionsHandler] Traceback (most recent call last): File "/Users//dev/projects/my-project/server/node_modules/python-bridge/node_python_bridge.py", line 94, in value = eval(_compile(data['code'], '', 'eval'), _locals) File "", line 1, in File "/Users//dev/projects/my-project/server/node_modules/facenet/dist/src/python3/facenet_bridge.py", line 195, in align image = base64_to_image(image_base64, row, col, depth) File "/Users//dev/projects/my-project/server/node_modules/facenet/dist/src/python3/facenet_bridge.py", line 43, in base64_to_image image = image_array.reshape(row, col, depth) TypeError: 'float' object cannot be interpreted as an integer

Error: Traceback (most recent call last): File "/Users//dev/projects/my-project/server/node_modules/python-bridge/node_python_bridge.py", line 94, in value = eval(_compile(data['code'], '', 'eval'), _locals) File "", line 1, in File "/Users//dev/projects/my-project/server/node_modules/facenet/dist/src/python3/facenet_bridge.py", line 195, in align image = base64_to_image(image_base64, row, col, depth) File "/Users//dev/projects/my-project/server/node_modules/facenet/dist/src/python3/facenet_bridge.py", line 43, in base64_to_image image = image_array.reshape(row, col, depth) TypeError: 'float' object cannot be interpreted as an integer

at ChildProcess.onMessage (/Users/<USER>/dev/projects/my-project/server/node_modules/python-bridge/index.js:45:32)
at Object.onceWrapper (events.js:317:30)
at emitTwo (events.js:126:13)
at ChildProcess.emit (events.js:214:7)
at emit (internal/child_process.js:772:12)
at _combinedTickCallback (internal/process/next_tick.js:141:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
huan commented 6 years ago

Can you run my example code? if you could, could you find out which part different between the two code, could cause your problem?

If you could provide a minimum runnable code with reproduce steps, I might be able to have a look at it.

nickbw2003 commented 6 years ago

Sure. I've just added some example code to a fork of your project. Please see https://github.com/nickbw2003/node-facenet

You can start the sample via "npm run demo-buffer" Example code is located at "examples/demo_buffer.ts"

Many thanks

huan commented 6 years ago

I remembered that the align() should take a string parameter for the image file path?

nickbw2003 commented 6 years ago

According to your docs and code ist should also work by passing a ImageData object

huan commented 6 years ago

According to your code: https://github.com/nickbw2003/node-facenet/blob/c336b26374ef293ccd6933463b18dec0c07ef5d0/examples/demo_buffer.ts#L8-L9

    const imageBuffer = fs.readFileSync(`${__dirname}/../tests/fixtures/two-faces.jpg`);
    const faces = await facenet.align({ data: new Uint8ClampedArray(imageBuffer), width: 640, height: 426 });

The problem is: your data is not right.

A data in ImageData is a raw array that stands for the col/row/RGB of the image, not the jpeg file data.

You have to use loadImage() to decode the image file for you, and return the right imageData.

nickbw2003 commented 6 years ago

Thank you. We are now using canvas to convert the image data - it's working as expected now.

huan commented 6 years ago

Glad to know that.

Could you close this issue for now?