Skip to content

Commit 4ce903a

Browse files
Merge branch 'visual-insights' into dev
2 parents eb57cf7 + a4eff92 commit 4ce903a

File tree

6 files changed

+151
-79
lines changed

6 files changed

+151
-79
lines changed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ APIs and SDKs that use cognitive computing to solve complex problems.
3737
* [Speech to Text](#speech-to-text)
3838
* [Text to Speech](#text-to-speech)
3939
* [Tradeoff Analytics](#tradeoff-analytics)
40+
* [Visual Insights](#visual-insights)
4041
* [Visual Recognition](#visual-recognition)
4142
* [Running in Bluemix](#running-in-bluemix)
4243
* [Debug](#debug)
@@ -542,6 +543,31 @@ tradeoff_analytics.dilemmas(params, function(err, res) {
542543
});
543544
```
544545

546+
### Visual Insights
547+
Use the [Visual Insights][visual_insights] to get insight into the themes present in a collection of images based on their visual appearance/content.
548+
549+
```js
550+
var watson = require('watson-developer-cloud');
551+
var fs = require('fs');
552+
553+
var visual_insights = watson.visual_insights({
554+
username: '<username>',
555+
password: '<password>',
556+
version: 'v1'
557+
});
558+
559+
var params = {
560+
images_file: fs.createReadStream('./resources/images.zip')
561+
};
562+
563+
visual_insights.summary(params, function(err, res) {
564+
if (err)
565+
console.log(err);
566+
else
567+
console.log(JSON.stringify(res, null, 2));
568+
});
569+
```
570+
545571
### Visual Recognition
546572
Use the [Visual Recognition][visual_recognition] service to recognize the
547573
following picture.
@@ -641,6 +667,8 @@ See [CONTRIBUTING](https://github.com/watson-developer-cloud/nodejs-wrapper/blob
641667
[concept_expansion]: http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/glimpseapi/
642668
[relationship_extraction]: http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/sireapi/
643669
[visual_recognition]: http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/visual-recognition/
670+
[visual_insights]: http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/visual-insights/
671+
644672
[text_to_speech]: http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/text-to-speech/
645673
[speech_to_text]: http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/speech-to-text/
646674
[concept_insights]: http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/concept-insights/

examples/resources/images.zip

102 KB
Binary file not shown.

examples/visual_insights.v1.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
var watson = require('watson-developer-cloud');
4+
var fs = require('fs');
5+
6+
var visual_insights = watson.visual_insights({
7+
username: 'INSERT YOUR USERNAME FOR THE SERVICE HERE',
8+
password: 'INSERT YOUR PASSWORD FOR THE SERVICE HERE',
9+
version: 'v1'
10+
});
11+
12+
var params = {
13+
images_file: fs.createReadStream('./resources/images.zip')
14+
};
15+
16+
visual_insights.summary(params, function(err, res) {
17+
if (err)
18+
console.log(err);
19+
else
20+
console.log(JSON.stringify(res, null, 2));
21+
});

lib/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ var watson = {};
115115
'dialog',
116116
'retrieve_and_rank',
117117
'document_conversion',
118-
118+
'visual_insights',
119119
// deprecated
120120
'search',
121121
'language_identification',

services/alchemy_vision/v1.js

Lines changed: 22 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ var requestFactory = require('../../lib/requestwrapper');
2121
var endpoints = require('../../lib/alchemy_endpoints.json');
2222
var helper = require('../../lib/helper');
2323
var isStream = require('isstream');
24-
var pick = require('object.pick');
2524
var omit = require('object.omit');
2625
var fs = require('fs');
2726

@@ -54,18 +53,33 @@ function createRequest(method) {
5453
' needs to be specified'));
5554
return;
5655
}
56+
// always return json
57+
params.outputMode = 'json';
5758

5859
var parameters = {
5960
options: {
6061
url: endpoints[method][format],
61-
method: 'POST',
62-
json: true,
63-
qs: extend({outputMode: 'json'}, params) // change default output to json
62+
method: 'POST'
6463
},
6564
defaultOptions: this._options
6665
};
6766

68-
return requestFactory(parameters, errorFormatter(callback));
67+
if (!params.image || !isStream(params.image)) {
68+
// url or base64 images are considered 'not-raw'
69+
params.imagePostMode = 'not-raw';
70+
// send the parameters as form url-encoded
71+
parameters.options.form = params;
72+
return requestFactory(parameters, errorFormatter(callback));
73+
} else {
74+
params.imagePostMode = 'raw';
75+
// send the parameters as query parameters
76+
parameters.options.qs = omit(params,['image']);
77+
// add the content-length to the headers
78+
parameters.options.headers = {
79+
'Content-Length': fs.statSync(params.image.path).size
80+
};
81+
return params.image.pipe(requestFactory(parameters, errorFormatter(callback)));
82+
}
6983
};
7084
}
7185

@@ -81,86 +95,16 @@ function AlchemyVision(options) {
8195
/**
8296
* Extracts images from a URL or html
8397
*/
84-
AlchemyVision.prototype.getImageLinks = function(_params, callback ) {
85-
var params = _params || {};
86-
var accepted_formats = Object.keys(endpoints['image_link']);
87-
var format = helper.getFormat(params, accepted_formats);
88-
89-
if (format === null) {
90-
callback(new Error('Missing required parameters: ' + accepted_formats.join(', ') + ' needs to be specified'));
91-
return;
92-
}
93-
94-
var parameters = {
95-
options: {
96-
url: endpoints['image_link'][format],
97-
method: 'POST',
98-
json: true,
99-
qs: extend({}, params,{outputMode: 'json'}) // change default output to json
100-
},
101-
defaultOptions: this._options
102-
};
103-
104-
return requestFactory(parameters, errorFormatter(callback));
105-
};
98+
AlchemyVision.prototype.getImageLinks = createRequest('image_link');
10699

107100
/**
108101
* Tags image with keywords
109102
*/
110-
AlchemyVision.prototype.getImageKeywords = function(_params, callback) {
111-
var params = extend({}, _params);
112-
var accepted_formats = Object.keys(endpoints['image_keywords']);
113-
var format = helper.getFormat(params, accepted_formats);
114-
115-
if (format === null) {
116-
callback(new Error('Missing required parameters: ' + accepted_formats.join(', ') + ' needs to be specified'));
117-
return;
118-
}
119-
120-
var parameters = {
121-
options: {
122-
url: endpoints['image_keywords'][format],
123-
method: 'POST',
124-
json: true,
125-
qs: {outputMode: 'json'} // change default output to json
126-
},
127-
defaultOptions: this._options
128-
};
129-
130-
if (typeof(params.image) !== 'undefined') {
131-
132-
// check if image is stream or string
133-
if ((typeof(params.image) !== 'string') && !isStream(params.image)) {
134-
callback(new Error('Invalid arguments: image needs to be a stream or base64'));
135-
return;
136-
}
137-
138-
if (isStream(params.image)) {
139-
params.imagePostMode = 'raw';
140-
// handle raw images
141-
parameters.options.body = params.image;
142-
143-
} else {
144-
params.imagePostMode = 'not-raw';
145-
parameters.options.formData = params;
146-
}
147-
} else {
148-
parameters.options.formData = params;
149-
}
150-
151-
return requestFactory(parameters, errorFormatter(callback));
152-
};
103+
AlchemyVision.prototype.getImageKeywords = createRequest('image_keywords');
153104

154105
/**
155106
* Face detection and Recognition
156107
*/
157-
AlchemyVision.prototype.recognizeFaces = function(_params, callback) {
158-
var params = _params || {};
159-
160-
if (params.image && typeof(params.image) !== 'string')
161-
params.imagePostMode = 'raw';
162-
163-
return createRequest('image_recognition').call(this, params, callback);
164-
};
108+
AlchemyVision.prototype.recognizeFaces = createRequest('image_recognition');
165109

166110
module.exports = AlchemyVision;

services/visual_insights/v1.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright 2014 IBM Corp. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
'use strict';
18+
19+
var extend = require('extend');
20+
var requestFactory = require('../../lib/requestwrapper');
21+
var isStream = require('isstream');
22+
23+
function VisualInsights(options) {
24+
// Default URL
25+
var serviceDefaults = {
26+
url: 'https://gateway.watsonplatform.net/visual-insights-experimental/api'
27+
};
28+
29+
// Replace default options with user provided
30+
this._options = extend(serviceDefaults, options);
31+
}
32+
33+
/**
34+
* Returns a list of the classifiers that are used in the summary call
35+
*/
36+
VisualInsights.prototype.classifiers = function(params, callback) {
37+
var parameters = {
38+
options: {
39+
method: 'GET',
40+
url: '/v1/classifiers',
41+
qs: params,
42+
json: true
43+
},
44+
defaultOptions: this._options
45+
};
46+
return requestFactory(parameters, callback);
47+
};
48+
49+
/**
50+
* Classifies @param images_file using all available classifiers.
51+
*
52+
* @param {ReadStream} images_file The zip of images to analyze.
53+
*/
54+
VisualInsights.prototype.summary = function(params, callback) {
55+
params = params || {};
56+
57+
if (!params.images_file) {
58+
callback(new Error('Missing required parameters: images_file'));
59+
return;
60+
}
61+
62+
if (!isStream(params.images_file)) {
63+
callback(new Error('images_file is not a standard Node.js Stream'));
64+
return;
65+
}
66+
67+
var parameters = {
68+
options: {
69+
method: 'POST',
70+
url: '/v1/summary',
71+
formData: params,
72+
json: true
73+
},
74+
defaultOptions: this._options
75+
};
76+
return requestFactory(parameters, callback);
77+
};
78+
79+
module.exports = VisualInsights;

0 commit comments

Comments
 (0)