Do it yourself bio-robotics
Movie bio-robotics
Video created with a DIY microscope by Jona Andersen, Juriaan Boerman and Mark-Jan Tellingen during the workshop 'Bio-Robotics of Arjan Scherpenisse.
Recognizing a plant in a pinch
When asked to assist how to quickly recognize a plant with a webcam I remembered an Apple WWDC presentation called "Find my iCone" an app that tracked an orange construction pylon using it's color.
I already had some web/Javascript code to do some chromakey (greenscreen) swapping, so I just re-purposed it. However, tracking the correct color of say "purple flowers" needed to be a little less fined grained then #ef0114 (for example, I have no idea what "color" that is by looking at it's hex values), so I grabbed a JS library to print colors as words.
Here's the code:
<!DOCTYPE html> <html> <head> <script src="ntc.js"></script> </head> <body> <video id='v'></video>
<h1>I don't see anything.
<canvas id='c'></canvas> <script> function rgbToHex(r, g, b) { return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); } window.addEventListener('DOMContentLoaded', function() { var v = document.getElementById('v'); navigator.getUserMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); if (navigator.getUserMedia) { // Request access to video only navigator.getUserMedia({ video: true, audio: false }, function(stream) { var url = window.URL || window.webkitURL; v.src = url ? url.createObjectURL(stream) : stream; v.play(); }, function(error) { alert('Something went wrong. (error code ' + error.code + ')'); return; }); } else { alert('Sorry, the browser you are using doesn\'t support getUserMedia'); return; } }); var isStreaming = false, v = document.getElementById('v'), c = document.getElementById('c'), //bg = document.getElementById('bg'), grey = document.getElementById('grey'); con = c.getContext('2d'); w = 480, h = 480, greyscale = false; v.addEventListener('canplay', function(e) { if (!isStreaming) { // videoWidth isn't always set correctly in all browsers if (v.videoWidth > 0) h = v.videoHeight / (v.videoWidth / w); c.setAttribute('width', w); c.setAttribute('height', h); // Reverse the canvas image con.translate(w, 0); con.scale(-1, 1); isStreaming = true; } }, false); v.addEventListener('play', function() { // Every 33 milliseconds copy the video image to the canvas setInterval(function() { if (v.paused || v.ended) return; con.fillRect(0, 0, w, h); con.drawImage(v, 0, 0, w, h); //goingGrey(); chromaKey(); }, 33); }, false); var goingGrey = function() { var imageData = con.getImageData(0, 0, w, h); var data = imageData.data; for (var i = 0; i < data.length; i += 4) { var bright = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; data[i] = bright; data[i + 1] = bright; data[i + 2] = bright; } con.putImageData(imageData, 0, 0); }; var count = 0; var purpleCount = 0; var chromaKey = function() { var camData = con.getImageData(0, 0, w, h); //con.drawImage(bg, 0, 0, w, h); var bgData = con.getImageData(0, 0, w, h); var imgData = con.createImageData(w, h); document.querySelector('h1').innerHTML = 'I see nothing.'; for (i = 0; i < imgData.width * imgData.height * 4; i += 4) { var r = camData.data[i + 0]; var g = camData.data[i + 1]; var b = camData.data[i + 2]; var a = camData.data[i + 3]; if(++count % 200 == 0) { var hexColor = rgbToHex(r,g,b); var n_match = ntc.name(hexColor); n_rgb = n_match[0]; // RGB value of closest match n_name = n_match[1]; // Text string: Color name n_exactmatch = n_match[2]; // True if exact color match // compare rgb levels for green and set alphachannel to 0; if (n_name.indexOf('Loulou') != -1) { console.log(n_name); console.log(hexColor); if(++purpleCount > 100) { document.querySelector('h1').innerHTML = 'I see the plant.'; imgData.data[i + 0] = 0; imgData.data[i + 1] = 0; imgData.data[i + 2] = 0; imgData.data[i + 3] = 1; } } else { imgData.data[i + 0] = r; imgData.data[i + 1] = g; imgData.data[i + 2] = b; imgData.data[i + 3] = a; } } } con.putImageData(imgData, 0, 0); }; </script> </body> </html>