imgrecog
Version:
Node.js tool to parse and act on images, using the Google Vision and Sightengine APIs.
220 lines (219 loc) • 8.87 kB
JavaScript
;
// GOOGLE VISION
Object.defineProperty(exports, "__esModule", { value: true });
exports.Vision = void 0;
const utils_1 = require("./utils");
const vision = require("@google-cloud/vision");
// Likelyhood texts matched with a numeric score.
const likelyhood = {
VERY_UNLIKELY: 0,
UNLIKELY: 0.21,
POSSIBLE: 0.51,
LIKELY: 0.71,
VERY_LIKELY: 0.91
};
/**
* Google Vision API wrapper.
*/
class Vision {
constructor() {
/**
* Prepare the Google Vision client.
* @param options Program options with the authfile.
*/
this.prepare = async (options) => {
try {
this.client = new vision.ImageAnnotatorClient({ keyFilename: options.googleKeyfile });
utils_1.logInfo(options, `Using credentials from file ${options.googleKeyfile}`);
}
catch (ex) {
utils_1.logError(options, "Could not create the Google Vision API client", ex);
}
// Reset API call counter to 0.
this.apiCalls = 0;
};
/**
* Detect objects on the specified image.
* @param options Program options.
* @param filepath Image file to be scanned.
*/
this.detectObjects = async (options, filepath) => {
this.apiCalls++;
try {
const apiCall = await this.client.objectLocalization(filepath);
const apiResult = apiCall[0].localizedObjectAnnotations;
utils_1.logDebug(options, `${filepath} got ${apiResult.length} objects`);
const logtext = [];
let tags = {};
// Add objects as tags.
for (let obj of apiResult) {
const key = utils_1.normalizeTag(obj.name);
const score = utils_1.normalizeScore(obj.score);
if (score) {
logtext.push(`${key}:${score}`);
tags[key] = score;
}
}
const objects = logtext.length > 0 ? logtext.join(", ") : "NONE";
const logDetails = `${filepath}: ${objects}`;
utils_1.logInfo(options, logDetails);
return {
file: filepath,
tags: tags
};
}
catch (ex) {
utils_1.logError(options, `${filepath} - error detecting objects`, ex);
return null;
}
};
/**
* Detect labels and tags for the specified image.
* @param options Program options.
* @param filepath Image file to be scanned.
*/
this.detectLabels = async (options, filepath) => {
this.apiCalls++;
try {
const apiCall = await this.client.labelDetection(filepath);
const apiResult = apiCall[0].labelAnnotations;
utils_1.logDebug(options, `${filepath} got ${apiResult.length} labels`);
const logtext = [];
let tags = {};
// Add labels as tags.
for (let label of apiResult) {
const key = utils_1.normalizeTag(label.description);
const score = utils_1.normalizeScore(label.score);
if (score) {
logtext.push(`${key}:${score}`);
tags[key] = score;
}
}
const labels = logtext.length > 0 ? logtext.join(", ") : "NONE";
const logDetails = `${filepath}: ${labels}`;
utils_1.logInfo(options, logDetails);
return {
file: filepath,
tags: tags
};
}
catch (ex) {
utils_1.logError(options, `${filepath} - error detecting labels`, ex);
return null;
}
};
/**
* Detect landmarks for the specified image.
* @param options Program options.
* @param filepath Image file to be scanned.
*/
this.detectLandmarks = async (options, filepath) => {
this.apiCalls++;
try {
const apiCall = await this.client.landmarkDetection(filepath);
const apiResult = apiCall[0].landmarkAnnotations;
utils_1.logDebug(options, `${filepath} got ${apiResult.length} landmarks`);
const logtext = [];
let tags = {};
// Add landmarks as tags.
for (let land of apiResult) {
const key = utils_1.normalizeTag(land.description);
const score = utils_1.normalizeScore(land.score);
if (score) {
logtext.push(`${key}:${score}`);
tags[key] = score;
}
}
const landmarks = logtext.length > 0 ? logtext.join(", ") : "NONE";
const logDetails = `${filepath}: ${landmarks}`;
utils_1.logInfo(options, logDetails);
return {
file: filepath,
tags: tags
};
}
catch (ex) {
utils_1.logError(options, `${filepath} - error detecting landmarks`, ex);
return null;
}
};
/**
* Detect logos and brands for the specified image.
* @param options Program options.
* @param filepath Image file to be scanned.
*/
this.detectLogos = async (options, filepath) => {
this.apiCalls++;
try {
const apiCall = await this.client.logoDetection(filepath);
const apiResult = apiCall[0].logoAnnotations;
utils_1.logDebug(options, `${filepath} got ${apiResult.length} logos`);
const logtext = [];
let tags = {};
// Add logos as tags.
for (let logo of apiResult) {
const key = utils_1.normalizeTag(`logo-${logo.description}`);
const score = utils_1.normalizeScore(logo.score);
if (score) {
logtext.push(`${key}:${score}`);
tags[key] = score;
}
}
const logos = logtext.length > 0 ? logtext.join(", ") : "NONE";
const logDetails = `${filepath}: ${logos}`;
utils_1.logInfo(options, logDetails);
return {
file: filepath,
tags: tags
};
}
catch (ex) {
utils_1.logError(options, `${filepath} - error detecting logos`, ex);
return null;
}
};
/**
* Detect if the specified image is unsafe (violent, adult, racy, medical, spoof).
* All these tags will be prefixed with "explicit".
* @param options Program options.
* @param filepath Image file to be scanned.
*/
this.detectUnsafe = async (options, filepath) => {
this.apiCalls++;
try {
const apiCall = await this.client.safeSearchDetection(filepath);
const apiResult = apiCall[0].safeSearchAnnotation;
const apiKeys = Object.keys(apiResult);
utils_1.logDebug(options, `${filepath} got ${apiKeys.length} unsafe properties`);
const logtext = [];
let tags = {};
// Add safe search labels as tags.
for (let unsafeKey of apiKeys) {
if (unsafeKey.indexOf("Confidence") > 0)
continue;
const value = apiResult[unsafeKey];
const key = utils_1.normalizeTag(`explicit-${unsafeKey}`);
const score = utils_1.normalizeScore(likelyhood[value]);
if (score) {
logtext.push(`${key}:${score}`);
tags[key] = score;
}
}
const unsafe = logtext.length > 0 ? logtext.join(", ") : "NONE";
const logDetails = `${filepath}: ${unsafe}`;
utils_1.logInfo(options, logDetails);
return {
file: filepath,
tags: tags
};
}
catch (ex) {
utils_1.logError(options, `${filepath} - error detecting unsafe`, ex);
return null;
}
};
}
}
exports.Vision = Vision;
// Exports...
exports.default = new Vision();