example
Example
// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com

// Example 16-11: Simple color tracking

import processing.video.*;

// Variable for capture device
Capture video;

// A variable for the color we are searching for.
color trackColor; 

void setup() {
  size(320,240);
  video = new Capture(this,width,height,15);
  // Start off tracking for red
  trackColor = color(255,0,0);
  smooth();
}

void draw() {
  // Capture and display the video
  if (video.available()) {
    video.read();
  }
  video.loadPixels();
  image(video,0,0);

  // 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; 

  // XY coordinate of closest color
  int closestX = 0;
  int closestY = 0;

  // Begin loop to walk through every pixel
  for (int x = 0; x < video.width; x ++ ) {
    for (int y = 0; y < video.height; y ++ ) {
      int loc = x + y*video.width;
      // 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);

      // 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.

      // 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;
      }
    }
  }

  // We only consider the color found if its color distance is less than 10. 
  // This threshold of 10 is arbitrary and you can adjust this number depending on how accurate you require the tracking to be.
  if (worldRecord < 10) { 
    // Draw a circle at the tracked pixel
    fill(trackColor);
    strokeWeight(4.0);
    stroke(0);
    ellipse(closestX,closestY,16,16);
  }
}

void mousePressed() {
  // Save color where the mouse is clicked in trackColor variable
  int loc = mouseX + mouseY*video.width;
  trackColor = video.pixels[loc];
}
  • http://www.fiddlersblog.com Daniel

    Using the dist-function is exactly the trick I was looking for. My color tracking hardly worked before I read this example. Thank you! What a pity that the book is a little high priced …

  • Dave

    Comment above is ridiculous, i’d pay double what the book cost.

  • Laura Orozco

    good afternoon,

    I know that it is processing version 15.1.1, and how I can run thelibrary in another language, or how I can modify it to load an image, I need to identify the color but I q display an image instead of thecircle of example 16.11.

    thanks

  • Anonymous

    Take a look at the PImage examples and use loadImage() and then use image() instead of ellipse() to draw the image.

  • Mickael Lafontaine

    Hi there,

    I’m trying to run this in Processing 2.0a4 but it gives only a black screen. On Processing 1.5 it works fine. I’ve checked the 2.0 doc for the video library, and there’s no change in the capture doc page between 2.0 and 1.5. Do you know where the problem come from ? 
    And by the way, thank you so much for this amazing documentation. 
    Mike

  • Haquim_assamite

    so good.

    I need tracking 4 colors in same time, how i can do this?

  • J Kura

    which programming language we must use?

  • emnullfuenf

    You have to call video.start() and remove the framerate(15) from new Capture(this,width,height);

  • sugianto thoeng

    I made some modification on the code, but I still can not find why it doesnt track any color using Kinect cam, here is my code, please any help for this:

    import SimpleOpenNI.*;

    SimpleOpenNI kinect;

    color trackColor;

    // Frame

    PImage currentFrame;

    void setup()

    {

    size(640, 480);

    kinect = new SimpleOpenNI(this);

    kinect.enableRGB();

    trackColor = color (255,0,0);

    smooth ();

    currentFrame = createImage (640,480, RGB);

    }

    void draw()

    {

    kinect.update();

    currentFrame.loadPixels();

    PImage depthImage = kinect.depthImage();

    PImage currentFrame = kinect.rgbImage ();

    image(currentFrame,0,0);

    // 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;

    // XY coordinate of closest color

    int closestX = 0;

    int closestY = 0;

    // Begin loop to walk through every pixel

    for (int x = 0; x < currentFrame.width; x ++ ) {

    for (int y = 0; y < currentFrame.height; y ++ ) {

    int loc = x + y*currentFrame.width;

    // What is current color

    color currentColor = currentFrame.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);

    // 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.

    // 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;

    }

    }

    }

    // We only consider the color found if its color distance is less than 10.

    // This threshold of 10 is arbitrary and you can adjust this number depending on how accurate you require the tracking to be.

    if (worldRecord < 10) {

    // Draw a circle at the tracked pixel

    fill(trackColor);

    strokeWeight(4.0);

    stroke(0);

    ellipse(closestX,closestY,16,16);

    }

    }

    void mousePressed(){

    color c = get(mouseX, mouseY);

    println("r: " + red(c) + " g: " + green(c) + " b: " + blue(c));

    // Save color where the mouse is clicked in trackColor variable

    int loc = mouseX + mouseY*currentFrame.width;

    println(loc);

    trackColor = currentFrame.pixels[loc];

    }

  • Mickael Lafontaine

    Thanks a lot!

  • Ban Li

    Hi, I want to use this code to track multi color, instead of mouse click to choose color I want to setup the color and if the processing track the color will send a serial date to Arduino, but the problem is i only can setup one color, I need to track 3 or more colors, can anybody help me about this?

  • Tifany

    Can color tracker trigger mouseX action? How would I trigger the mouse click and mouse movement following the ellipse?

  • ML92

    Hi there, how can I track skin colour?

  • fik

    how could i program kinect to recognize object ??? plze help me

  • Nguyen Tung Son

    I put video.start in the setup and deleted the frame rate but it’s still black? Does anyone know what to do? Tks!

  • Eric Tie

    why my camera appear just a black screen? I need it for my final year project. Please help! Thanks in advance

  • shiffman
  • Eric Tie

    Bro, this can be run under version 2.0.3?

  • Eric Tie

    Color still can’t detect. Sorry for bothering on that.

  • Eric Tie

    Currently I’m using Processing 2.0.3, but still can’t detect the color. What should I do now? and where the problem come from? Thanks in advance.

  • Eric

    Good morning, I would like to ask, how can I detect 2 to 4 color at the same time? Thanks in advance.

  • shiffman

    you’ll need an array or object to track multiple colors / locations.

  • shiffman

    you’ll need an array / object to track multiple colors / locations.

  • Phinch

    Hello, thank you for the code! I made some adjustments to change the color accuracy depending on how long it’s been since it’s found the color.
    Declare the int recordTime in the global scope.

    if (worldRecord < recordTime) {

    // Draw a circle at the tracked pixel

    fill(trackColor);

    strokeWeight(4.0);

    stroke(0);

    ellipse(closestX,closestY,16,16);

    recordTime= int(worldRecord);

    }

    else

    {

    recordTime++;

    }

  • colas

    Hi

    Thank for the code, i try to make the image of the camera be hidden, while tracking a color, then i can make visuals and drawings with the color that tracking on the background or a object.

    is this possible?

  • jhon

    it does not work

  • shiffman
  • Dr. Odoyo Wilfred

    It actually works perfectly. Same code just make the frame adjustments and the cam.start(); which you do at the setup().

  • Max Hanz

    i know this question is rather old, but you could simply draw a background after the cam-image has been displayed and all the color tracking is done.

  • shiffman

    In fact, you can simply just comment out the call to image(). No need to draw an image to examine its pixels.

  • Max Hanz

    Ah okay i see. I thought you were just calling “loadpixels” insted of “image.loadpixels”

  • anandp

    which is this foftware

  • Erwin Arizona Rivera

    i need to do the same you can solve that problem I will be really happy if you tell me if you solve it and how you solve it

  • shiffman

    You might consider using an array to keep track of the four colors and then search for the closest XY for each (perhaps an array for each of these as well.) For a longer discussion of this I would suggest posting to http://forum.processing.org