Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

Color Tracker II

Februar 29, 2012

Der erweiterte Color Tracker kann mehrer Farbflächen (auch von der gleichen Farbe) tracken. ENTER - Alle Trackings löschen SPACE - Debug Mode On/Off
// Imports
import processing.video.*;
import java.awt.Rectangle;

// Settings
int ZONE = 5;
int TRESHOLD = 15;
boolean DEBUG = true;
int LAST_DEBUG_COLOR = 0;

// Objects
EnhancedCapture video;
TrackerManager trackerManager;

// Setup Routine
void setup() {
  size(640,480);
  video = new EnhancedCapture(this,width,height,"IIDC FireWire Video",15);
  smooth();
  trackerManager = new TrackerManager();
  colorMode(HSB,255);
}

// Draw Loop
void draw() {
  if (video.available()) {
    video.read();
    video.mirror();
    trackerManager.trackFrame(video);
    image(video,0,0);
    if(DEBUG) {
      trackerManager.drawDebug(this);
    } else {
      trackerManager.drawTracker(this);
    }
  }
}

// Mouse Interaction
void mouseReleased() {
  trackerManager.trackPoint(mouseX,mouseY,video.pixels[mouseX + mouseY*video.width]);
}

// Keyboard Interaction
void keyPressed() {
  if(keyCode == ENTER) {
    trackerManager.clear();
    LAST_DEBUG_COLOR = 0;
  } else if(keyCode == 32) {
    DEBUG = !DEBUG;
  } else {
    println("KEY: "+keyCode);
  }
}

class ColorMatch
{
  int x;
  int y;
  int c;
  
  ColorMatch(int _x, int _y, color _c) {
    this.x = _x;
    this.y = _y;
    this.c = _c;
  }
}

class EnhancedCapture extends Capture
{
  // Call Super Constructor
  EnhancedCapture(PApplet parent, int width, int height, String device, int fps) {
    super(parent,width,height,device,fps);
  }
  
  // Mirror internal Image
  void mirror() {
    PImage mirror = new PImage(this.width,this.height);
    for (int i = 0; i < this.width; i++) {
      for (int j = 0; j < this.height; j++) {     
        mirror.pixels[j*this.width+i] = this.pixels[(this.width -i-1)+j*this.width];
      }
    }
    this.pixels = mirror.pixels;
  }
}

class TrackPoint
{
  // Properties
  int x;
  int y;
  color c;
  Tracker activeTracker;
  color debugColor;
  ArrayList trackers;
  
  // Create new Track Point
  TrackPoint(int _x, int _y, color _c) {
    this.x = _x;
    this.y = _y;
    this.c = _c;
    this.debugColor = color(LAST_DEBUG_COLOR,255,255);
    LAST_DEBUG_COLOR += 50;
  }
  
  // Scan Image
  void trackFrame(PImage img) {
    
    // Get Matching Colors from Image
    ArrayList matches = new ArrayList();
    for (int _x = 0; _x < img.width; _x ++ ) {
      for (int _y = 0; _y < img.height; _y ++ ) {
        int loc = _x + _y*img.width;
        color _c = img.pixels[loc];
        if (dist(red(_c),green(_c),blue(_c),red(this.c),green(this.c),blue(this.c)) <= TRESHOLD) {
          matches.add(new ColorMatch(_x,_y,_c));
        }
      }
    }
    
    // Create Trackers
    trackers = new ArrayList();
    for(int i=0; i < matches.size(); i++) {
      ColorMatch match = (ColorMatch) matches.get(i);
      boolean found = false;
      for(int ii=0; ii < trackers.size(); ii++) {
        Tracker tracker = (Tracker) trackers.get(ii);
        if(tracker.eatPixel(match.x,match.y)) {
          found = true;
          break;
        }
      }
      if(!found) {
        trackers.add(new Tracker(match.x,match.y,match.c));
      }
    }
    
    // Combine Trackers
    for(int i=0; i < trackers.size(); i++) {
      Tracker tracker = (Tracker)trackers.get(i);
      for(int ii=i+1; ii < trackers.size(); ii++) {
        Tracker tracker2 = (Tracker)trackers.get(ii);
        if (tracker.eatTracker(tracker2)) {
          trackers.remove(ii);
        }
      }
    }
    
    // Get Closest Tracker
    float closestDistance = 10000;
    for(int i=0; i < trackers.size(); i++) {
      Tracker tracker = (Tracker)trackers.get(i);
      float distance = dist(tracker.midX(),tracker.midY(),this.x,this.y);
      if(closestDistance > distance) {
        activeTracker = tracker;
        closestDistance = distance;
      }
    }
    
    // Set New Color
    //this.c = activeTracker.c;
    this.x = activeTracker.midX();
    this.y = activeTracker.midY();
  }
  
