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