Februar 26, 2012
![](../../../../files/2012/02/visual_video_color_tracking.jpg)
![](../../../../files/2012/02/videotracking_color1.jpg)
![](../../../../files/2012/02/videotracking_color2.jpg)
Processing
Main
PImage myImage; PImage imgmoustache; PImage imgglasses; import processing.opengl.*; float mouseInputX; float zoom; PVector startPos = new PVector(); PVector endPos = new PVector(); PVector startPosDir = new PVector(); ArrayList data= new ArrayList(); String[] imagesMoustaches = { "moustache.png", "moustache2.png", "moustache3.png" }; String[] imagesGlasses = { "glasses.png", "glasses2.png" }; int imageIndex=0; int imageIndexG=0; int mouseClicks=0; import processing.video.*; Capture video; color trackColor; color trackColor2; float rotation; void setup() { smooth(); // default tracking colors trackColor = color(204,204,0); trackColor2 = color(0,204,0); // default images imgmoustache = loadImage(imagesMoustaches[imageIndex]); imgglasses = loadImage(imagesGlasses[imageIndexG]); video = new Capture(this,800,600,12); if (video.available()) { video.read(); } myImage = video; reset(); size(800, 600); //, OPENGL } void reset() { data= new ArrayList(); if (video.available()) { video.read(); } myImage = video; myImage.loadPixels(); } void draw() { background(0); reset(); // COLOR TRACKING // Before we begin searching, the "world record" for closest color is set to a high number that is easy for the first pixel to beat. float worldRecord = 500; float worldRecord2 = 500; // XY coordinate of closest color int closestX = 0; int closestY = 0; int closestX2 = 0; int closestY2 = 0; // Loop through every pixel for (int x = 0; x < myImage.width; x++ ) { // We can get the length of the pixels array just like with any array. for (int y = 0; y < myImage.height; y++ ) { int loc = (x-myImage.width+1)*-1 + y * myImage.width; float mouseDistance = (width/2)-mouseX; startPos.set(mouseX,mouseY,0); endPos.set(width/2,height/2,0); PVector dir = PVector.sub(endPos,startPos); mouseDistance = dir.mag(); startPos.set(mouseX,mouseY,0); endPos.set(x,y,0); PVector dir2 = PVector.sub(endPos,startPos); float mouseDistanceCircle = dir2.mag(); // What is current color color currentColor = video.pixels[loc]; float r1 = red(currentColor); float g1 = green(currentColor); float b1 = blue(currentColor); float r2 = red(trackColor); float g2 = green(trackColor); float b2 = blue(trackColor); float rr2 = red(trackColor2); float gg2 = green(trackColor2); float bb2 = blue(trackColor2); // Using euclidean distance to compare colors float d = dist(r1,g1,b1,r2,g2,b2); // We are using the dist( ) function to compare the current color with the color we are tracking. float d2 = dist(r1,g1,b1,rr2,gg2,bb2); // We are using the dist( ) function to compare the current color with the color we are tracking. // If current color is more similar to tracked color than // closest color, save current location and current difference if (d < worldRecord) { worldRecord = d; closestX = x; closestY = y; } if (d2 < worldRecord2) { worldRecord2 = d2; closestX2 = x; closestY2 = y; } myImage.updatePixels(); } } pushMatrix(); scale(-1.0, 1.0); image(myImage,-1*myImage.width,0); popMatrix(); // ROTATION startPos.set(closestX, closestY, 0); endPos.set(closestX2, closestY2, 0); PVector dir = PVector.sub(endPos, startPos); //float mouseDistance = dir.mag(); startPosDir.set(closestX-closestX2, closestY-closestY2, 0); // angle of letter to mouse position float rotation = PVector.angleBetween(endPos,startPosDir); // get cross vector to determine direction (in which half circle) to complete 360 deg PVector v3 = startPos.cross(endPos); if (v3.z>0) { rotation = radians(360-degrees(rotation)); } rotation = radians(degrees(rotation)-60); if (worldRecord < 100) { float birdHeight = dist(closestX, closestY, 0, closestX2, closestY2, 0); float zoom = birdHeight/130; // image moustache imageMode(CENTER); pushMatrix(); translate(closestX, closestY); rotate(rotation); image(imgmoustache, 0, 0, imgmoustache.width/2*zoom, imgmoustache.height/2*zoom); popMatrix(); // image glasses pushMatrix(); translate(closestX2, closestY2); rotate(rotation); translate(0, imgglasses.height/3); image(imgglasses, 0, 0, imgglasses.width*zoom*0.75, imgglasses.height*zoom*0.75); popMatrix(); imageMode(CORNER); } } void mousePressed() { // pick color with mouse clicks loadPixels(); int loc = mouseX + mouseY * myImage.width; color tmp = color(red(pixels[loc]),green(pixels[loc]),blue(pixels[loc])); if (mouseClicks==0) { //mouseClicks++; trackColor = tmp; println(red(pixels[loc])+":"+green(pixels[loc])+":"+blue(pixels[loc])); //mouseClicks++; } if (mouseClicks==1) { trackColor2 = tmp; //mouseClicks=0; } } void keyPressed() { switch(key) { // laod next moustache case 'a': imageIndex++; if (imageIndex>=imagesMoustaches.length) imageIndex=0; imgmoustache = loadImage(imagesMoustaches[imageIndex]); reset(); break; // load next glasses case 's': imageIndexG++; if (imageIndexG>=imagesGlasses.length) imageIndexG=0; imgglasses = loadImage(imagesGlasses[imageIndexG]); reset(); break; // save screenshot case 'p': save("screen/screen_"+year()+"-"+month()+""+day()+"_"+hour()+"-"+minute()+"-"+second()); break; default: break; } // switch }