  void drawDebug(PApplet window) {
    noFill();
    strokeWeight(1);
    stroke(this.debugColor);
    for(int i=0; i < trackers.size(); i++) {
      Tracker tracker = (Tracker)trackers.get(i);
      rect(tracker.r.x,tracker.r.y,tracker.r.width,tracker.r.height);
    }
    line(0,this.y,window.width,this.y);
    line(this.x,0,this.x,window.height);
    strokeWeight(5);
    rect(activeTracker.r.x,activeTracker.r.y,activeTracker.r.width,activeTracker.r.height);
  }
  
  void drawTracker(PApplet window) {
    for(int i=0; i < trackers.size(); i++) {
      noStroke();
      fill(this.debugColor);
      ellipse(activeTracker.midX(),activeTracker.midY(),35,35);
    } 
  }
}

class Tracker
{
  // Properties
  color c;
  Rectangle r;
  Rectangle r2;
  
  // Create new Tracker
  Tracker(int _x, int _y, color _c)
  {
    this.r = new Rectangle(_x,_y,1,1);
    this.r2 = new Rectangle(r.x,r.y,r.width,r.height);
    this.r2.grow(ZONE,ZONE);
    this.c = _c;
  }
  
  // Eat a Pixel
  boolean eatPixel(int _x, int _y)
  {
    if(r.contains(_x,_y)) {
      return true;
    }
    else if(r2.contains(_x,_y)) {
      r.add(_x,_y);
      r2 = new Rectangle(r.x,r.y,r.width,r.height);
      r2.grow(ZONE,ZONE);
      return true;
    }
    return false;
  }
  
  // Eat another tracker = grow rectangle
  boolean eatTracker(Tracker tracker)
  {
    if (r2.intersects(tracker.r2)) {
      r.add(tracker.r);
      r2 = new Rectangle(r.x,r.y,r.width,r.height);
      r2.grow(ZONE,ZONE);
      return true;
    }
    return false;
  }
  
  // Get Site of Rectangle
  double size() {
    return r.getWidth()*r.getHeight();
  }
  
  // Get center X
  int midX() {
    return r.x + r.width/2;
  }
  
  // Get Center Y
  int midY() {
    return r.y + r.height/2;
  }
}

class TrackerManager
{
  ArrayList trackPoints;
  
  TrackerManager() {
    this.trackPoints = new ArrayList();
  }
  
  void trackPoint(int _x, int _y, color _c) {
    trackPoints.add(new TrackPoint(_x,_y,_c));
  }
  
  void trackFrame(PImage img) {
    for(int i=0; i<trackPoints.size(); i++) {
      TrackPoint point = (TrackPoint)trackPoints.get(i);
      point.trackFrame(img);
    }
  }
  
  void drawDebug(PApplet window) {
    fill(255);
    window.text("TP: "+trackPoints.size()+" - FPS: "+round(window.frameRate),10,20);
    for(int i=0; i < trackPoints.size(); i++) {
      TrackPoint trackPoint = (TrackPoint) trackPoints.get(i);
      trackPoint.drawDebug(window);
    }
  }
  
  void drawTracker(PApplet window) {
    for(int i=0; i < trackPoints.size(); i++) {
      TrackPoint trackPoint = (TrackPoint) trackPoints.get(i);
      trackPoint.drawTracker(window);
    }
  }
  
  void clear() {
    while(trackPoints.size() > 0) {
      trackPoints.remove(0);
    }
  }
}