6.2 Video Sampling and Color Tracking

 

Computer vision is a form of computationally analyzing an image or video to ascertain information about that image from object detection to patterns to motion and so on. This example uses analyzes the pixels in a video to determine if they are “close enough” to a tracking color. The example below stores all of the positions of the pixels that are close to the tracking color in a list.

 

import processing.video.*;

ArrayList <PVector> pixelmatch = new ArrayList <PVector>();

Capture cam;

PGraphics video_holder;

color track_color = color(0,255,0);

void setup() {
  size(640, 480);
  
  String[] cameras = Capture.list();
  
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {    
    // The camera can be initialized directly using an 
    // element from the array returned by list():
    cam = new Capture(this, cameras[4]);
    cam.start();     
    
    video_holder = createGraphics(width,height);
  }      
}

void draw() {
  if (cam.available() == true) {
    cam.read();
  }
  video_holder.beginDraw();
  video_holder.image(cam, 0, 0);
  video_holder.endDraw();
  image(video_holder,0,0);
  
  pixelmatch = new ArrayList ();
  
  for(int x = 0; x < cam.width; x++){
    for(int y = 0; y < cam.height; y++){
      color sample_color = video_holder.get(x,y);
      float r1 = red(sample_color);
      float g1 = blue(sample_color);
      float b1 = green(sample_color);
      float r2 = red(track_color);
      float g2 = blue(track_color);
      float b2 = green(track_color);
      
      //determine if the color sample from the xurrent pixel
      //is close to the tracking color
      float range = dist(r1,g1,b1,r2,g2,b2);
      if(range < 15){
        pixelmatch.add(new PVector(x,y,0));
      }
    }
  }

  for(int i = 0; i < pixelmatch.size(); i++){ 
    PVector p = pixelmatch.get(i); 
    ellipse(p.x,p.y,5,5); 
  } 
}

//select the tracking color with a mouse click
void mouseClicked() {
  track_color = video_holder.get(mouseX,mouseY);
}

While the example above draws an ellipse for every pixel that matches the tracking color, what we really want is the center of all of the tracked points. To do this we average the position of those points. The example below adds the average of the tracked pixel positions and draws one ellipse at the average position.

 

import processing.video.*;

ArrayList <PVector> pixelmatch = new ArrayList <PVector> ();

Capture cam;

PGraphics video_holder;


color track_color = color(0,255,0);

void setup() {
  size(640, 480);
  
  String[] cameras = Capture.list();
  
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {    
    // The camera can be initialized directly using an 
    // element from the array returned by list():
    cam = new Capture(this, cameras[4]);
    cam.start();     
    
    video_holder = createGraphics(width,height);
  }      
}

void draw() {
  if (cam.available() == true) {
    cam.read();
  }
  video_holder.beginDraw();
  video_holder.image(cam, 0, 0);
  video_holder.endDraw();
  image(video_holder,0,0);
  
  pixelmatch = new ArrayList ();
  
  for(int x = 0; x < cam.width; x++){
    for(int y = 0; y < cam.height; y++){
      color sample_color = video_holder.get(x,y);
      float r1 = red(sample_color);
      float g1 = blue(sample_color);
      float b1 = green(sample_color);
      float r2 = red(track_color);
      float g2 = blue(track_color);
      float b2 = green(track_color);
      
      //determine if the color sample from the xurrent pixel
      //is close to the tracking color
      float range = dist(r1,g1,b1,r2,g2,b2);
      if(range < 15){
        pixelmatch.add(new PVector(x,y,0));
      }
    }
  }
  
  float x_av = 0;
  float y_av = 0;
  for(int i = 0; i < pixelmatch.size(); i++){ 
    PVector p = pixelmatch.get(i); 
    //ellipse(p.x,p.y,5,5); 
    x_av = x_av + p.x; 
    y_av = y_av + p.y; 
  } 
  //average all of the pixel positions 
  if(pixelmatch.size() > 0){
    x_av = x_av/pixelmatch.size();
    y_av = y_av/pixelmatch.size();
    noStroke();
    fill(0,255,255);
    ellipse(x_av,y_av,20,20);
  }
}

//select the tracking color with a mouse click
void mouseClicked() {
  track_color = video_holder.get(mouseX,mouseY);
}

The example below stores each average position in a list and draws a trail for through those points

import processing.video.*;

ArrayList  <PVector> pixelmatch = new ArrayList <PVector>();

ArrayList  <PVector> trail = new ArrayList <PVector>();
ArrayList  <PVector> color_track = new ArrayList <PVector>();

Capture cam;

PGraphics video_holder;

int vwidth = 640;
int vheight = 480;

color track_color = color(0,255,0);

void setup() {
  size(640, 480);
  
  String[] cameras = Capture.list();
  
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[16]);
    }
    
    // The camera can be initialized directly using an 
    // element from the array returned by list():
    cam = new Capture(this, cameras[16]);
    cam.start();     
    
    video_holder = createGraphics(vwidth,vheight);
  }      
}

void draw() {
  if (cam.available() == true) {
    cam.read();
  }
  video_holder.beginDraw();
  video_holder.image(cam, 0, 0);
  video_holder.endDraw();
  image(video_holder,0,0);
  
  pixelmatch = new ArrayList ();
  
  for(int x = 0; x < cam.width; x++){
    for(int y = 0; y < cam.height; y++){
      color sample_color = video_holder.get(x,y);
      float r1 = red(sample_color);
      float g1 = blue(sample_color);
      float b1 = green(sample_color);
      float r2 = red(track_color);
      float g2 = blue(track_color);
      float b2 = green(track_color);
      
      float range = dist(r1,g1,b1,r2,g2,b2);
      
      if(range < 15){
        pixelmatch.add(new PVector(x,y,0));
      }
    }
  }
  
  float x_av = 0;
  float y_av = 0;
  for(int i = 0; i < pixelmatch.size(); i++){ 
    PVector p = pixelmatch.get(i); 
    //ellipse(p.x,p.y,5,5); 
    x_av = x_av + p.x; 
    y_av = y_av + p.y; 
  } 
  if(pixelmatch.size() > 10){
    x_av = x_av/pixelmatch.size();
    y_av = y_av/pixelmatch.size();
    
    noStroke();
    fill(0,255,255);
    ellipse(x_av,y_av,20,20);
    trail.add(new PVector(x_av,y_av,0));
    color_track.add(new PVector(red(track_color),green(track_color),blue(track_color)));
  }
 
  for(int i = 0; i < trail.size()-1; i++){
    PVector p1 = trail.get(i);
    PVector p2 = trail.get(i+1);
    
    PVector cc = color_track.get(i);
    strokeWeight(5);
    stroke(cc.x,cc.y,cc.z);
    line(p1.x,p1.y,p2.x,p2.y);
  }
}

void mouseClicked() {
  track_color = video_holder.get(mouseX,mouseY);
}