Skip to content

Instantly share code, notes, and snippets.

@nitobuendia
Created November 28, 2020 11:09
Show Gist options
  • Save nitobuendia/fb9820468be381183fe7acec8e3d4d96 to your computer and use it in GitHub Desktop.
Save nitobuendia/fb9820468be381183fe7acec8e3d4d96 to your computer and use it in GitHub Desktop.
Emoji Classifier
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Getting Started with ml5.js</title>
<!-- p5 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.sound.min.js"></script>
<!-- ml5 -->
<script src="https://unpkg.com/ml5@0.4.3/dist/ml5.min.js"></script>
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
/** @fileoverview Minimal nodejs server to avoid CORS issues. */
const http = require('http');
const fs = require('fs');
const nStatic = require('node-static');
const fileServer = new nStatic.Server('./');
http.createServer((req, res) => {
fileServer.serve(req, res);
}).listen(3000);
/** @fileoverview Classifies emojis into happy and sad using Tensorflow.js (ml5.js). */
/**
* Creates a canvas element.
* @return {!Element} Canvas element.
*/
function createCanvasElement() {
const canvasElement = document.createElement('canvas');
return canvasElement;
}
/**
* Writes an emoji (text) to a canvas element.
* @param {string} emoji Emoji text to draw.
* @param {!Element} canvasElement Canvas element to which to write emoji.
* @param {number} size Font size that will be used for canvas.
*/
function writeEmojiToCanvas(emoji, canvasElement, size = 100) {
const margin = 20 / 100;
const startPoint = (size / 2) * (1 + margin);
canvasElement.height = size * (1 + margin);
canvasElement.width = size * (1 + margin);
const canvasContext = canvasElement.getContext('2d');
canvasContext.font = `${size}px serif`;
canvasContext.textAlign = 'center';
canvasContext.textBaseline = 'middle';
canvasContext.fillText(emoji, startPoint, startPoint);
}
/**
* Converts a canvas into a image via data URL.
* @param {!Element} canvasElement Canvas element to convert to image.
* @return {!Element} Image element with canvas contents.
*/
function createImageFromCanvas(canvasElement) {
const canvasContext = canvasElement.getContext('2d');
const imageElement = document.createElement('img');
imageElement.crossOrigin = 'anonymous';
imageElement.src = canvasContext.canvas.toDataURL();
return imageElement;
}
/**
* Converts an emoji (text) into an image element.
* @param {string} emoji Emoji to convert to image.
* @return {!Element} Image element with emoji data.
*/
function convertEmojiToImage(emoji) {
const canvasElement = createCanvasElement();
writeEmojiToCanvas(emoji, canvasElement);
return createImageFromCanvas(canvasElement);
}
/**
* Creates an image from a URL (e.g. URL, data or local).
* @param {string} imageUrl URL to load.
* @return {!Element} Image element with loaded URL.
*/
function getImageFromUrl(imageUrl) {
const imageElement = document.createElement('img');
imageElement.crossOrigin = 'anonymous';
imageElement.src = imageUrl;
return imageElement;
}
/**
* Outputs image and resutls from classification model.
* @param {!Element} image Image being classified.
* @param {!Array<{
* label:string,
* confidence:number
*}> results Classification results.
*/
function outputImageAndResults(image, results) {
const div = document.createElement('div');
div.appendChild(image);
for (const result of results) {
console.log(result);
const resultLayer = document.createElement('div');
const resultPercentage = Math.round(result.confidence * 100);
resultLayer.innerText = `${result.label}: ${resultPercentage}%`;
div.appendChild(resultLayer);
}
document.body.appendChild(div);
}
// Model generated with https://teachablemachine.withgoogle.com.
// Test manually on https://teachablemachine.withgoogle.com/models/Qyt6JnMPp/
const classifier = ml5.imageClassifier(
'https://teachablemachine.withgoogle.com/models/Qyt6JnMPp/model.json');
// Store images in the emojis/ folder named as a sequence: 1.png, 2.png...
// Alternatively create an array and manually feed emojis using:
// const emoji = convertEmojiToImage('😜');
const NUMBER_IMAGES = 10;
for (let i = 1; i < NUMBER_IMAGES; i++) {
const emojiImage = getImageFromUrl(`emojis/${i}.png`);
classifier.classify(emojiImage, (err, results) => {
console.log(err, results);
outputImageAndResults(emojiImage, results);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment