The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

211142 (3) [Avatar] Offline
I downloaded the file from the book. Then I modified dstBucket and outputDomain appropriately and uploaded the new zip to AWS Lambda. Finally I added a policy to allow PUTting S3 objects in my bucket and connected the policy to a Lambda rule for my faceDetection function.

I ran:
aws lambda invoke --function-name faceDetection --payload '{"imageUrl":""}' output.txt

I got this result:
    "FunctionError": "Unhandled", 
    "StatusCode": 200

This was in the output.txt file:
  "errorMessage": "Cannot find module '/var/task/node_modules/opencv/build/opencv/v5.0.0/Release/node-v46-linux-x64/opencv.node'",
  "errorType": "Error",
  "stackTrace": [
    "Function.Module._load (module.js:276:25)",
    "Module.require (module.js:353:17)",
    "require (internal/module.js:12:17)",
    "Object.<anonymous> (/var/task/node_modules/opencv/lib/bindings.js:4:15)",
    "Module._compile (module.js:409:26)",
    "Object.Module._extensions..js (module.js:416:10)",
    "Module.load (module.js:343:32)",
    "Function.Module._load (module.js:300:12)",
    "Module.require (module.js:353:17)"

There isn't a node-v46-linux-x64/opencv.node file in node_modules. Instead there's a node-v11-linux-x64/opencv.node file. How I can get this to work?
211142 (3) [Avatar] Offline
Changing {node_abi} to node-v11 in package.json's binary:module_path value led to this error:
  "errorMessage": "Module did not self-register.",
  "errorType": "Error",
  "stackTrace": [
    "Object.Module._extensions..node (module.js:434:18)",
    "Module.load (module.js:343:32)",
    "Function.Module._load (module.js:300:12)",
    "Module.require (module.js:353:17)",
    "require (internal/module.js:12:17)",
    "Object.<anonymous> (/var/task/node_modules/opencv/lib/bindings.js:4:15)",
    "Module._compile (module.js:409:26)",
    "Object.Module._extensions..js (module.js:416:10)",
    "Module.load (module.js:343:32)"
211142 (3) [Avatar] Offline
Anybody else able to get opencv to work?
475381 (3) [Avatar] Offline
Hi, I have same problem.Beside that the book in this exercise is not well described, but i get:

"errorMessage": "Cannot find module '/var/task/node_modules/opencv/build/opencv/v5.0.0/Release/node-v48-linux-x64/opencv.node'"

any hints?
481543 (1) [Avatar] Offline
I had the same problem. It looks like the opencv that was delivered with the node.js is not right (not sure why) because the directly that the log is complaining about doesn't exist. I uploaded the python version. I had to change the invoke method for python and I was able to get this to work.
512702 (1) [Avatar] Offline
I had the same problems with opencv face-detection example for nodejs.

I tried the faceDetection several hours before I understood, that I have to compile the opencv for the node-version I selected in lambda (6.10).
And than use that binaries for the lambda package to get the face detection running in lambda.

I googled around and sampled steps mainly from two pages and the book itself to get it running.
Hope posting my steps help you.

If you are not experienced in setting up and using a AWS EC2 Linux instance and Linux (via ssh/commandline/scp/zip ...), the description of my steps will not help you.

What I did:
1. Start a new AWS EC2 instance from the Amazon Linux-Image.
2. Connect to this instance via ssh.
3. Install the nvm ( node version manager)
curl -o- | bash
. ~/.nvm/

4. Install the node Version I selected in the lambda-Function (6.10)
nvm install 6.10
5. Install the compiler and tools
sudo yum update -y
sudo yum install –y gcc44 gcc-c++ libgcc44 cmake

6. make a Directory for compiling opencv and changed to it
mkdir compile_opencv && cd compile_opencv
7. Download opencv version 2.4. linux unix-source-code
wget -O

8. make folder for the source files
mkdir opencv-source
9. change to soure folder
cd opencv-source
10. unzip opencv-zip to souce-folder
unzip ../
11. prepare compiling
12. compile and install opencv locally (takes a while or long depending on your ec2 instance)
make && make install
13. correct the library parameters for the image-formats (as explained in the book) in the file:
-ljasper -ltiff -lpng -ljpeg
-llibjasper -llibtiff -llibpng -llibjpeg
14. make a node project folder
cd ~
mkdir opencv_lambda_template

15. install opencv in the project folder
PKG_CONFIG_PATH=~/opencv/lib/pkgconfig/ npm install --prefix=~/opencv_lambda_template opencv

16. (optional) test opencv in project folder (copied from step 6:

cd ~/opencv_lambda_template
cd node_modules/opencv/examples/
mkdir tmp
node face-detection.js # Image saved to ./tmp/face-detection.png
ls tmp # face-detection.png
rm -r tmp

You may then zip the project folder and copy (scp ...) the zip to your local machine.
There you can extract and use it as template for the project. You fill with your code file and install the appropriate packages.

Or you may edit the project on the ec2 instance.
Finally you zip it and push it to S3 (you have to install the needed credentials on the ec2 instance if you do it from there).

From S3 you can load the zip to lambda.

Pages that helped me beside the book itself:

Hope that helps

DeMoehn (10) [Avatar] Offline
Thanks for the detailed introductions.
I had the same problems with Node.js as you guys.

As it is a but cumbersome to create an EC2 instance, build the opencv library, install all the needed npms, etc. I have the opencv and the finished node.js lambda application hosted on my S3 if anyone is intertested, feel free:

- OpenCV:
- App:

504344 (14) [Avatar] Offline
Thanks for sharing unfortunately I am not able to solve it with your provided files. What I have done:

1) downloaded app provided by DeMoehn

2) unzipped file

3) modified index.js to include my buckets (input and output to same xx-faces)

4) deleted package.json and output.txt

5) zipped index + node_modules

6) created new policy and role for face detection same like in previous example (thumbs) - read and put in S3 bucket

7) created lambda function with S3 trigger

smilie checked logs and here we are

Unable to import module 'index': Error
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)

Seems for me index is not liked but I do not get why

@DeMoehn maybe you can help out. Some insights are really appreciated.
DeMoehn (10) [Avatar] Offline
I just did the same as you

- Downloaded my Code
- unpacked
- Deleted packe.json and output.txt
- Opened the index.js file (didn't change the bucket)
- Zipped everything
- Uploaded it again

Worked out great for me...

Did you somehow forget to add the index.js to the .zip file, is index.js not in the root directory or maybe somehow currupt?
504344 (14) [Avatar] Offline
You were right I had mixed up zipping process shame on me. Now at least I have some errors.

2018-01-04T10:41:05.847Z 9f085fb5-f13b-11e7-a561-573ee1a9c4a8 Error: options.uri is a required argument
at Request.init (/var/task/node_modules/request/request.js:232:31)
at new Request (/var/task/node_modules/request/request.js:128:8)
at request (/var/task/node_modules/request/index.js:53:10)
at /var/task/node_modules/request/index.js:61:12
at Function.get (/var/task/node_modules/request/index.js:100:12)
at exports.handler (/var/task/index.js:23:11)
2018-01-04T10:41:05.964Z 9f085fb5-f13b-11e7-a561-573ee1a9c4a8
    "errorMessage": "options.uri is a required argument",
    "errorType": "Error",
    "stackTrace": [
        "Request.init (/var/task/node_modules/request/request.js:232:31)",
        "new Request (/var/task/node_modules/request/request.js:128:8)",
        "request (/var/task/node_modules/request/index.js:53:10)",
        "Function.get (/var/task/node_modules/request/index.js:100:12)",
        "exports.handler (/var/task/index.js:23:11)"
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /home/ec2-user/compile_opencv/opencv-source/opencv-2.4.11/modules/core/src/array.cpp, line 2482
DeMoehn (10) [Avatar] Offline
Are you using Node 6.10? Or 4.3?
504344 (14) [Avatar] Offline
DeMoehn (10) [Avatar] Offline
Seems like there is a problem with the original image URL.
Where is it stored?
Is it public accessible?
504344 (14) [Avatar] Offline
I rechecked by uploading a new one, bucket and image permissions are set to public.

Storage in S3 same folder like output jr-faces.
DeMoehn (10) [Avatar] Offline
I see, just try using a public Picture you found on Google or something like this with public URL, not AWS
504344 (14) [Avatar] Offline
thx for help, i will try later
150034 (6) [Avatar] Offline
AWS Lambda recently released support for Node 8.10.0, which for the first time means Lambda supports async/await, so I wanted to see if I could modify this project to utilize the latest available versions of Node and OpenCV as of April 2018.

I was able to get the last release on the OpenCV 2.x line to work, which is (as I write) version, but I was unable to get the latest 3.x release to work with Node.

Here are reproducible steps to build a binary OpenCV Node module from under Node 8.10.0:

1. Spin up an Amazon Linux EC2 instance (ami-1853ac65), bring it up to date, install build tools, and reboot into the updated kernel:
$ sudo yum update -y
$ sudo yum install -y gcc gcc-c++ libgcc cmake
$ sudo reboot

2. Install NVM and use it to install Node 8.10.0
$ curl -o- | bash
[... relog to get nvm env...]
$ nvm install 8.10.0

3. Download and build OpenCV
$ cd
$ curl -L -O
$ mkdir opencv-build
$ unzip -d opencv-build/
$ cd opencv-build/
$ make && make install

4. The problems in the file ~/opencv/lib/pkgconfig/opencv.pc from version 2.4.11 has been fixed, however in between 2.4.11 and another problem was introduced.

Edit the file ~/opencv/lib/pkgconfig/opencv.pc and in the Libs: line, insert the flag (anywhere in the line):

That is, the line should ultimately read like this:
Libs: -L${exec_prefix}/share/OpenCV/3rdparty/lib -L${exec_prefix}/lib -lopencv_contrib -lopencv_stitching -lopencv_nonfree -lopencv_superres -lopencv_ocl -lopencv_ts -lopencv_videostab -lopencv_gpu -lopencv_photo -lopencv_objdetect -lopencv_legacy -lopencv_video -lopencv_ml -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lIlmImf -llibjasper -llibtiff -llibpng -llibjpeg -lopencv_imgproc -lopencv_flann -lopencv_core -lzlib -lrt -lpthread -lm -ldl -lstdc++

5. Build the binary node module, installing it in the package root of your Lambda function, which I named faceDetection to match the name of the Lambda:
$ cd
$ mkdir ~/faceDetection
$ PKG_CONFIG_PATH=~/opencv/lib/pkgconfig/ npm install --prefix=~/faceDetection/ opencv

6. Test the module:
$ cd ~/faceDetection/node_modules/opencv/examples
$ mkdir tmp
$ node face-detection
Image saved to ./tmp/face-detection.png

Have a look at that ./tmp/face-detection.png to see that it's working.

Copy the book's index.js to that package root, edit it with your S3 bucket information, install the other required Node packages (util, request, node-uuid), ZIP it up and it should work as your Lambda function using Node 8.10.0.

Since the whole point of this exercise was to take advantage of the features of Node 8.10.0, I rewrote the handler function to use promises with async/await, which I've copied below.

'use strict';

const cv = require('opencv');
const util = require('util');
const request = require('request').defaults({encoding: null});

const uuid = require('node-uuid');
const AWS = require('aws-sdk');

const s3 = new AWS.S3();

const dstBucket = 'YOUR-BUCKET';
const dstPrefix = 'tmp/';
const outputDomain = '';

function getFormattedDate() {
  const now = new Date().toISOString(); // YYYY-MM-DDTHH:mm:ss.sssZ
  const formattedNow = `${now.substr(0, 4)}${now.substr(5, 2)}${now.substr(8, 2)}${now.substr(11, 2)}${now.substr(14, 2)}${now.substr(17, 2)}`;
  return formattedNow;

exports.handler = async event => {
  console.log('Reading options from event:\n', util.inspect(event, {depth: 5}));

  const {imageUrl} = event;

  const body = await new Promise((resolve, reject) => {
    request.get(imageUrl, (error, _, body) => error ? reject(error) : resolve(body));

  const image = await new Promise((resolve, reject) => {
    cv.readImage(body, (error, image) => error ? reject(error) : resolve(image));

  if (image.width() < 1 || image.height() < 1) {
    throw new Error('Image has no size');

  const faces = await new Promise((resolve, reject) => {
    image.detectObject('node_modules/opencv/data/haarcascade_frontalface_alt.xml', {}, (error, faces) => {
      return error ? reject(error) : resolve(faces);

  if (faces.length === 0) {
    return {
      faces: 0,
      outputURL: imageUrl,

  for (const face of faces) {
    image.rectangle([face.x, face.y], [face.width, face.height], [255, 255, 255], 2);

  const dstKey = dstPrefix + getFormattedDate() + '-' + uuid.v4() + '.jpg';
  const contentType = 'image/jpeg';

  await s3.putObject({
    Bucket: dstBucket,
    Key: dstKey,
    Body: image.toBuffer(),
    ContentType: contentType,

  return {
    faces: faces.length,
    outputURL: `https://${outputDomain}/${dstKey}`,