Skip to content

Commit

Permalink
Upgrades vision to partial-GAPIC (#434)
Browse files Browse the repository at this point in the history
  • Loading branch information
gguuss authored and jmdobry committed Jul 31, 2017
1 parent c7be652 commit 006c627
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 262 deletions.
188 changes: 87 additions & 101 deletions vision/detect.js

Large diffs are not rendered by default.

40 changes: 25 additions & 15 deletions vision/faceDetection.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,25 @@ var fs = require('fs');
*/
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);
});
const request = { source: { filename: inputFile } };
vision.faceDetection(request)
.then((results) => {
const faces = results[0].faceAnnotations;
var numFaces = faces.length;
console.log('Found ' + numFaces + (numFaces === 1 ? ' face' : ' faces'));
callback(null, faces);
})
.catch((err) => {
console.error('ERROR:', err);
callback(err);
});
}

/**
* Draws a polygon around the faces, then saves to outputFile.
*/
function highlightFaces (inputFile, faces, outputFile, Canvas, callback) {
fs.readFile(inputFile, function (err, image) {
fs.readFile(inputFile, (err, image) => {
if (err) {
return callback(err);
}
Expand All @@ -64,12 +68,18 @@ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) {
context.strokeStyle = 'rgba(0,255,0,0.8)';
context.lineWidth = '5';

faces.forEach(function (face) {
faces.forEach((face) => {
context.beginPath();
face.bounds.face.forEach(function (bounds) {
let origX = 0;
let origY = 0;
face.boundingPoly.vertices.forEach((bounds, i) => {
if (i === 0) {
origX = bounds.x;
origY = bounds.y;
}
context.lineTo(bounds.x, bounds.y);
});
context.lineTo(face.bounds.face[0].x, face.bounds.face[0].y);
context.lineTo(origX, origY);
context.stroke();
});

Expand All @@ -78,7 +88,7 @@ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) {
var writeStream = fs.createWriteStream(outputFile);
var pngStream = canvas.pngStream();

pngStream.on('data', function (chunk) {
pngStream.on('data', (chunk) => {
writeStream.write(chunk);
});
pngStream.on('error', console.log);
Expand All @@ -89,13 +99,13 @@ function highlightFaces (inputFile, faces, outputFile, Canvas, callback) {
// Run the example
function main (inputFile, outputFile, Canvas, callback) {
outputFile = outputFile || 'out.png';
detectFaces(inputFile, function (err, faces) {
detectFaces(inputFile, (err, faces) => {
if (err) {
return callback(err);
}

console.log('Highlighting...');
highlightFaces(inputFile, faces, outputFile, Canvas, function (err) {
highlightFaces(inputFile, faces, outputFile, Canvas, (err) => {
if (err) {
return callback(err);
}
Expand Down
2 changes: 1 addition & 1 deletion vision/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"dependencies": {
"@google-cloud/storage": "1.1.0",
"@google-cloud/vision": "0.11.2",
"@google-cloud/vision": "^0.12.0",
"async": "2.3.0",
"natural": "0.5.1",
"redis": "2.7.1",
Expand Down
22 changes: 12 additions & 10 deletions vision/quickstart.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016, Google, Inc.
* Copyright 2017, 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
Expand All @@ -19,24 +19,26 @@
// Imports the Google Cloud client library
const Vision = require('@google-cloud/vision');

// Your Google Cloud Platform project ID
const projectId = 'YOUR_PROJECT_ID';

// Instantiates a client
const visionClient = Vision({
projectId: projectId
});
const vision = Vision();

// The name of the image file to annotate
const fileName = './resources/wakeupcat.jpg';

// Prepare the request object
const request = {
source: {
filename: fileName
}
};

// Performs label detection on the image file
visionClient.detectLabels(fileName)
vision.labelDetection(request)
.then((results) => {
const labels = results[0];
const labels = results[0].labelAnnotations;

console.log('Labels:');
labels.forEach((label) => console.log(label));
labels.forEach((label) => console.log(label.description));
})
.catch((err) => {
console.error('ERROR:', err);
Expand Down
4 changes: 2 additions & 2 deletions vision/system-test/detect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ test(`should detect logos in a remote file`, async (t) => {

test(`should detect properties in a local file`, async (t) => {
const output = await tools.runAsync(`${cmd} properties ${files[1].localPath}`, cwd);
t.true(output.includes(`Colors:`));
t.true(output.includes(`{ color: { red: 69, green: 42, blue: 27`));
t.true(output.split(`\n`).length > 4, `Multiple colors were detected.`);
});

test(`should detect properties in a remote file`, async (t) => {
const output = await tools.runAsync(`${cmd} properties-gcs ${bucketName} ${files[1].name}`, cwd);
t.true(output.includes(`Colors:`));
t.true(output.includes(`{ color: { red: 69, green: 42, blue: 27`));
t.true(output.split(`\n`).length > 4, `Multiple colors were detected.`);
});

Expand Down
43 changes: 7 additions & 36 deletions vision/system-test/quickstart.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016, Google, Inc.
* Copyright 2017, 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
Expand All @@ -16,46 +16,17 @@
'use strict';

const path = require(`path`);
const proxyquire = require(`proxyquire`).noPreserveCache();
const sinon = require(`sinon`);
const test = require(`ava`);
const tools = require(`@google-cloud/nodejs-repo-tools`);

const vision = proxyquire(`@google-cloud/vision`, {})();
const cmd = `node quickstart.js`;
const cwd = path.join(__dirname, `..`);

test.before(tools.stubConsole);
test.after.always(tools.restoreConsole);

test.cb(`should detect labels`, (t) => {
const filePath = path.join(__dirname, `../resources/wakeupcat.jpg`);
const expectedFileName = `./resources/wakeupcat.jpg`;
const visionMock = {
detectLabels: (_fileName) => {
t.is(_fileName, expectedFileName);

return vision.detectLabels(filePath)
.then(([labels]) => {
t.true(Array.isArray(labels));

setTimeout(() => {
try {
t.is(console.log.callCount, 6);
t.deepEqual(console.log.getCall(0).args, [`Labels:`]);
labels.forEach((label, i) => {
t.deepEqual(console.log.getCall(i + 1).args, [label]);
});
t.end();
} catch (err) {
t.end(err);
}
}, 200);

return [labels];
});
}
};

proxyquire(`../quickstart`, {
'@google-cloud/vision': sinon.stub().returns(visionMock)
});
test(`should detect labels in a remote file`, async (t) => {
const output = await tools.runAsync(`${cmd}`, cwd);
t.true(output.includes(`Labels:`));
t.true(output.includes(`cat`));
});
69 changes: 37 additions & 32 deletions vision/textDetection.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,14 @@ function lookup (words, callback) {
function extractDescription (texts) {
var document = '';
texts.forEach(function (text) {
document += (text.desc || '');
document += (text.description || '');
});
return document;
}

function extractDescriptions (filename, index, texts, callback) {
if (texts.length) {
index.add(filename, extractDescription(texts), callback);
function extractDescriptions (filename, index, response, callback) {
if (response.textAnnotations.length) {
index.add(filename, extractDescription(response.textAnnotations), callback);
} else {
console.log(filename + ' had no discernable text.');
index.setContainsNoText(filename, callback);
Expand All @@ -147,36 +147,41 @@ function extractDescriptions (filename, index, texts, callback) {

// [START get_text]
function getTextFromFiles (index, inputFiles, callback) {
var options = { verbose: true };

// Make a call to the Vision API to detect text
vision.detectText(inputFiles, options, function (err, detections) {
if (err) {
return callback(err);
}
var textResponse = {};
var tasks = [];
inputFiles.forEach(function (filename, i) {
var response = detections[i];
if (response.error) {
console.log('API Error for ' + filename, response.error);
return;
} else if (Array.isArray(response)) {
textResponse[filename] = 1;
} else {
textResponse[filename] = 0;
}
tasks.push(function (cb) {
extractDescriptions(filename, index, response, cb);
});
});
async.parallel(tasks, function (err) {
if (err) {
return callback(err);
}
callback(null, textResponse);
});
let requests = [];
inputFiles.forEach((filename) => {
let request = {
image: {content: fs.readFileSync(filename).toString('base64')},
features: {type: 'TEXT_DETECTION'}
};
requests.push(request);
});
vision.batchAnnotateImages({requests: requests})
.then((results) => {
let detections = results[0].responses;
var textResponse = {};
var tasks = [];
inputFiles.forEach(function (filename, i) {
var response = detections[i];
if (response.error) {
console.log('API Error for ' + filename, response.error);
return;
} else if (Array.isArray(response)) {
textResponse[filename] = 1;
} else {
textResponse[filename] = 0;
}
tasks.push(function (cb) {
extractDescriptions(filename, index, response, cb);
});
});
async.parallel(tasks, function (err) {
if (err) {
return callback(err);
}
callback(null, textResponse);
});
});
}

// Run the example
Expand Down
Loading

0 comments on commit 006c627

Please sign in to comment.