UNPKG

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
"use strict"; // 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();