UNPKG

emoji-net

Version:

EmojiNet is an image to emoji recognizer based on MobileNet / Google Emoji Scavenger Hunt

121 lines 4.88 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EmojiNet = exports.MOBILENET_SIZE = void 0; /** * @license * Copyright 2018 Google LLC * * 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 * * https://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. * ============================================================================= */ require("isomorphic-fetch"); const tfc = __importStar(require("@tensorflow/tfjs-core")); const tfjs_converter_1 = require("@tensorflow/tfjs-converter"); const emoji_classes_1 = require("./emoji-classes"); const canvas_utils_1 = require("./canvas-utils"); const MOBILENET_SIZE = 224; exports.MOBILENET_SIZE = MOBILENET_SIZE; const MODEL_FILE_URL = 'https://emojiscavengerhunt.withgoogle.com/model/tensorflowjs_model.pb'; const WEIGHT_MANIFEST_FILE_URL = 'https://emojiscavengerhunt.withgoogle.com/model/weights_manifest.json'; // const MODEL_FILE_URL = 'file:///model/tensorflowjs_model.pb' // const WEIGHT_MANIFEST_FILE_URL = 'file:///model/weights_manifest.json' const INPUT_NODE_NAME = 'input'; const OUTPUT_NODE_NAME = 'final_result'; const PREPROCESS_DIVISOR = tfc.scalar(255 / 2); class EmojiNet { async load() { this.model = await tfjs_converter_1.loadFrozenModel(MODEL_FILE_URL, WEIGHT_MANIFEST_FILE_URL); this.predict(tfc.zeros([ MOBILENET_SIZE, MOBILENET_SIZE, 3, ])); } dispose() { if (this.model) { this.model.dispose(); } } async recognize(src) { const image = await canvas_utils_1.loadImage(src); const resizedImage = await canvas_utils_1.resizeImage(image, MOBILENET_SIZE, MOBILENET_SIZE); const canvas = await canvas_utils_1.createCanvas(MOBILENET_SIZE, MOBILENET_SIZE); const ctx = canvas.getContext('2d'); if (!ctx) { throw new Error('no ctx'); } ctx.putImageData(resizedImage, 0, 0); const pixels = tfc.fromPixels(canvas); const predictions = this.predict(pixels); const top3 = this.getTopKClasses(predictions, 3); return top3; } /** * Infer through MobileNet, assumes variables have been loaded. This does * standard ImageNet pre-processing before inferring through the model. This * method returns named activations as well as softmax logits. * * @param input un-preprocessed input Array. * @return The softmax logits. */ predict(input) { const preprocessedInput = tfc.div(tfc.sub(input.asType('float32'), PREPROCESS_DIVISOR), PREPROCESS_DIVISOR); const reshapedInput = preprocessedInput.reshape([ 1, ...preprocessedInput.shape, ]); const dict = {}; dict[INPUT_NODE_NAME] = reshapedInput; return this.model.execute(dict, OUTPUT_NODE_NAME); } getTopKClasses(predictions, topK) { const values = predictions.dataSync(); predictions.dispose(); let predictionList = []; for (let i = 0; i < values.length; i++) { predictionList.push({ index: i, probobility: values[i], }); } predictionList = predictionList.sort((a, b) => { return b.probobility - a.probobility; }).slice(0, topK); return predictionList.map(x => ({ id: x.index, name: emoji_classes_1.EMOJI_CLASSES[x.index], probobility: x.probobility, })); } } exports.EmojiNet = EmojiNet; //# sourceMappingURL=emoji-net.js.map