// Cloned by Rahul K Johny on 30 Nov 2022 from World "Recognise any image" by Starter user
// Please leave this clone trail here.
// ML5 image recognition using MobileNet
// uses AB framework
// enter URL of image at runtime
document.write ( `
<html>
<head>
<title>Sketchpad</title>
<script type="text/javascript">
// Variables for referencing the canvas and 2dcanvas context
var canvas,ctx;
// Variables to keep track of the mouse position and left-button status
var mouseX,mouseY,mouseDown=0;
// Draws a dot at a specific position on the supplied canvas name
// Parameters are: A canvas context, the x position, the y position, the size of the dot
function drawDot(ctx,x,y,size) {
// Let's use black by setting RGB values to 0, and 255 alpha (completely opaque)
r=0; g=0; b=0; a=255;
// Select a fill style
ctx.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
// Draw a filled circle
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
}
// Clear the canvas context using the canvas width and height
function clearCanvas(canvas,ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
// Keep track of the mouse button being pressed and draw a dot at current location
function sketchpad_mouseDown() {
mouseDown=1;
drawDot(ctx,mouseX,mouseY,12);
}
// Keep track of the mouse button being released
function sketchpad_mouseUp() {
mouseDown=0;
}
// Keep track of the mouse position and draw a dot if mouse button is currently pressed
function sketchpad_mouseMove(e) {
// Update the mouse co-ordinates when moved
getMousePos(e);
// Draw a dot if the mouse button is currently being pressed
if (mouseDown==1) {
drawDot(ctx,mouseX,mouseY,12);
}
}
// Get the current mouse position relative to the top-left of the canvas
function getMousePos(e) {
if (!e)
var e = event;
if (e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if (e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
}
// Set-up the canvas and add our event handlers after the page has loaded
function init() {
// Get the specific canvas element from the HTML document
canvas = document.getElementById('sketchpad');
// If the browser supports the canvas tag, get the 2d drawing context for this canvas
if (canvas.getContext)
ctx = canvas.getContext('2d');
// Check that we have a valid context to draw on/with before adding event handlers
if (ctx) {
canvas.addEventListener('mousedown', sketchpad_mouseDown, false);
canvas.addEventListener('mousemove', sketchpad_mouseMove, false);
window.addEventListener('mouseup', sketchpad_mouseUp, false);
}
}
</script>
<style>
/* Some CSS styling */
#sketchpadapp {
/* Prevent nearby text being highlighted when accidentally dragging mouse outside confines of the canvas */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.leftside {
float:left;
width:220px;
height:285px;
background-color:#def;
padding:10px;
border-radius:4px;
}
.rightside {
float:left;
margin-left:10px;
}
#sketchpad {
float:left;
border:2px solid #888;
border-radius:4px;
position:relative; /* Necessary for correct mouse co-ords in Firefox */
}
</style>
</head>
<body onload="init()">
<div id="sketchpadapp">
<div class="leftside">
Simple mouse-based HTML5 canvas sketchpad.<br/><br/>
Draw something by holding down the mouse button or using single clicks.<br/><br/>
On a touchscreen, tapping the area will register as a single mouse click.<br/><br/>
<input type="submit" value="Clear Sketchpad" onclick="clearCanvas(canvas,ctx);">
</div>
<div class="rightside">
<canvas id="sketchpad" height="300" width="400">
</canvas>
</div>
</div>
</body>
</html>
` );
// no run, pause, step
AB.drawRunControls = false;
let classifier;
let img;
// asynchronous loads of resources, with callback functions when ready
var classifierLoaded = false;
var imgLoaded = false;
AB.world.newRun = function()
{
AB.runReady = false; // prevent screenshot while waiting on splash screen
ABWorld.init ( 'lightblue' );
AB.headerRHS();
// can do classifier load while we are waiting for user
classifier = ml5.imageClassifier ( 'MobileNet', function()
{
// console.log ( "loaded classifier");
classifierLoaded = true;
if ( classifierLoaded && imgLoaded ) init();
});
};
function recognise() // user has entered a URL
{
var url = jQuery("input#url").val();
url = url.trim();
if ( ! url.startsWith ( "https://ancientbrain.com/uploads/" ) )
{
$("#errordiv").html( "<font color=red> <B> Error: Image must be an upload on Ancient Brain </b></font> " );
return;
}
// else URL looks good
AB.removeSplash();
url = url.replace ( "https://ancientbrain.com/uploads/", "/uploads/" );
// console.log ( "fetching image: " + url );
loadImage ( url, function ( theimg )
{
// console.log ( "loaded image");
img = theimg;
imgLoaded = true;
if ( classifierLoaded && imgLoaded ) init();
});
}
function init() // all resources loaded
{
// center image in full window canvas, so screenshot looks good
// x + img.width + x = ABWorld.p5canvas.width
var x = (ABWorld.p5canvas.width - img.width ) /2;
var y = (ABWorld.p5canvas.height - img.height ) /2;
image (img, x, y);
AB.headerRHS();
// AB.msg ( "Running image recognition ... <br> ", 1 );
AB.runReady = true;
classifier.classify ( img, 5, function ( error, results ) // classify, with callback function
{
if (error)
{
AB.msg ( "<font color=red> <B> Error recognising image. See console for details. </b></font> <br> ", 2 );
console.log (error);
}
// results = an array ordered by confidence
var r = "<hr> <h3> Rank Confidence Identification </h3> ";
for ( var i = 0; i < results.length; i++ )
{
r = r + (i+1) + ". " + nf(results[i].confidence, 0, 2) + " " + results[i].label + " <br> ";
// https://p5js.org/reference/#/p5/nf
}
AB.msg ( r, 3 );
});
}