Created
November 28, 2020 11:09
-
-
Save nitobuendia/fb9820468be381183fe7acec8e3d4d96 to your computer and use it in GitHub Desktop.
Emoji Classifier
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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/[email protected]/dist/ml5.min.js"></script> | |
</head> | |
<body> | |
<script src="sketch.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** @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