Skip to content

Commit

Permalink
Add Cloud Vision face detection sample.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmdobry committed May 11, 2016
1 parent 4fbaf10 commit 673d712
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 1 deletion.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This repository holds Node.js samples used throughout [cloud.google.com]().
* [Google Cloud Logging](#google-cloud-logging)
* [Google Cloud Pub/Sub](#google-cloud-pubsub)
* [Google Cloud Storage](#google-cloud-storage)
* [Google Cloud Vision](#google-cloud-vision)
* [Google Prediction API](#google-prediction-api)
* [Other Example Apps](#other-example-apps)
* [More Information](#more-information)
Expand Down Expand Up @@ -106,6 +107,10 @@ __Other Examples__

- Auth sample - [Source code][storage_1] | [Documentation][storage_2]

## Google Cloud Vision

- Face detection - [Source code][vision_1] | [Documentation][vision_2]

## Google Prediction API

- Hosted Models sample - [Source code][predictionapi_1] | [Documentation][predictionapi_2]
Expand Down Expand Up @@ -307,6 +312,9 @@ See [LICENSE](https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/ma
[storage_1]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/storage/authSample.js
[storage_2]: https://cloud.google.com/storage/docs/authentication#acd-examples

[vision_1]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/vision/faceDetection.js
[vision_2]: https://cloud.google.com/vision/docs/face-tutorial

[predictionapi_1]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/prediction/hostedmodels.js
[predictionapi_2]: https://cloud.google.com/prediction/docs/developer-guide#predictionfromappengine

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"ava": {
"files": [
"test/appengine/**/*.test.js"
"test/**/*.test.js"
]
},
"devDependencies": {
Expand Down
35 changes: 35 additions & 0 deletions test/vision/faceDetection.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2016, Google, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

var test = require('ava');
var fs = require('fs');
var path = require('path');
var faceDetectionExample = require('../../vision/faceDetection');
var inputFile = path.resolve(path.join('../../vision', 'face.png'));
var outputFile = path.resolve(path.join('../../vision', 'out.png'));

test.cb('should detect faces', function (t) {
faceDetectionExample.main(
inputFile,
outputFile,
function (err, faces) {
t.ifError(err);
t.is(faces.length, 1);
var image = fs.readFileSync(outputFile);
t.ok(image);
t.end();
}
);
});
1 change: 1 addition & 0 deletions vision/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
out.*
30 changes: 30 additions & 0 deletions vision/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Cloud Vision API samples

These samples require two environment variables to be set:

- `GOOGLE_APPLICATION_CREDENTIALS` - Path to a service account file. You can
download one from your Google project's "credentials" page.
- `GCLOUD_PROJECT` - ID of your Google project.

See [gcloud-node authentication][auth] for more details.

[auth]: https://googlecloudplatform.github.io/gcloud-node/#/docs/guides/authentication

## Run a sample

Install dependencies first:

npm install

### Face detection sample

This sample uses [node-canvas](https://github.com/Automattic/node-canvas) to
draw an output image. node-canvas depends on Cairo, which may require separate
installation. See the node-canvas [installation section][canvas-install] for
details.

[canvas-install]: https://github.com/Automattic/node-canvas#installation

Execute the sample:

node faceDetection "/path/to/image.jpg"
Binary file added vision/face.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 119 additions & 0 deletions vision/faceDetection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright 2016, Google, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

// [START auth]
// You must set the GOOGLE_APPLICATION_CREDENTIALS and GCLOUD_PROJECT
// environment variables to run this sample. See:
// https://github.com/GoogleCloudPlatform/gcloud-node/blob/master/docs/authentication.md
var projectId = process.env.GCLOUD_PROJECT;

// Initialize gcloud
var gcloud = require('gcloud')({
projectId: projectId
});

// Get a reference to the vision component
var vision = gcloud.vision();
// [END auth]

var fs = require('fs');
var Canvas = require('canvas');
var Image = Canvas.Image;

/**
* Uses the Vision API to detect faces in the given file.
*/
function detectFaces(inputFile, callback) {
// Make a call to the Vision API to detect the faces
vision.detectFaces(inputFile, function (err, faces) {
if (err) {
return callback(err);
}
var numFaces = faces.length;
console.log('Found ' + numFaces + (numFaces === 1 ? ' face' : ' faces'));
callback(null, faces);
});
}

/**
* Draws a polygon around the faces, then saves to outputFile.
*/
function highlightFaces(inputFile, faces, outputFile, callback) {
fs.readFile(inputFile, function (err, image) {
if (err) {
return callback(err);
}

// Open the original image into a canvas
var img = new Image();
img.src = image;
var canvas = new Canvas(img.width, img.height);
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height);

// Now draw boxes around all the faces
context.strokeStyle = 'rgba(0,255,0,0.8)';
context.lineWidth = '5';

faces.forEach(function (face) {
context.beginPath();
face.bounds.face.forEach(function (bounds) {
context.lineTo(bounds.x, bounds.y);
});
context.lineTo(face.bounds.face[0].x, face.bounds.face[0].y);
context.stroke();
});

// Write the result to a file
console.log('Writing to file ' + outputFile);
var writeStream = fs.createWriteStream(outputFile);
var pngStream = canvas.pngStream();

pngStream.on('data', function (chunk) {
writeStream.write(chunk);
});
pngStream.on('error', console.log);
pngStream.on('end', callback);
});
}

// Run the example
function main(inputFile, outputFile, callback) {
outputFile = outputFile || 'out.png';
detectFaces(inputFile, function (err, faces) {
if (err) {
return callback(err);
}

console.log('Highlighting...');
highlightFaces(inputFile, faces, outputFile, function (err) {
if (err) {
return callback(err);
}
console.log('Finished!');
callback(null, faces);
});
});
}

exports.main = main;

if (module === require.main) {
if (process.argv.length < 3) {
console.log('Usage: node faceDetection <inputFile> [outputFile]');
process.exit(1);
}
exports.main(process.argv[2], process.argv[3], console.log);
}
17 changes: 17 additions & 0 deletions vision/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "cloud-vision-samples",
"description": "Node.js samples for Google Cloud Vision.",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"engines": {
"node": ">=0.10.x"
},
"scripts": {
"faceDetection": "node faceDetection.js"
},
"dependencies": {
"gcloud": "^0.32.0",
"canvas": "^1.3.15"
}
}

0 comments on commit 673d712

Please sign in to comment.