Do it yourself bio-robotics: Difference between revisions

From Hackers & Designers
No edit summary
No edit summary
Line 6: Line 6:


'''Step 1'''   
'''Step 1'''   
Dismantle the webcam cover
Dismantle the webcam cover


'''Step 2'''   
'''Step 2'''   
Detached the lens of the webcam. Often this optical lens part is partially glued to the front of the webcam but it can be detached by twisting firmly.   
Detached the lens of the webcam. Often this optical lens part is partially glued to the front of the webcam but it can be detached by twisting firmly.   


'''Step 3'''   
'''Step 3'''   
Put the lens, up side down, back on the webcam   
Put the lens, up side down, back on the webcam   


'''step 4'''   
'''step 4'''   
Connect the webcam to the computer
Connect the webcam to the computer




'''step 5'''   
'''step 5'''   
To focus, just move the webcam towards or away from the object
To focus, just move the webcam towards or away from the object



Revision as of 23:29, 14 December 2015

A reversible modification for a webcam which lets you take pictures of things far less than 1mm wide.

To make the microscope webcam you need the following:

  • Standard webcam with an adjustable focus-lens
  • Computer

Step 1

Dismantle the webcam cover

Step 2

Detached the lens of the webcam. Often this optical lens part is partially glued to the front of the webcam but it can be detached by twisting firmly.

Step 3

Put the lens, up side down, back on the webcam

step 4

Connect the webcam to the computer


step 5

To focus, just move the webcam towards or away from the object


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.

Bio-robotics

youtu.be/iB5cnaERx9c


Recognizing a plant in a pinch

by James Bryan Graves

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>