diff --git a/README.md b/README.md index 4444cb04a05..da0710c964c 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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] @@ -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 diff --git a/package.json b/package.json index cf0b74d5021..a9428ff7284 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ }, "ava": { "files": [ - "test/appengine/**/*.test.js" + "test/**/*.test.js" ] }, "devDependencies": { diff --git a/test/vision/faceDetection.test.js b/test/vision/faceDetection.test.js new file mode 100644 index 00000000000..ea350771644 --- /dev/null +++ b/test/vision/faceDetection.test.js @@ -0,0 +1,30 @@ +// 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 path = require('path'); +var faceDetectionExample = require('../../vision/faceDetection'); + +test.cb('should detect faces', function (t) { + faceDetectionExample.main( + path.resolve(path.join('../../vision', 'face.png')), + path.resolve(path.join('../../vision', 'out.png')), + function (err, faces) { + t.ifError(err); + t.is(faces.length, 1); + t.end(); + } + ); +}); diff --git a/vision/.gitignore b/vision/.gitignore new file mode 100644 index 00000000000..3e5a87a1bd5 --- /dev/null +++ b/vision/.gitignore @@ -0,0 +1 @@ +out.* \ No newline at end of file diff --git a/vision/README.md b/vision/README.md new file mode 100644 index 00000000000..860b81b3477 --- /dev/null +++ b/vision/README.md @@ -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" diff --git a/vision/face.png b/vision/face.png new file mode 100644 index 00000000000..b613a94e345 Binary files /dev/null and b/vision/face.png differ diff --git a/vision/faceDetection.js b/vision/faceDetection.js new file mode 100644 index 00000000000..c7377128160 --- /dev/null +++ b/vision/faceDetection.js @@ -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 [outputFile]'); + process.exit(1); + } + exports.main(process.argv[2], process.argv[3], console.log); +} diff --git a/vision/package.json b/vision/package.json new file mode 100644 index 00000000000..989ac3c8e96 --- /dev/null +++ b/vision/package.json @@ -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" + } +}