Do it yourself bio-robotics: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
=== Recognizing a plant in a pinch === | |||
by [[James Bryan Graves]] | |||
When asked to assist how to quickly recognize a plant with a webcam I remember 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 [http://chir.ag/projects/ntc/ 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.</h1> | |||
<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> | |||
[[Category:DIY Manual]] | [[Category:DIY Manual]] |
Revision as of 16:03, 22 November 2015
Recognizing a plant in a pinch
When asked to assist how to quickly recognize a plant with a webcam I remember 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>I don't see anything.